Самый эффективный способ получить следующий неиспользованный идентификатор - PullRequest
5 голосов
/ 25 августа 2010

(относится к Нахождение наименьшего неиспользуемого уникального идентификатора в списке и Получение неиспользуемых уникальных значений в таблице SQL )

ПредположимУ меня есть таблица, содержащая столбец id и некоторые другие (здесь они не имеют никакого значения):

+-----+-----+
| id  |other|
+-----+-----+

Идентификатор имеет числовое возрастающее значение.Моя цель - получить самый низкий неиспользуемый идентификатор и создать эту строку.Поэтому, конечно, при первом запуске он вернет 0, и строка этого ряда будет создана.После нескольких выполнений это будет выглядеть так:

+-----+-----+
| id  |other|
+-----+-----+
|  0  | ... |
|  1  | ... |
|  2  | ... |
|  3  | ... |
|  4  | ... |
+-----+-----+

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

+-----+-----+
| id  |other|
+-----+-----+
|  0  | ... |
|  2  | ... |
|  4  | ... |
+-----+-----+

Если я сейчас снова выполню запрос, он хотел бы получить идентификатор 1, и должна быть создана эта строка:

| id  |other|
+-----+-----+
|  0  | ... |
|  1  | ... |
|  2  | ... |
|  4  | ... |
+-----+-----+

В следующий раз, когда запрос выполняется, он должен вернуть идентификаторы 3, 5, 6 и т. Д.

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

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

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

Ответы [ 4 ]

2 голосов
/ 25 августа 2010

Как Деннис Харбринк сказал; триггер при удалении и другой при вставке:

Триггер на удаление возьмет удаленный идентификатор и вставит его в таблицу пула идентификаторов (только один столбец id)

Триггер перед вставкой будет проверять, предоставлено ли значение идентификатора, в противном случае он просто запрашивает таблицу пула идентификаторов (например: SELECT MIN (id) FROM id_pool_table) и назначает ее (например, удаляет ее из id_pool_table)

2 голосов
/ 25 августа 2010

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

Самый быстрый и безопасный способ создания значения идентификатора - полагаться на встроенную функциональность, которая дает уникальное целочисленное значение (IE: автоинкремент SQLite). Использование триггеров только увеличивает накладные расходы, использование MAX (id) +1 крайне рискованно ...

Основная информация

В идеале для первичного ключа следует использовать собственный генератор целочисленных значений (автоинкремент SQLite / MySQL, последовательности Oracle / PostgreSQL, IDENTITY SQL Server). Если вы хотите, чтобы значение всегда было последовательным, добавьте дополнительный столбец, чтобы сохранить это последовательное значение и поддерживать его при необходимости. Генерация уникальных целых чисел в MySQL / SQLite / SQL Server допускается только по одному на столбец - последовательности более гибкие.

2 голосов
/ 25 августа 2010

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

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

1 голос
/ 25 августа 2010

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

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

...