Схема именования внешнего ключа


153

Я только начинаю работать с внешними ключами в первый раз, и мне интересно, есть ли стандартная схема именования для них?

Учитывая эти таблицы:

task (id, userid, title)
note (id, taskid, userid, note);
user (id, name)

Там, где у Задач есть Заметки, Задачи принадлежат Пользователям, а Пользователям - Примечания автора.

Как бы назвали три внешних ключа в этой ситуации? Или, наоборот, это вообще имеет значение ?

Обновление : этот вопрос касается имен внешних ключей, а не имен полей!


6
Примечание для читателей. Многие из перечисленных ниже рекомендаций не работают в Oracle из-за ограничения имени в 30 символов. Имя таблицы или имя столбца уже может быть близко к 30 символам, поэтому соглашение, объединяющее их в одно имя, требует стандарта усечения или других приемов.
Чарльз Бернс

Ответы:


180

Стандартное соглашение в SQL Server:

FK_ForeignKeyTable_PrimaryKeyTable

Так, например, ключ между заметками и задачами будет:

FK_note_task

И ключ между задачами и пользователями будет:

FK_task_user

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

FK_task_user
FK_note_task
FK_note_user

Таким образом, вы можете видеть, что задачи зависят от пользователей, а заметки зависят как от задач, так и от пользователей.


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

4
Вы включаете текущее имя таблицы в ключ, чтобы оно отличалось. Имена FK находятся в глобальном пространстве имен в SQL Server, поэтому нельзя иметь два FK с именем FK_PrimaryKeyTable, подключенных к двум различным таблицам внешнего ключа. Правила могут отличаться для других серверов баз данных.
Грег Бук

Хорошо ... У меня есть разные пространства имен для каждой таблицы в Oracle, поэтому мне не нужна собственная ссылка.
Стив Мойер

29
Кажется, это обычное использование, но что делать людям, когда два внешних ключа указывают на одну и ту же таблицу. то есть messageтаблица имеет from_user_idи to_user_idоба из них станут fk_message_user. Мне кажется, лучше использовать fk_tablename_columnname(fk_message_from_user_id в моем примере) по этой причине, а затем попытаться сохранить имена столбцов в ясности относительно целевой таблицы (т. Е. To_user_id явно ссылается на пользовательскую таблицу)
Code Commander

Что делать, если обе таблицы имеют подчеркивания для ex. user_role и user_addresses? fk_user_addresses_user_role это не смущает?
Гови С.

38

Я использую два символа подчеркивания в качестве разделителя, т.е.

fk__ForeignKeyTable__PrimaryKeyTable 

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

CREATE TABLE NaturalPersons (
   ...
   person_death_date DATETIME, 
   person_death_reason VARCHAR(30) 
      CONSTRAINT person_death_reason__not_zero_length
         CHECK (DATALENGTH(person_death_reason) > 0), 
   CONSTRAINT person_death_date__person_death_reason__interaction
      CHECK ((person_death_date IS NULL AND person_death_reason IS NULL)
              OR (person_death_date IS NOT NULL AND person_death_reason IS NOT NULL))
        ...

3
Это абсолютно лучший ответ.
Фредерик Краутвальд

1
Я только что создал Derby DB с очень специфическим соглашением об именах, и этот здесь самый читаемый и прослеживаемый. Спасибо
Anddo

17

Как насчет FK_TABLENAME_COLUMNNAME?

К EEP I т S реали S tupid всякий раз , когда это возможно.


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

1
@JohnC, если имена столбцов FK имеют другое имя таблицы в имени столбца, то разве это не должно быть очень легко узнать? Он сообщает вам две таблицы и имя столбца, в котором он определен. Пример: FK_Animals_OwnerIDтаблица «Животные и владельцы», определенная в столбце OwnerID
Дэвид Шеррет

10

Примечание от Microsoft относительно SQL Server:

Ограничение FOREIGN KEY не обязательно должно быть связано только с ограничением PRIMARY KEY в другой таблице; он также может быть определен для ссылки на столбцы ограничения UNIQUE в другой таблице.

поэтому я буду использовать термины, описывающие зависимость, вместо традиционных терминов первичные / внешние отношения.

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

FK_ChildTable_ParentTable

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

FK_ChildTable_childColumn_ParentTable_parentColumn

9

Я обычно просто оставляю свой PK с именем id, а затем объединяю свое имя таблицы и имя ключевого столбца при именовании FK в других таблицах. Я никогда не зацикливался на верблюжьем загоне, потому что некоторые базы данных отбрасывают чувствительность к регистру и в любом случае просто возвращают все прописные или строчные буквы. В любом случае, вот как будет выглядеть моя версия ваших таблиц:

task (id, userid, title);
note (id, taskid, userid, note);
user (id, name);

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


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

Так что, по крайней мере, мы можем читать схемы друг друга;) ... что смущает то, что вы не можете читать свои собственные после пары лет отсутствия. Мы используем ERWin для построения диаграмм наших схем, но часто бывает удобно иметь текстовую версию и соглашение, позволяющее легко находить таблицы и поля.
Стив Мойер

5

Это, вероятно, чрезмерное убийство, но это работает для меня. Это очень помогает мне, особенно когда я имею дело с VLDB. Я использую следующее:

CONSTRAINT [FK_ChildTableName_ChildColName_ParentTableName_PrimaryKeyColName]

Конечно, если по какой-то причине вы не ссылаетесь на первичный ключ, вы должны ссылаться на столбец, содержащийся в уникальном ограничении, в этом случае:

CONSTRAINT [FK_ChildTableName_ChildColumnName_ParentTableName_ColumnInUniqueConstaintName]

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


1

Мой обычный подход

FK_ColumnNameOfForeignKey_TableNameOfReference_ColumnNameOfReference

Или другими словами

FK_ChildColumnName_ParentTableName_ParentColumnName

Таким образом, я могу назвать два внешних ключа, которые ссылаются на одну и ту же таблицу, как history_info tableс column actionBy and actionToиз users_infoтаблицы

Это будет как

FK_actionBy_usersInfo_name - For actionBy
FK_actionTo_usersInfo_name - For actionTo

Обратите внимание, что:

Я не включил имя дочерней таблицы, потому что это кажется мне здравым смыслом, я нахожусь в таблице ребенка, поэтому я могу легко принять имя таблицы ребенка. Его общий характер равен 26 и хорошо соответствует пределу оракула в 30 символов, который был изложен Чарльзом Бернсом в комментарии здесь.

Примечание для читателей. Многие из перечисленных ниже рекомендаций не работают в Oracle из-за ограничения имени в 30 символов. Имя таблицы или имя столбца уже может быть близко к 30 символам, поэтому соглашение, объединяющее их в одно имя, требует стандарта усечения или других приемов. - Чарльз Бернс


Ваша будет провалена, если у вас в 3-й таблице есть FK, указывающая на ParentTableName_ParentColumnName ту же таблицу с дубликатом FK_Name
Тони Донг

0

Основываясь на ответах и ​​комментариях здесь, соглашение об именах, которое включает в себя таблицу FK, поле FK и таблицу PK (FK_FKTbl_FKCol_PKTbl), должно избегать коллизий имен ограничений FK.

Итак, для приведенных таблиц здесь:

fk_task_userid_user
fk_note_userid_user

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

fk_task_modifiedby_user
fk_note_modifiedby_user

-2

Если вы не часто ссылаетесь на свои FK и используете MySQL (и InnoDB), вы можете просто позволить MySQL назвать FK для вас.

Позже вы можете найти нужное имя FK, выполнив запрос .


4
Я могу только объяснить свой отрицательный голос. Почти каждая система баз данных позволяет системе называть ограничения. Можете ли вы представить себе возможность вернуться назад и попытаться быстро выяснить во время производственной проблемы даже базу данных из 100 таблиц, пытаясь расшифровать, к каким отношениям относится FK__123ee456ff? Это просто и просто положить ужасную практику. Когда вы строите индекс для этого FK, то что? системные имена это тоже? поэтому, когда индекс IX_007e373f5963 фрагментирован на 98%, как вы узнаете, где искать, чтобы выяснить, почему? Это просто не должно быть сделано.
SSISPissesMeOff

-3

Попробуйте использовать UUID версии 4 в верхнем регистре с заменой первого октета на FK и '_' (подчеркивание) вместо '-' (тире).

Например

  • FK_4VPO_K4S2_A6M1_RQLEYLT1VQYV
  • FK_1786_45A6_A17C_F158C0FB343E
  • FK_45A5_4CFA_84B0_E18906927B53

Обоснованием является следующее

  • Строгий алгоритм генерации => единообразные имена ;
  • Длина ключа не превышает 30 символов , что ограничивает длину имени в Oracle (до 12c);
  • Если ваше имя сущности изменяется, вам не нужно переименовывать свой FK, как в подходе, основанном на имени сущности (если DB поддерживает оператор переименования таблиц);
  • Редко можно использовать имя ограничения внешнего ключа. Например, инструмент БД обычно показывает, к чему применяется ограничение. Не нужно бояться загадочного взгляда, потому что вы можете избежать его использования для «расшифровки».
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.