Как обработать фрагментацию столбца идентификатора автоинкремента в MySQL - PullRequest
4 голосов
/ 01 декабря 2009

У меня есть таблица с полем auto_increment, и иногда строки удаляются, поэтому auto_increment оставляет пропуски. Есть ли способ избежать этого или, если нет, как написать SQL-запрос, который:

  1. Изменяет значение auto_increment как максимальное (текущее значение) + 1
  2. Вернуть новое значение auto_increment?

Я знаю, как написать часть 1 и 2 , но можно ли поместить их в один и тот же запрос?

Если это невозможно:

как мне "выбрать" (вернуть) значение auto_increment или auto_increment значение + 1?

Ответы [ 5 ]

8 голосов
/ 01 декабря 2009

перенумерация вызовет путаницу. Существующие отчеты будут ссылаться на запись 99, и, тем не менее, если система перенумеровывает эту запись, она может изменить нумерацию этой записи на 98, теперь все отчеты (и заполненные пользовательские интерфейсы) неверны. После того, как вы присвоите уникальный идентификатор, он должен оставаться неизменным.

Использование полей идентификатора для чего-либо кроме простой уникальной нумерации будет проблематичным. Наличие требования «нет пробелов» просто несовместимо с требованием иметь возможность делить. Возможно, вы могли бы пометить записи как удаленные, а не удалять их. Тогда действительно нет пробелов. Скажем, вы производите нумерованные счета-фактуры: вместо этого вы бы отменили счет-фактуру с нулевым значением, а не удалили его.

1 голос
/ 08 мая 2013

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

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

Считайте, что у меня есть стол с автомобилями и стол с людьми

car
carid
ownerid
name

person
personid
name

А что есть некоторые простые данные

car
1 1 Van
2 1 Truck
3 2 Car
4 3 Ferrari
5 4 Pinto

person
1 Mike
2 Joe
3 John
4 Steve

и теперь я удаляю человека Джона.

person
1 Mike
2 Joe
4 Steve

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

1 Mike
2 Joe
3 Jim
4 Steve

и, по родству, будет владельцем Ferrari.

0 голосов
/ 25 декабря 2015

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

У меня есть таблица с полем auto_increment, и иногда строки удаляются, поэтому auto_increment оставляет пропуски. Есть ли способ избежать этого?

  1. Если в вашей таблице слишком много пробелов в столбце автоинкремента, вероятно, в результате такого большого количества тестов INSERT запросов
  2. И если вы хотите предотвратить чрезмерные значения идентификаторов, удалив пробелы
  3. А также, если столбец id является просто счетчиком и не имеет отношения к любому другому столбцу в вашей базе данных

, это может быть то, что вы (или любой другой человек, ищущий такую ​​вещь) ищут:

РЕШЕНИЕ

  1. удалить исходную id колонку
  2. добавьте его снова, используя auto_increment на

Но если вы просто хотите сбросить auto_increment на первое доступное значение:

ALTER TABLE `table_name` AUTO_INCREMENT=1
0 голосов
/ 01 июля 2015

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

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

Вот один из моментов, который нужно использовать в работе с гаечным ключом: сам MySQL (не менее 5,6 InnoDB) будет повторно использовать идентификатор автоинкремента в следующих случаях:

  • удалить любые числовые строки с наибольшим идентификатором автоинкремента
  • Остановитесь и запустите MySQL
  • вставить новую строку

Вставленная строка будет иметь идентификатор, рассчитанный как max (id) +1, не продолжится с идентификатора, который был удален.

0 голосов
/ 01 декабря 2009

не уверен, поможет ли это, но на сервере sql вы можете повторно заполнить поля идентификации. Кажется, в mySql есть оператор ALTER TABLE, чтобы добиться этого. Например, чтобы установить идентификатор для продолжения на 59446.

ALTER TABLE table_name AUTO_INCREMENT = 59446; 

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

...