Автоинкремент после удаления в MySQL - PullRequest
62 голосов
/ 06 февраля 2010

У меня есть таблица MySQL с полем первичного ключа с включенным AUTO_INCREMENT. Прочитав другие посты здесь, я заметил людей с такой же проблемой и с разными ответами. Некоторые рекомендуют не использовать эту функцию, другие утверждают, что ее нельзя «исправить».

У меня есть:

table: course
fields: courseID, courseName

Пример: количество записей в таблице: 18. Если я удалю записи 16, 17 и 18 - я ожидаю, что следующая введенная запись будет иметь идентификатор курса из 16, однако это будет 19, поскольку последний введенный идентификатор курса был 18 .

Мои знания SQL не удивительны, но есть ли возможность обновить или обновить это количество с помощью запроса (или параметра в интерфейсе phpMyAdmin)?

Эта таблица будет относиться к другим в базе данных.


Учитывая все советы, я решил проигнорировать эту «проблему». Я просто удаляю и добавляю записи, пока автоинкремент выполняет свою работу. Я думаю, что на самом деле не имеет значения, что это за номер, поскольку он используется только в качестве уникального идентификатора и не имеет (как упоминалось выше) business значения.

Для тех, кого я, возможно, перепутал с моим оригинальным постом: я не хочу использовать это поле, чтобы знать, сколько у меня записей. Я просто хотел, чтобы база данных выглядела аккуратно и была более согласованной.

Ответы [ 16 ]

66 голосов
/ 06 февраля 2010

То, что вы пытаетесь сделать, звучит опасно, поскольку оно не предназначено для AUTO_INCREMENT.

Если вы действительно хотите найти наименьшее значение неиспользованного ключа, вообще не используйте AUTO_INCREMENT и управляйте своими ключами вручную. Тем не менее, это НЕ рекомендуемая практика.

Сделайте шаг назад и спросите «, зачем вам нужно повторно использовать значения ключей? » Разве беззнаковые INT (или BIGINT) не предоставляют достаточно большого пространства ключей?

Действительно ли у вас будет более 18,446,744,073,709,551,615 уникальных записей в течение срока службы вашего приложения?

35 голосов
/ 06 февраля 2010
ALTER TABLE foo AUTO_INCREMENT=1

Если вы удалили самые последние записи, это должно привести к использованию следующей самой низкой доступной записи. Например, если нет уже 19, удаление 16-18 приведет к сбросу автоинкремента для использования 16.


РЕДАКТИРОВАТЬ: Я пропустил немного о phpmyadmin. Вы также можете установить его там. Перейдите на экран таблицы и щелкните вкладку операций. Там есть поле AUTOINCREMENT, в котором вы можете вручную установить все, что вам нужно.

16 голосов
/ 06 февраля 2010

Первичные автоинкрементные ключи в базе данных используются для уникальной идентификации данной строки и не должны иметь никакого значения business . Поэтому оставьте первичный ключ как есть и добавьте еще один столбец с именем, например courseOrder. Затем, когда вы удаляете запись из базы данных, вы можете отправить дополнительный оператор UPDATE, чтобы уменьшить столбец courseOrder всех строк, которые на courseOrder больше, чем та, которую вы сейчас удаляете.

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

9 голосов
/ 26 февраля 2015

Попробуйте:

SET @num: = 0;

ОБНОВЛЕНИЕ your_table SET id = @num: = (@ num + 1);

ALTER TABLE tableName AUTO_INCREMENT = 1;

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

пример: до

  • 1: первое значение здесь
  • 2: второе значение здесь
  • X: удаленное значение
  • 4: остальная часть стола
  • 5: остальное остальное ..

, поэтому в таблице будет отображаться массив: 1,2,4,5

Пример: ПОСЛЕ (если вы воспользуетесь этой командой, вы получите)

  • 1: первое значение здесь
  • 2: второе значение здесь
  • 3: остальная часть стола
  • 4: остаток от остальных

Нет следа от удаленного значения, а остальная часть увеличенного продолжается с этим новым счетчиком.

НО

  1. Если где-то в вашем коде что-то использовать автоинкрементное значение ... возможно, это приписывание вызовет проблему.
  2. Если вы не используете это значение в вашем коде, все должно быть в порядке.
3 голосов
/ 06 февраля 2010

Вы не должны полагаться на идентификатор AUTO_INCREMENT, чтобы сообщить вам, сколько записей у вас в таблице. Вы должны использовать SELECT COUNT(*) FROM course. Идентификаторы предназначены для уникальной идентификации курса и могут использоваться в качестве ссылок в других таблицах, поэтому не следует повторять идентификаторы и не пытаться сбросить поле автоинкремента.

2 голосов
/ 19 мая 2014

Я пришел сюда в поисках ответа на заглавный вопрос "MySQL - Auto Increment after delete", но я смог найти ответ на этот вопрос только в вопросах

Используя что-то вроде:

DELETE FROM table;
ALTER TABLE table AUTO_INCREMENT = 1;

Обратите внимание, что Ответ Дарина Димитрова действительно хорошо объясняет AUTO_INCREMENT и его использование. Взгляните туда, прежде чем делать что-то, о чем вы могли бы пожалеть.

PS: сам вопрос больше "Why you need to recycle key values?" и ответ Дольфа покрыть это.

2 голосов
/ 06 февраля 2010

вы можете выбрать идентификаторы так:

set @rank = 0;
select id, @rank:=@rank+1 from tbl order by id

Результатом является список идентификаторов и их позиции в последовательности.

Вы также можете сбросить идентификаторы так:

set @rank = 0;
update tbl a join (select id, @rank:=@rank+1 as rank from tbl order by id) b
  on a.id = b.id set a.id = b.rank;

Вы также можете просто распечатать первый неиспользуемый идентификатор, например:

select min(id) as next_id from ((select a.id from (select 1 as id) a
  left join tbl b on a.id = b.id where b.id is null) union
  (select min(a.id) + 1 as id from tbl a left join tbl b on a.id+1 = b.id
  where b.id is null)) c;

после каждой вставки вы можете сбросить auto_increment:

alter table tbl auto_increment = 16

или явно установить значение id при вставке:

insert into tbl values (16, 'something');

обычно в этом нет необходимости, у вас есть count(*) и возможность создать рейтинг в ваших наборах результатов. типичный рейтинг может быть:

set @rank = 0;
select a.name, a.amount, b.rank from cust a,
  (select amount, @rank:=@rank+1 as rank from cust order by amount desc) b
  where a.amount = b.amount

клиентов, ранжированных по потраченной сумме.

1 голос
/ 02 сентября 2016

Существует способ исправить это. Сначала вы удаляете столбец первичного ключа auto_incremented, а затем добавляете его снова, например:

ALTER TABLE table_name DROP column_name;
ALTER TABLE table_name ADD column_name int not null auto_increment primary key first;
1 голос
/ 15 января 2016

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

ALTER TABLE my_table ADD `ID` INT NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY (`ID`);

Для работающей системы это не очень хорошая идея, особенно если есть другие таблицы с внешними ключами, указывающими на нее.

1 голос
/ 01 декабря 2012

Я получил очень простой, но хитрый способ.

При удалении строки вы можете сохранить идентификаторы в другой временной таблице. После этого, когда вы будете вставлять новые данные в основную таблицу, вы сможете искать и выбирать идентификаторы из временной таблицы. Так что используйте проверку здесь. Если временная таблица не имеет идентификаторов, рассчитайте максимальный идентификатор в основной таблице и установите новый идентификатор как: new_ID = old_max_ID+1.

NB. Вы не можете использовать здесь функцию автоинкремента.

...