español - mysql tutorial
Reordenar/restablecer la clave primaria de incremento automático (12)
Tengo una tabla MySQL con una clave primaria de incremento automático. Borré algunas filas en el medio de la tabla. Ahora tengo, por ejemplo, algo así en la columna ID: 12, 13, 14, 19, 20. Eliminé las 15, 16, 17 y 18 filas.
Quiero reasignar / restablecer / reordenar la clave principal para que tenga continuidad, es decir, hacer el 19 a 15, el 20 a 16, y así sucesivamente.
¿Cómo puedo hacerlo?
Aunque esta pregunta parece ser bastante antigua, publicará una respuesta para alguien que busca aquí.
SET @count = 0;
UPDATE `users` SET `users`.`id` = @count:= @count + 1;
Si la columna se utiliza como una clave externa en otras tablas, asegúrese de usar ON UPDATE CASCADE
lugar del valor predeterminado ON UPDATE NO ACTION
para la relación de clave externa en esas tablas.
Además, para restablecer el recuento de AUTO_INCREMENT
, puede emitir inmediatamente la siguiente declaración.
ALTER TABLE `users` AUTO_INCREMENT = 1;
Para MySQL restablecerá el valor a MAX(id) + 1
.
La mejor opción es alterar la columna y eliminar el atributo auto_increment. A continuación, emita otra instrucción alter y vuelva a colocar auto_increment en la columna. Esto restablecerá el recuento al máximo +1 de las filas actuales y, por lo tanto, conservará las referencias de clave externa en esta tabla, en otras tablas de su base de datos o en cualquier otro uso de clave para esa columna.
O bien, desde PhpMyAdmin, elimine el indicador "AutoIncrement", guárdelo, configúrelo de nuevo y guárdelo. Esto lo restablece.
Para restablecer los ID de mi tabla de Usuario, uso la siguiente consulta SQL. Se ha dicho anteriormente que esto arruinará cualquier relación que pueda tener con otras tablas.
ALTER TABLE `users` DROP `id`;
ALTER TABLE `users` AUTO_INCREMENT = 1;
ALTER TABLE `users` ADD `id` int UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST;
Podría soltar la columna de clave principal y volver a crearla. Todos los identificadores deben ser reasignados en orden.
Sin embargo, esta es probablemente una mala idea en la mayoría de las situaciones. Si tiene otras tablas que tienen claves externas a esta tabla, definitivamente no funcionará.
Puede eliminar la funcionalidad de incremento automático de la clave principal de esa columna, y luego cada vez que actualice esa columna ejecutará una consulta previa que contará todas las filas de la tabla, luego ejecutará un ciclo que recorre ese recuento de filas insertando cada valor en el fila respectiva, y finalmente ejecuta una consulta insertando una nueva fila con el valor de esa columna como el recuento total de filas más uno. Esto funcionará sin problemas y es la solución más absoluta para alguien que intenta lograr lo que eres. Aquí hay un ejemplo de código que puede usar para la función:
$table_row_count = mysql_result(mysql_query("SELECT COUNT(`field_1`) FROM `table`"), 0);
$viewsrowsdata = mysql_query("
SELECT `rank`, `field1`, `field2`, `field3`, `field4`
FROM (SELECT (@rank:=@rank+1) as `rank`, `field1`, `field2`, `field3`, `field4`
FROM (SELECT * FROM `views`) a
CROSS JOIN (SELECT @rank:=0) b
ORDER BY rank ASC) c
");
while ($row = mysql_fetch_assoc($viewsrowsdata)) {
$data[] = $row;
}
foreach ($data as $row) {
$new_field_1 = (int)$row[''rank''];
$old_field_1 = (int)$row[''field1''];
mysql_query("UPDATE `table` SET `field_1` = $new_field_1 WHERE `field_1` = $old_field_1");
}
mysql_query("INSERT INTO `table` (`field1`, `field2`, `field3`, `field4`) VALUES (''$table_row_count'' + 1, ''$field_2_value'', ''field_3_value'', ''field_4_value'')");
Aquí creé una matriz asociativa que había agregado en una columna de rango con la consulta dentro de una consulta de selección, que daba a cada fila un valor de rango que comenzaba con 1. Luego iteraba a través de la matriz asociativa.
Otra opción habría sido obtener el recuento de filas, ejecutar una consulta de selección básica, obtener la matriz asociativa e iterarla de la misma manera, pero con una variable añadida que se actualiza a través de cada iteración. Esto es menos flexible pero logrará lo mismo.
$table_row_count = mysql_result(mysql_query("SELECT COUNT(`field_1`) FROM `table`"), 0);
$viewsrowsdata = mysql_query("SELECT * FROM `table`");
$updated_key = 0;
while ($row = mysql_fetch_assoc($viewsrowsdata)) {
$data[] = $row;
}
foreach ($data as $row) {
$updated_key = $updated_key + 1;
mysql_query("UPDATE `table` SET `field_1` = ''$updated_key'' WHERE `field_1` = ''$row[''field_1'']''");
}
mysql_query("INSERT INTO `table` (`field1`, `field2`, `field3`, `field4`) VALUES (''$table_row_count'' + 1, ''$field_2_value'', ''field_3_value'', ''field_4_value'')");
Puedes simplemente usar esta consulta
alter table abc auto_increment = 1;
También puede evitar el uso de ID numéricos como clave principal. Puede usar los códigos de país como ID principal si la tabla contiene información de países, o puede usar enlaces permanentes, si contiene artículos, por ejemplo.
También podría simplemente usar un valor aleatorio o MD5. Todas estas opciones tienen sus propios beneficios, especialmente en TI sec. Los ID numéricos son fáciles de enumerar.
Tenía las mismas dudas, pero no pude hacer ningún cambio en la tabla, decidí hacer lo siguiente después de haber visto que mi ID no excedía el número máximo establecido en la variable @count:
SET @count = 40000000;
UPDATE `users` SET `users`.`id` = @count:= @count + 1;
SET @count = 0;
UPDATE `users` SET `users`.`id` = @count:= @count + 1;
ALTER TABLE `users` AUTO_INCREMENT = 1;
La solución toma, pero es segura y fue necesaria porque mi tabla poseía claves externas con datos en otra tabla.
para InnoDB, haz esto (esto eliminará todos los registros de una tabla, crea una bakcup primero):
SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS ;
SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION ;
SET NAMES utf8 ;
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 ;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 ;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE=''NO_AUTO_VALUE_ON_ZERO'' ;
SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 ;
/* ================================================= */
drop table tablename;
CREATE TABLE `tablename` (
table structure here!
) ENGINE=InnoDB AUTO_INCREMENT= ai number to reset DEFAULT CHARSET= char set here;
/* ================================================= */
SET SQL_MODE=@OLD_SQL_MODE ;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS ;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS ;
SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT ;
SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS ;
SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION ;
SET SQL_NOTES=@OLD_SQL_NOTES ;
SET @num := 0;
UPDATE your_table SET id = @num := (@num+1);
ALTER TABLE your_table AUTO_INCREMENT =1;
Creo que esto lo hará