Это немного религиозный спор. Лично я предпочитаю синтетические первичные ключи, а не естественные первичные ключи, но у обеих сторон есть веские аргументы. На самом деле, если вы последовательны и разумны, любой подход может работать хорошо.
Если вы используете естественные ключи, двумя основными недостатками являются наличие составных ключей и изменение значений первичного ключа. Если у вас есть составные первичные ключи, вам, очевидно, придется иметь несколько столбцов в каждой дочерней таблице. Это может стать громоздким с точки зрения модели данных, когда между сущностями много отношений. Но это также может вызвать проблемы у людей, разрабатывающих запросы — очень легко создавать запросы, использующие N-1 из N условий соединения, и получать почти правильный результат. Если у вас есть естественные ключи, вы также неизбежно столкнетесь с ситуацией, когда значение естественного ключа изменится, и тогда вам придется распространить это изменение на множество различных сущностей — это намного сложнее, чем изменение уникального значения в таблице.
С другой стороны, если вы используете синтетические ключи, вы теряете место, добавляя дополнительные столбцы, добавляя дополнительные накладные расходы для поддержки дополнительного индекса, и вы увеличиваете риск получения функционально дублированных результатов. Ужасно легко либо забыть создать уникальное ограничение для бизнес-ключа, либо увидеть, что в комбинации есть неуникальный индекс, и просто предположить, что это был уникальный индекс. На самом деле пару дней назад меня укусил этот конкретный сбой: я проиндексировал составной естественный ключ (с неуникальным индексом), а не создал уникальное ограничение. Глупая ошибка, но сделать ее относительно легко.
С точки зрения написания запросов и соглашения об именах я бы также предпочел синтетические ключи, потому что приятно знать, когда вы соединяете таблицы, что первичный ключ A будет A_ID, а первичный ключ B будет B_ID . Это намного лучше самодокументируется, чем попытка запомнить, что первичный ключ A — это комбинация A_NAME и A_REVISION_NUMBER, а первичный ключ B — это B_CODE.
person
Justin Cave
schedule
10.02.2011