MySQL Удалить все строки из таблицы и сбросить идентификатор на ноль

183

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

marek_lani
источник

Ответы:

304

Не удаляйте, используйте усечение:

Truncate table XXX

Обработчик таблицы не запоминает последнее использованное значение AUTO_INCREMENT, но начинает отсчет с начала. Это верно даже для MyISAM и InnoDB, которые обычно не используют значения последовательности.

Источник .

Francois
источник
20
Усечение хорошо работает с неограниченными таблицами, но если ваша таблица имеет ограничение внешнего ключа, вы можете рассмотреть возможность использования метода Delete. Смотрите этот пост, если у вас есть ограничения FK: усекать таблицу ограничений внешнего ключа
Джулиан Соро
1
помните, что урезанная таблица не будет отката
пенни чан
83

Если вы не можете использовать TRUNCATE(например, из-за ограничений внешнего ключа), вы можете использовать таблицу изменения после удаления всех строк, чтобы перезапустить auto_increment:

ALTER TABLE mytable AUTO_INCREMENT = 1
a_horse_with_no_name
источник
3
@NBhargav Поскольку вы можете использовать движок InnoDB на своей таблице вместо MyISAM, первый не поддерживает сброс индекса.
Густаво Рубио
как удалить все строки перед изменением значения auto_increment
Касун Сиямбалапития
@KasunSiyambalapitiya DELETE FROM tablename;(но это не будет работать хорошо, когда есть ограничения FK - см. Stackoverflow.com/a/5452798/507761 )
Мэтью Рид
17

Если таблица имеет внешние ключи, тогда я всегда использую следующий код:

SET FOREIGN_KEY_CHECKS = 0; -- disable a foreign keys check
SET AUTOCOMMIT = 0; -- disable autocommit
START TRANSACTION; -- begin transaction

/*
DELETE FROM table_name;
ALTER TABLE table_name AUTO_INCREMENT = 1;
-- or
TRUNCATE table_name;
-- or
DROP TABLE table_name;
CREATE TABLE table_name ( ... );
*/

SET FOREIGN_KEY_CHECKS = 1; -- enable a foreign keys check
COMMIT;  -- make a commit
SET AUTOCOMMIT = 1 ;

Но разница будет во времени исполнения. Посмотрите на ответ Сорина выше.

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

Интересный факт.

Я был уверен, TRUNCATEчто всегда будет работать лучше, но в моем случае для базы данных с приблизительно 30 таблицами с внешними ключами, заполненной всего несколькими строками, для TRUNCATEвсех таблиц потребовалось около 12 секунд , а не несколько сотен миллисекунд дляDELETE строк. Установка автоматического приращения добавляет около секунды, но все равно намного лучше.

Так что я бы посоветовал попробовать оба, посмотреть, что работает быстрее для вашего случая.

Сорин
источник
2

если вы хотите использовать, truncateиспользуйте это:

SET FOREIGN_KEY_CHECKS = 0; 
TRUNCATE table $table_name; 
SET FOREIGN_KEY_CHECKS = 1;
david2020
источник