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

Каковы плюсы и минусы для включения поля даты в качестве части первичного ключа?

Ответ 1

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

Таким образом, нет ничего плохого в этом, но, как и любой другой метод, его можно использовать неправильно, как в примере Патрика.

Изменить: здесь добавлен еще один комментарий.

Мне напомнили кое-что, что я написал некоторое время назад, о том, действительно ли значения даты в базах данных были естественными или синтетическими. Читаемое представление даты как "ГГГГ-ММ-ДД", конечно, естественно, но внутренне в Oracle это хранится в виде числа, которое просто представляет эту конкретную дату/время для Oracle. Мы можем выбирать и изменять представление этого внутреннего значения в любое время (в разные читаемые форматы или в другую систему календаря целиком) без внутреннего значения, теряющего его значение в качестве конкретной даты и времени. Я думаю, что на этом основании тип данных DATE находится где-то между естественным и синтетическим.

Ответ 2

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

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

Ответ 3

если вы уже решили использовать "естественный" первичный ключ, тогда возникает вопрос: является ли дата необходимой частью первичного ключа или нет - плюсы/минусы не имеют значения!

Ответ 4

Есть несколько вопросов, которые я задал бы об использовании даты как части первичного ключа.

Включает ли эта цифра временную часть? Это делает вещи сложными, потому что время включает часовые пояса и летнее время. Это не изменяет значение даты/времени, но может привести к неожиданным результатам с точки зрения сортировки или получения значений на основе запроса.

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

Ответ 5

Небольшое совпадение состоит в том, что он не так элегантен, как некоторые другие идентификаторы

(например, сказать коллеге, пожалуйста, можете ли вы посмотреть на запись 475663, это немного проще, чем сказать, пожалуйста, посмотрите на 2008-12-04 19:34:02)

Существует также риск путаницы в разных форматах даты в разных местах

(например, 4 марта 2008 г. - 4/3/2008 в Европе, 3/4/2008 в США)

(Мое предпочтение всегда заключается в использовании отдельного столбца ключа)

Ответ 6

Как всегда.. Это зависит.

Какова ваша цель включить столбец даты/времени в ПК? Должна ли она предоставлять дополнительную информацию о записи без фактического выбора строки?

Основная проблема, которую я могу предвидеть здесь, - очевидные, т.е. вы используете дату UTC или локальную дату? Будет ли неверна интерпретация даты (кто-нибудь подумает, что это означает местное время, когда это означает UTC)? Как некоторые из других предположили, что это может быть лучше использовано в суррогатном/составном ключе вместо этого? Возможно, вам лучше использовать его в ключе или индексе, отличном от Первичного ключа.

[Side note] Этот вид напоминает мне теорию (1) COMB (комбинированный GUID), хотя идея здесь была для создания уникального идентификатора для ПК, который SQL Server лучше индексировал/требовал меньше перестройки индекса, а не добавлял значимую дату/время в строку.

(1) [http://www.informit.com/articles/article.aspx?p=25862&seqNum=7]

Ответ 7

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

  • holiday_dates (дата hol_date)
  • employee_salary (employee_id integer, sal_start_date date)

(Какой смысл добавлять суррогатный employee_salary_id выше?)

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

  • hotel_room_booking (booking_reference)

Мы могли бы использовать (room_no, booking_from_date) или (room_no, booking_to_date), но ссылка более полезна для общения с клиентом и т.д. Мы можем сделать их ограниченными УНИКАЛЬНЫМИ ограничениями, но на самом деле нам нужно более сложное "нет" накладывать "на них.

Ответ 8

Дата в качестве единственного или первого компонента первичного ключа вызывает проблемы с производительностью в таблицах с высокой вставкой. (Таблицу нужно часто перебалансировать).

Часто возникает проблема, если в каждую дату добавлено более одного.

В большинстве случаев я считаю этот плохой запах и не советовал ему.

Ответ 9

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

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

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

Ответ 10

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