Можно ли рассчитывать на автоинкрементный первичный ключ в вашей базе данных? - PullRequest
5 голосов
/ 10 мая 2009

В моем нынешнем приложении Rails я разрешаю конфликты планирования, сортируя модели по полю "created_at". Тем не менее, я понял, что при вставке нескольких моделей из формы, которая позволяет это, все created_at раз абсолютно одинаковы!

Это в большей степени вопрос лучших практик программирования: может ли ваше приложение полагаться на столбец идентификатора в вашей базе данных для увеличения и увеличения с каждым INSERT для получения порядка их создания? Другими словами, могу ли я отсортировать группу строк, которые я извлекаю из базы данных, по столбцу идентификатора и быть уверенным, что это точная сортировка на основе порядка создания? И это хорошая практика в моем приложении?

Ответы [ 7 ]

2 голосов
/ 10 мая 2009

Сгенерированные идентификационные номера будут уникальными. Независимо от того, используете ли вы Sequence, как в PostgreSQL и Oracle, или если вы используете другой механизм, такой как автоинкремент MySQL.

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

Следовательно, вы не должны использовать сгенерированное поле идентификатора для такой задачи, чтобы не полагаться на детали реализации базы данных.

Генерация созданного или обновленного поля во время выполнения команды намного удобнее для сортировки по времени создания или обновления позже. Например:

INSERT INTO A (data, created) VALUES (smething, DATE())
UPDATE A SET data=something, updated=DATE()
1 голос
/ 10 мая 2009

Это зависит от поставщика вашей базы данных.

MySQL Я считаю, что абсолютно автоматически заказывает ключи автоматического увеличения. SQL Server Я точно не знаю, так ли это или нет, но я верю, что это так.

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

Альтернативой может быть переход на созданное время, а затем идентификатор.

0 голосов
/ 11 мая 2009

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

0 голосов
/ 11 мая 2009

Вероятно, это зависит от двигателя БД. Я бы проверил, как ваша БД реализует последовательности, и если нет документированных проблем, я бы решил использовать ID.

например. Последовательность Postgresql в порядке, если вы не играете с параметрами кэша последовательности.

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

Мой совет - полагаться на сгенерированные последовательности идентификаторов и продвигать ваш проект вперед.

0 голосов
/ 10 мая 2009

Одна оговорка к ответу EJB:

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

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

0 голосов
/ 10 мая 2009

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

Для установки времени создания вы можете просто использовать значение по умолчанию, например:

CREATE TABLE foo (
  id INTEGER UNSIGNED AUTO_INCREMENT NOT NULL;
  created TIMESTAMP NOT NULL DEFAULT NOW();
  updated TIMESTAMP;
  PRIMARY KEY(id);
) engine=InnoDB; ## whatever :P

Теперь, это заботится о времени создания. со временем обновления я бы предложил триггер AFTER UPDATE, как этот (конечно, вы можете сделать это в отдельном запросе, но триггер, на мой взгляд, является лучшим решением - более прозрачным):

DELIMITER $$
CREATE TRIGGER foo_a_upd AFTER UPDATE ON foo
FOR EACH ROW BEGIN
  SET NEW.updated = NOW();
END;
$$
DELIMITER ;

И это должно сделать.

EDIT: Горе это я. Глупо я не уточнил, что это для mysql, могут быть некоторые различия в именах функций (а именно, 'NOW') и других тонких itty-bitty.

0 голосов
/ 10 мая 2009

Я полагаю, что ответ на ваш вопрос - да ... если я читаю между строк, я думаю, вы обеспокоены тем, что система может повторно использовать номера идентификаторов, которые «отсутствуют» в последовательности, и, следовательно, если вы имели использовал 1,2,3,5,6,7 в качестве идентификационных номеров, во всех известных мне реализациях следующий идентификационный номер всегда будет 8 (или, возможно, выше), но я не знаю ни одной БД, которая бы пыталась и выясните, что идентификатор записи № 4 отсутствует, поэтому попытайтесь повторно использовать этот идентификатор.

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

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

...