He leído algunos posts sobre esto pero ninguno cubrir esta cuestión.

Supongo que no es posible, pero voy a preguntar de todos modos.

Tengo una tabla con más de 50.000 registros. Es una vieja tabla, donde varios insertar/eliminar operaciones han tenido lugar.

Que dijo, hay varios «agujeros» algunos de los cerca de 300 registros. I. e.: …, 1340, 1341, 1660, 1661, 1662, …

La pregunta es. Hay un sencillo/fácil manera de hacer nuevos insertos de llenar estos «agujeros»?

thx
Paulo Bueno

Considere esto: shoes tener id 1, shirts tener id 2, jackets tener id 3. Se decide eliminar shirts, entonces usted decide agregar pants. Si usted llene el hueco, luego de un breve período de tiempo, los motores de búsqueda conducirá a aquellos que están buscando camisetas example.com/product?id=2, que es…pants.

OriginalEl autor Paulo Bueno | 2009-12-03

7 Comentarios

  1. 8

    ¿Cuál es la razón que usted necesita esta funcionalidad? Su base de datos debe ser fino con las lagunas, y si se está aproximando el tamaño máximo de su clave, sólo lo hacen sin firmar o cambiar el tipo de campo.

    Gracias Shane, que es exactamente mi preocupación. Estoy usando mediumint y puede ser utilizado por algunos años. Pero si es necesario que yo podría cambiar.
    Si se acercan a quedarse sin espacio, simplemente actualizar el esquema a un mayor tipo de datos. muchos, Muchos, muchos, muchos, muchos los valores pueden ser representados por los 64 bits.
    Otra pregunta: ¿qué sucede cuando se alcance el tamaño máximo de la auto-incremento de valor? Será el flujo a través de la y – cuando en unsigned – empezar de nuevo con un 0 (o 1)?
    la respuesta es que mysql se produce un error y la operación de inserción simplemente falla.
    No es una pregunta tonta, entiendo que puede ser estético. Sin embargo, generalmente las bases de datos son parte de la infraestructura de una aplicación o programa, por lo que la aplicación va a hacer que las cosas parecen estéticamente agradable (es decir, calcular el ‘rango’ y mostrar que, en lugar de la id). Pensar bases de datos necesita ser bonita es como decir que te gustaría que los postes de madera en las paredes de su casa para ser pintadas.

    OriginalEl autor Shane N

  2. 13

    Estoy de acuerdo con @Aaron Digulla y @Shane N. de Las lagunas no tienen sentido. Si HACER decir algo, que es un deficiente diseño de base de datos. Período.

    Que se dice, si es absolutamente NECESARIO para llenar estos huecos, Y que se están ejecutando en menos de MySQL 3.23, se puede utilizar una TABLA TEMPORAL para crear un nuevo conjunto de Identificadores. La idea aquí es que usted va a seleccionar a todos sus Identificadores, en fin, en una tabla temporal como tal:

    CREATE TEMPORARY TABLE NewIDs
    (
        NewID INT UNSIGNED AUTO INCREMENT,
        OldID INT UNSIGNED
    )
    
    INSERT INTO NewIDs (OldId)
    SELECT
        Id
    FROM
        OldTable
    ORDER BY
        Id ASC

    Esto le dará una tabla de asignación de su Identificador antiguo a un nuevo Id que va a ser secuencial en la naturaleza, debido a que el INCREMENTO AUTOMÁTICO de la propiedad de la función NewId columna.

    Una vez hecho esto, usted necesita para actualizar cualquier otra referencia a la Identificación de «OldTable» y la clave externa se utiliza. Para hacer esto, usted probablemente necesitará quitar las restricciones de clave externa tiene, la actualización de cualquier referencia en las tablas de la OldId a la función NewId y, a continuación, volver a su instituto restricciones de clave externa.

    Sin embargo, yo diría que usted no debe hacer CUALQUIER de esto, y simplemente entender que su campo de Id existe con el único propósito de hacer referencia a un registro, y debe NO tienen alguna relevancia.

    ACTUALIZACIÓN: la Adición de un ejemplo de la actualización de los Identificadores de

    Por ejemplo:

    Digamos que usted tiene los siguientes 2 esquemas de tabla:

    CREATE TABLE Parent
    (
        ParentId INT UNSIGNED AUTO INCREMENT,
        Value INT UNSIGNED,
        PRIMARY KEY (ParentId)
    )
    
    CREATE TABLE Child
    (
        ChildId INT UNSIGNED AUTO INCREMENT,
        ParentId INT UNSIGNED,
        PRIMARY KEY(ChildId),
        FOREIGN KEY(ParentId) REFERENCES Parent(ParentId)
    )

    Ahora, las lagunas que aparecen en la tabla primaria.

    Con el objeto de actualizar los valores de los Padres y el Niño, primero se crea una tabla temporal con los mapeos:

    CREATE TEMPORARY TABLE NewIDs
    (
        Id INT UNSIGNED AUTO INCREMENT,
        ParentID INT UNSIGNED
    )
    
    INSERT INTO NewIDs (ParentId)
    SELECT
        ParentId
    FROM
        Parent
    ORDER BY
        ParentId ASC

    Siguiente, tenemos que decirle a MySQL a ignorar la restricción de clave externa para que podamos ACTUALIZAR correctamente nuestros valores. Vamos a utilizar esta sintaxis:

    SET foreign_key_checks = 0;

    Esto hace que MySQL para omitir la comprobación de claves foráneas a la hora de actualizar los valores, pero va a valer el valor correcto se utiliza el tipo (ver De referencia de MySQL para más detalles).

    Siguiente, necesitamos actualizar nuestro Padre y el Hijo tablas con los nuevos valores. Vamos a utilizar la siguiente instrucción UPDATE para esto:

    UPDATE
        Parent,
        Child,
        NewIds
    SET
        Parent.ParentId = NewIds.Id,
        Child.ParentId = NewIds.Id
    WHERE
        Parent.ParentId = NewIds.ParentId AND
        Child.ParentId = NewIds.ParentId

    Ahora hemos actualizado todos nuestros ParentId valores correctamente a la nueva, ordenó a los Identificadores de nuestra tabla temporal. Una vez completado esto, podemos volver a nuestro instituto de clave externa controles para mantener la integridad referencial:

    SET foreign_key_checks = 1;

    Por último, vamos a colocar nuestra tabla temporal para limpiar los recursos:

    DROP TABLE NewIds

    Y es que.

    Yo no tenía idea de que podría hacer una combinación de varias tablas en una ACTUALIZACIÓN. Muy bueno, gracias!

    OriginalEl autor karlgrz

  3. 4

    Por lo general no necesita preocuparse de las lagunas. Si vas a llegar a la final de el tipo de datos para la IDENTIFICACIÓN debería ser relativamente fácil para MODIFICAR la tabla para actualizar a la siguiente más grande de tipo int.

    Si usted absolutamente debe empezar a llenar los vacíos, he aquí una consulta para devolver el menor a disposición de IDENTIFICACIÓN (esperemos que no sea demasiado lentamente):

    SELECT MIN(table0.id)+1 AS newid
    FROM table AS table0
    LEFT JOIN table AS table1 ON table1.id=table0.id+1
    WHERE table1.id IS NULL

    (recuerde que el uso de transacción y/o captura de clave duplicada inserciones si usted necesita inserciones simultáneas de trabajo.)

    Una pequeña corrección: si la tabla está vacía esta consulta devolverá NULL en lugar de 1. La solución rápida es usar SELECT IFNULL(MIN(que representa table0.id), 0) + 1 …

    OriginalEl autor bobince

  4. 2
    INSERT INTO prueba(id) 
    VALUES (
    (SELECT IFNULL( MAX( id ) , 0 )+1 FROM prueba target))

    IFNULL para saltar nula en el cero filas contar

    añadir destino para omitir el error de mysql «error DE la cláusula)

    Esto sólo se inserta una fila al final de la tabla con ID de max ID + 1.

    OriginalEl autor danis

  5. 1

    Hay una manera sencilla pero no funciona bien: Sólo intenta insertar con un id y cuando eso falla, pruebe la siguiente.

    Alternativamente, seleccione un ID y cuando no se consigue un resultado, el uso de la misma.

    Si usted está buscando una manera de decirle a la DB para rellenar automáticamente las lagunas, luego de que no es posible. Por otra parte, nunca debe ser necesario. Si usted siente que necesita, entonces usted está abusando de un técnico interno clave para algo, pero el solo propósito: permitir A usted para unirse a las mesas.

    [EDITAR] Si esto no es una clave principal, entonces usted puede utilizar esta instrucción de actualización:

    update (
        select *
        from table
        order by reg_id -- this makes sure that the order stays the same
    )
    set reg_id = x.nextval

    donde x es una nueva secuencia que se debe crear. Esto va a volver a numerar todos los elementos de la preservación del orden. Esto se producirá si usted tiene restricciones de clave externa. Y va a corromper la base de datos si hace referencia a estos Identificadores en cualquier lugar sin restricciones de clave externa.

    Tenga en cuenta que durante la inserción siguiente, la base de datos crear una enorme brecha a menos que restablezca la columna de identidad.

    OriginalEl autor Aaron Digulla

  6. 0

    Como otros han dicho, no importa, y si lo hace, entonces algo está mal en su diseño de base de datos. Pero, personalmente, me gusta estar en fin de todos modos!

    Aquí es algunos de SQL que se va a recrear su Id en el mismo orden, pero sin los espacios.

    Se hace primero en una temp_id campo (lo que será necesario crear), así que usted puede ver que está todo bien antes de sobrescribir su antiguo documento de identidad. Reemplazar Tbl y id según corresponda.

    SELECT @i:=0;
    UPDATE Tbl
    JOIN
    (
        SELECT id
        FROM Tbl
        ORDER BY id
    ) t2
    ON Tbl.id = t2.id
    SET temp_id = @i:[email protected]i+1;

    Ahora tendrá una temp_id de campo con todos los de su brillante nuevo Id. Usted puede hacerlos vivir simplemente:

    UPDATE Tbl SET id = temp_id;

    Y luego de dejar a su temp_id columna.

    Debo admitir que no estoy muy seguro de por qué funciona, ya que yo habría esperado que el motor se quejan de Identificadores duplicados, pero no cuando me encontré con él.

    OriginalEl autor Nigel Peck

  7. -1

    Puedes querer limpiar las lagunas en una columna de prioridad.
    La forma en que a continuación se dará un incremento automático de campo para la prioridad.
    El extra left join en la misma tabla se asegurará de que se agrega en el mismo orden (en este caso) la prioridad

    SET @a:=0;
    REPLACE INTO footable
     (id,priority)
        (
        SELECT tbl2.id, @a 
        FROM footable as tbl
        LEFT JOIN footable as tbl2 ON tbl2.id = tbl.id  
        WHERE (select @a:[email protected]a+1)
        ORDER BY tbl.priority
    )

    OriginalEl autor BvanRooijen

Dejar respuesta

Please enter your comment!
Please enter your name here