mysql автоматически увеличивает идентификаторы первичного ключа - PullRequest
0 голосов
/ 17 октября 2010

Как найти номер идентификатора удаления, который был использован, но удален, поскольку он больше не используется, прежде чем просто добавить поверх последнего добавленного номера идентификатора

Например:

  ID      Name

  1       Orange
  5       Apple

У меня включено автоинкремент, я хочу добавить банан в число 2, но автоинкремент добавляет его как идентификатор 6

Ответы [ 6 ]

1 голос
/ 17 октября 2010

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

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

1) пользователь А хочет вставить, поэтому ищет наименьший доступный идентификатор
2) пользователь B хочет вставить, поэтому ищет наименьший доступный идентификатор
3) пользователь A находит наименьший доступный идентификатор из 2
4) пользователь B находит наименьший доступный идентификатор из 2
5) пользователь A вставляет строку и использует ID 2
6) пользователь B вставляет строку и пытается использовать ID 2 и либо успешно (что делает ключ более не уникальным), либо завершается неудачно, потому что ID 2 уже использовался.

Каково предназначение этого?

1 голос
/ 17 октября 2010

Это не то, как работает автоинкремент.

Я почти уверен, что вам придется найти недостающие идентификаторы и назначить их самостоятельно.

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

0 голосов
/ 17 октября 2010

Хорошо, у меня есть ответ. Но если ты используешь это, я собираюсь выйти и избить тебя! Этот подзапрос найдет самую низкую дыру в идентификаторах. Просто замените слово table на имя вашей таблицы.

INSERT INTO
    table
SET
    id = (
        SELECT
            MIN(a.id + 1)
        FROM
            table a
            LEFT JOIN table b
                ON a.id + 1 = b.id
        WHERE
            b.id IS NULL
    ),
    name = 'next'
0 голосов
/ 17 октября 2010

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

Способ автоматического увеличения состоит в том, что у него есть счетчик, который увеличивается для каждой вставленной строки. При удалении строк счетчик не меняется.

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

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

0 голосов
/ 17 октября 2010

Так работает auto-inc.

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

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

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

0 голосов
/ 17 октября 2010

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

...