Проектирование базы данных - должна ли Date использоваться как часть первичного ключа - PullRequest
14 голосов
/ 04 декабря 2008

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

Ответы [ 10 ]

9 голосов
/ 04 декабря 2008

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

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

Редактировать: вот еще один комментарий, чтобы добавить.

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

4 голосов
/ 04 декабря 2008

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

4 голосов
/ 04 декабря 2008

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

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

3 голосов
/ 04 декабря 2008

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

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

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

2 голосов
/ 04 декабря 2008

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

  • праздничные дни (праздничная дата)
  • 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), но ссылка более полезна для общения с клиентом и т. Д. Мы могли бы сделать это в УНИКАЛЬНЫЕ ограничения, но на самом деле нам нужно более сложное «нет» перекрытие "проверить это.

2 голосов
/ 04 декабря 2008

Как всегда .. Зависит.

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

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

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

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

2 голосов
/ 04 декабря 2008

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

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

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

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

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

0 голосов
/ 04 декабря 2008

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

0 голосов
/ 04 декабря 2008

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

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

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

0 голосов
/ 04 декабря 2008

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...