2010-01-21 9 views
6

Tengo 100 millones de filas, y se está haciendo demasiado grande. Veo muchas lagunas. (desde que elimino, agregue, elimine, agregue.)¿Hay algún daño al restablecer el autoincremento?

Quiero llenar estos espacios con el auto-incremento. Si lo reinicio ... ¿hay algún daño?

Si hago esto, tendrá que llenar los vacíos ?:

mysql> ALTER TABLE tbl AUTO_INCREMENT = 1; 
+0

duplicado: http://stackoverflow.com/questions/1949842/when-to-fix-auto-increment-gaps-in-mysql – Thilo

Respuesta

9

potencialmente muy peligroso, porque se puede obtener un número nuevo que ya está en uso.

Lo que propone es restablecer la secuencia a 1 nuevamente. Solo producirá 1,2,3,4,5,6,7, etc., independientemente de si estos números están en una brecha o no.

Actualización: Según la respuesta de Martin, debido a los peligros implicados, MySQL ni siquiera le permitirá hacerlo. Restablecerá el contador a al menos el valor actual + 1.

Piense de nuevo en el problema real que causa la existencia de lagunas. Por lo general, es solo un problema estético.

Si el número es demasiado grande, cambie a un tipo de datos más grande (bigint debería ser suficiente).

+0

¿Qué pasa si el número es demasiado grande? – TIMEX

+0

Si el número es demasiado grande, hay dos casos (ambos malos): es demasiado grande debido a lagunas, o demasiado grande, incluso sin espacios vacíos. En el segundo caso, no hay nada que puedas hacer salvo volver a pensar en tu esquema. En el primer caso, podría soltar y volver a crear toda la columna. Pero esto volverá a numerar cada fila, lo que también puede descartarse. – Thilo

5

Lo más probable es que no obtenga nada al hacer esto, y podría fácilmente arruinar su aplicación sobrescribiendo filas, ya que va a restablecer el recuento de las identificaciones. (En otras palabras, la próxima vez que inserte una fila, sobrescribirá la fila con ID 1, y luego 2, etc.) ¿Qué obtendrá al llenar las lagunas? Si el número es demasiado grande, simplemente cámbielo a larger number (como BIGINT).


Editar: mi error. No hará nada en absoluto, lo que respalda mi punto de que simplemente debes cambiar el tipo de columna a un tipo de entero más grande. El valor máximo posible para un BIGINT es 2^64, que es sobre 18 quintillion. Si solo tiene 100 millones de filas en este momento, debería ser plenty en el futuro previsible.

+0

No, no sobrescribirá nada, solo las claves principales pueden incrementarse automáticamente, por lo que obtendrá un error de clave duplicada, incluso si pudiera hacer esto. – Duncan

2

Estoy de acuerdo con musicfreak ... El máximo para un número entero (int(10)) es 4.294.967.295 (sin signo de grueso). Si necesita ir aún más alto, cambiar a BIGINT le brinda hasta 18,446,744,073,709,551,615.

+0

A menos que esté realizando MUCHAS eliminaciones e inserciones, creo que haría que la base de datos cayera antes de que fuera más grande que una int sin firmar. – Duncan

6

FWIW ...De acuerdo con la MySQL docs aplicar

ALTER TABLE tbl AUTO_INCREMENT = 1 

donde tbl contiene los datos existentes no debe tener ningún efecto:

Para cambiar el valor del contador AUTO_INCREMENT que se utilizará para nuevas filas, haga lo siguiente:

ALTER TABLE t2 AUTO_INCREMENT = valor;

No puede restablecer el contador a un valor inferior o igual a cualquiera que ya se haya utilizado. Para MyISAM, si el valor es menor o igual que el valor máximo actualmente en la columna AUTO_INCREMENT , el valor es restablecer al máximo actual más uno. Para InnoDB, si el valor es menor que el valor máximo actual en la columna , no se produce ningún error y el valor de secuencia actual no se cambia.

Ejecuté una pequeña prueba que confirmó esto para una tabla MyISAM.

Así que las respuestas a sus preguntas son: no hay daño, y no, no llenará los huecos. Como otros respondientes han dicho: un cambio de tipo de datos parece ser la opción menos dolorosa.

1

Como no puede cambiar el siguiente valor de autoincremento, tiene otras opciones. Se puede hacer el cambio de tipo de datos, pero me parece un poco perturbador ya que en realidad no tienes tantas filas. Tendrías que asegurarte de que tu código pueda manejar ID tan grandes, que pueden o no ser difíciles para ti.

¿Puede hacer mucho tiempo de inactividad? Si es así, hay dos opciones en las que puedo pensar:

  1. Vuelque/vuelva a cargar los datos. Puede hacer esto para que no conserve los números de identificación. Por ejemplo, puede usar SELECT ... INTO para copiar los datos, sans-IDs, en una nueva tabla con DDL idéntico. A continuación, suelta la tabla anterior y cambia el nombre de la nueva tabla al nombre anterior. Dependiendo de la cantidad de datos que haya, esto podría tomar un tiempo considerable (y espacio temporal en el disco).

  2. Puede hacer un pequeño programa para emitir instrucciones de ACTUALIZACIÓN para cambiar los ID. Si deja que funcione lentamente, "desfragmentará" sus identificaciones a lo largo del tiempo. Luego, puede detener temporalmente las inserciones (solo uno o dos minutos), actualizar las últimas identificaciones y luego reiniciarlas. Después de actualizar los últimos ID, puede cambiar el valor AUTO_INCREMENT para que sea el próximo número y su agujero desaparecerá. Esto no debería causar un tiempo de inactividad real (al menos en InnoDB), pero podría llevar bastante tiempo dependiendo de qué tan agresivo sea su programa.

Por supuesto, ambos ignoran la integridad referencial. Supongo que eso no es un problema (declaraciones de registro que no se utilizan como claves externas, o algo así).

0

¿Realmente importa si hay lagunas?

Si realmente desea volver atrás y completarlos, siempre puede desactivar el incremento automático y buscar manualmente el siguiente ID disponible cada vez que quiera insertar una fila; recuerde bloquear la tabla para evitar condiciones de carrera. , por supuesto. Pero es mucho trabajo por hacer para obtener pocas ganancias.

¿Realmente necesita una clave sustituta de todos modos? Dependiendo de los datos (no ha mencionado un esquema) probablemente pueda encontrar una clave natural.

Cuestiones relacionadas