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

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

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

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

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

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

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

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

Charles Burns 29.11.2014 21:34
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
161
2
109 777
10
Перейти к ответу Данный вопрос помечен как решенный

Ответы 10

Как насчет FK_TABLENAME_COLUMNNAME?

Keep яt Simple Stupid, когда это возможно.

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

JohnC 11.04.2012 04:05

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

David Sherret 06.06.2016 21:22

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

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

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

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

nickf 14.10.2008 04:11

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

Steve Moyer 14.10.2008 04:15
Ответ принят как подходящий

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

FK_ForeignKeyTable_PrimaryKeyTable

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

FK_note_task

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

FK_task_user

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

FK_task_user
FK_note_task
FK_note_user

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

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

Greg Beech 14.10.2008 04:41

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

Greg Beech 14.10.2008 04:43

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

Steve Moyer 14.10.2008 04:47

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

Code Commander 12.01.2013 00:50

что, если в обеих таблицах есть символы подчеркивания, например. user_role и user_addresses? fk_user_addresses_user_role разве не сбивает с толку?

Govinda Sakhare 18.06.2015 14:25

@govi Да, это сбивает с толку (мне пришлось сделать это для Oracle). Но для SQL Server паскаль предпочтительнее подчеркивания. Обычно я просто добавляю суффикс к имени столбца в конец - например, FK_UserAddresses_UserRole_ToUserID и FK_UserAddresses_UserRole_FromUserID.

JumpingJezza 25.06.2015 04:14

@GregBeech Кроме того, вы можете добавить к этим именам числовой суффикс, если существует возможность множественных связей между двумя таблицами. Например, пользователь может «контролировать» несколько задач. В таких ситуациях вы можете назвать два внешних ключа FK_task_user_1, FK_task_user_2. Также вы можете использовать два символа подчеркивания в качестве разделителя (в случае таблиц с подчеркиванием в их именах), чтобы улучшить читаемость, как предлагает в один прекрасный день, когда.

Nikunj Madhogaria 16.08.2015 16:42

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

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))
        ...

Это абсолютно лучший ответ.

Frederik Krautwald 30.04.2015 12:30

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

Anddo 12.10.2019 16:08

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

spencer741 06.02.2021 04:22

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

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

fk_task_userid_user
fk_note_userid_user

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

fk_task_modifiedby_user
fk_note_modifiedby_user

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

A FOREIGN KEY constraint does not have to be linked only to a PRIMARY KEY constraint in another table; it can also be defined to reference the columns of a UNIQUE constraint in another table.

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

При ссылке на ПЕРВИЧНЫЙ КЛЮЧ таблицы независимый (родитель) с помощью столбца (столбцов) с аналогичным названием в таблице иждивенец (ребенок), я опускаю имена столбцов:

FK_ChildTable_ParentTable

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

FK_ChildTable_childColumn_ParentTable_parentColumn

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

spencer741 06.02.2021 04:26

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

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

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

SSISPissesMeOff 18.02.2016 02:33

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

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 символов., о чем заявил Чарльз Бернс в комментарии здесь

Note for readers: Many of the best practices listed below do not work in Oracle because of its 30 character name limit. A table name or column name may already be close to 30 characters, so a convention combining the two into a single name requires a truncation standard or other tricks. – Charles Burns

Ваш не удастся, если у вас есть 3-я таблица, у которой есть точка FK для той же таблицы ParentTableName_ParentColumnName с дублированием FK_Name

Tony Dong 12.06.2017 20:31

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

CONSTRAINT [FK_ChildTableName_ChildColName_ParentTableName_PrimaryKeyColName]

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

CONSTRAINT [FK_ChildTableName_ChildColumnName_ParentTableName_ColumnInUniqueConstaintName]

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

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

Например.

  • FK_4VPO_K4S2_A6M1_RQLEYLT1VQYV
  • FK_1786_45A6_A17C_F158C0FB343E
  • FK_45A5_4CFA_84B0_E18906927B53

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

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

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

spencer741 06.02.2021 08:22

Другие вопросы по теме