2012-04-17 20 views
6

cuando se borra, como ejemplo, el ID 3, tengo esto:cómo encontrar "agujeros" en la columna auto_increment?

id | name 
1 | 
2 |  
4 | 
5 | 
... 

ahora, quiero buscar el ID (s) que falta, porque quiero llenar el id de nuevo con:

INSERT INTO xx (id,...) VALUES (3,...) 

¿Hay alguna manera de buscar "agujeros" en el índice auto_increment?

gracias!

+7

¿Por qué quieres hacer esto? Dichos "agujeros" son normales en el funcionamiento diario de la base de datos y no deberían ser una preocupación. Si esto se debe a una noción errónea de estética, resístala. – Oded

+6

No deberías. Un auto_increment debería hacer su trabajo, y eso significa que se pueden hacer agujeros. Si empiezas a jugar con eso, irás a problemas más adelante. Solo déjalos estar. – Nanne

+0

Sin mencionar que si se sigue haciendo referencia a una ID eliminada en algún lugar, es decir, a través de una tabla de enlace marcado/no actualizado, la adición de una nueva fila con esa ID producirá problemas involuntarios. Como dice Oded, Nanne, simplemente deja a la IA para hacer su trabajo. –

Respuesta

13

se puede encontrar el valor de la parte superior de las lagunas de esta manera:

select t1.id - 1 as missing_id 
from mytable t1 
left join mytable t2 on t2.id = t1.id - 1 
where t2.id is null 
+0

+1, buena respuesta. – davidethell

+1

¿Qué pasa si tienes un gab más grande que 1? si tiene 14 y luego 20, solo mostrará 19 – Diego

+0

Disculpe, quise decir brecha * – Diego

0

En primer lugar, estoy de acuerdo con los comentarios que no se debe tratar de sellar agujeros. No podrá encontrar todos los agujeros con una sola instrucción SQL. Tendrás que recorrer todos los números posibles empezando por 1 hasta que encuentres un hoyo. Podría escribir una función sql para hacer esto por usted que luego podría usarse en una función. Así que si usted escribió una función llamada find_first_hole que luego podrían llamarlo en una inserción como:

INSERT INTO xx (id, ...) VALUES (find_first_hole(), ...) 
2

Creo que la única manera de hacerlo es con un bucle: Cualesquiera otras soluciones planteo muestran brechas más grandes que 1:

insert into XX values (1) 
insert into XX values (2) 
insert into XX values (4) 
insert into XX values (5) 
insert into XX values (10) 

declare @min int 
declare @max int 

select @min=MIN(ID) from xx 
select @max=MAX(ID) from xx 

while @min<@max begin 
    if not exists(select 1 from XX where id = @min+1) BEGIN 
     print 'GAP: '+ cast(@min +1 as varchar(10)) 
    END 

    set @[email protected]+1 
end 

resultado:

GAP: 3 
GAP: 6 
GAP: 7 
GAP: 8 
GAP: 9 
3

El propósito de AUTO_INCREMENT es generar identificadores únicos y sin sentido simples para sus filas. Tan pronto como tenga la intención de volver a utilizar esos ID, ya no son únicos (al menos no a tiempo), así que tengo la impresión de que no está utilizando la herramienta adecuada para el trabajo. Si decide deshacerse de AUTO_INCREMENT, puede hacer todas sus inserciones con el mismo algoritmo.

Como sobre el código SQL, esta consulta coincidirá con filas existentes con las filas que tiene la siguiente ID:

SELECT a.foo_id, b.foo_id 
FROM foo a 
LEFT JOIN foo b ON a.foo_id=b.foo_id-1 

Ej:

1 NULL 
4 NULL 
10 NULL 
12 NULL 
17 NULL 
19 20 
20 NULL 
24 25 
25 26 
26 27 
27 NULL 

Así que es fácil de filtrar las filas y obtener la primera brecha:

SELECT MIN(a.foo_id)+1 AS next_id 
FROM foo a 
LEFT JOIN foo b ON a.foo_id=b.foo_id-1 
WHERE b.foo_id IS NULL 

tomar esto como un punto de partida, ya que todavía necesita algunos ajustes:

  • Debe considerar el caso donde el número más bajo disponible es el más bajo posible.
  • Debe bloquear la tabla para manejar inserciones concurrentes.
  • En mi computadora es lento como el infierno con grandes mesas.
+0

gracias por información adicional (en mi computadora es lento como el infierno con las tablas grandes). – skyline26

0

Este es un problema isla lagunas &, ver mi (y otros) y respuestas herehere. En la mayoría de los casos, los huecos & los problemas de las islas se solucionan de forma más elegante usando CTE recursivos, que no están disponibles en mysql.

Cuestiones relacionadas