Переупорядочить / сбросить первичный ключ автоинкремента - PullRequest
117 голосов
/ 11 апреля 2009

У меня есть таблица MySQL с первичным ключом с автоматическим приращением. Я удалил несколько строк в середине таблицы. Теперь у меня есть, например, что-то вроде этого в столбце ID: 12, 13, 14, 19, 20. Я удалил 15, 16, 17 и 18 строк.

Я хочу переназначить / сбросить / переупорядочить первичный ключ, чтобы у меня была непрерывность, то есть сделать 19 a 15, 20 a 16 и т. Д.

Как я могу это сделать?

Ответы [ 14 ]

0 голосов
/ 04 июня 2016

У меня были те же сомнения, но я не мог внести никаких изменений в таблицу, я решил сделать следующее, увидев, что мой идентификатор не превышает максимальное число, установленное в переменной @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;

Решение подходит, но оно безопасно и было необходимо, потому что в моей таблице были внешние ключи с данными в другой таблице.

0 голосов
/ 30 ноября 2015

Вы также можете просто избежать использования числовых идентификаторов в качестве первичного ключа. Вы можете использовать коды стран в качестве основного идентификатора, если в таблице хранится информация о странах, или вы можете использовать постоянные ссылки, если в нем содержатся статьи, например.

Вы также можете просто использовать случайное значение или значение MD5. Все эти опции имеют свои преимущества, особенно в сфере IT. числовые идентификаторы легко перечислить.

0 голосов
/ 25 августа 2014

для InnoDB, сделайте это (это удалит все записи из таблицы, сначала создайте bakcup):

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 ;
0 голосов
/ 29 марта 2014

Вы можете удалить функцию автоинкремента первичного ключа для этого столбца, затем каждый раз, когда вы обновляете этот столбец, запускаете запрос, который подсчитает все строки в таблице, а затем запускает цикл, который выполняет итерацию по количеству строк, вставляя каждый значение в соответствующую строку и, наконец, запустите запрос, вставив новую строку со значением этого столбца, равным общему количеству строк плюс один. Это будет работать безупречно и является самым абсолютным решением для того, кто пытается достичь того, кем вы являетесь. Вот пример кода, который вы можете использовать для функции:

$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')");

Здесь я создал ассоциативный массив, который я добавил в столбец ранга с запросом в запросе выбора, который дал каждой строке значение ранга, начинающееся с 1. Затем я перебрал ассоциативный массив.

Другим вариантом было бы получить количество строк, выполнить базовый запрос выбора, получить ассоциативный массив и выполнить итерацию таким же образом, но с добавленной переменной, которая обновляется через каждую итерацию. Это менее гибко, но выполнит то же самое.

$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')");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...