Я только начинаю работать с внешними ключами в первый раз, и мне интересно, есть ли для них стандартная схема именования?
Учитывая эти таблицы:
task (id, userid, title)
note (id, taskid, userid, note);
user (id, name)
Если у Задач есть Заметки, Задачи принадлежат Пользователям, а Пользователи создают Заметки.
Как бы в этой ситуации были названы три внешних ключа? Или, как вариант, это вообще имеет значение?
Обновлять: этот вопрос касается имен внешних ключей, а не имен полей!
Возможный дубликат Именование столбцов идентификаторов в таблицах базы данных

Как насчет FK_TABLENAME_COLUMNNAME?
Keep яt Simple Stupid, когда это возможно.
Потому что, когда у вас есть огромная база данных с большим количеством ключей и таблиц, и вы получаете сообщение об ошибке во время обновления схемы в своем программном обеспечении, довольно сложно найти, где определяется внешний ключ, даже не выполнив поиск сценария создания базы данных.
@JohnC, если имена столбцов FK имеют другое имя таблицы в имени столбца, разве это не должно быть очень легко определить? Он сообщает вам две таблицы и имя столбца, для которого они определены. Пример: FK_Animals_OwnerID - Таблица животных и владельцев, определенная в столбце OwnerID.
Обычно я просто оставляю свой PK с именем id, а затем объединяю имя моей таблицы и имя ключевого столбца при именовании FK в других таблицах. Я никогда не беспокоюсь о верблюжьем регистре, потому что некоторые базы данных не учитывают регистр и в любом случае просто возвращают все имена в верхнем или нижнем регистре. В любом случае вот как будет выглядеть моя версия ваших таблиц:
task (id, userid, title);
note (id, taskid, userid, note);
user (id, name);
Обратите внимание, что я также называю свои таблицы в единственном числе, потому что строка представляет один из объектов, которые я сохраняю. Многие из этих условностей являются личными предпочтениями. Я бы сказал, что гораздо важнее выбрать соглашение и всегда использовать его, чем принимать чье-то соглашение.
хех - это точный стиль, который я использую на самом деле (но с camelCase) - я подумал, что добавлю немного дополнительного описания к именам, чтобы проиллюстрировать их связи.
Так что, по крайней мере, мы можем читать схемы друг друга;) ... стыдно не читать свои собственные после пары лет отсутствия. Мы используем ERWin для построения схем наших схем, но часто бывает удобно иметь текстовую версию, а соглашение позволяет легко находить таблицы и поля.
Стандартное соглашение в SQL Server:
FK_ForeignKeyTable_PrimaryKeyTable
Так, например, ключ между заметками и задачами будет:
FK_note_task
И ключом между задачами и пользователями будет:
FK_task_user
Это дает вам «с первого взгляда» представление о том, какие таблицы задействованы в ключе, поэтому легко увидеть, от каких таблиц зависит конкретная таблица (первая названная) (вторая названная). В этом сценарии полный набор ключей будет:
FK_task_user
FK_note_task
FK_note_user
Итак, вы можете видеть, что задачи зависят от пользователей, а заметки зависят как от задач, так и от пользователей.
Если внешний ключ указывает на ключ-кандидат во второй таблице, а не на первичный ключ, вы, вероятно, использовали бы третий сегмент имени, чтобы квалифицировать это. Это необычная ситуация, которую вы обычно не разрабатываете с нуля, поэтому я не включил это в ответ.
Вы включаете в ключ текущее имя таблицы, чтобы оно оставалось отличным. Имена FK находятся в глобальном пространстве имен в SQL Server, поэтому у вас не может быть двух FK с именем FK_PrimaryKeyTable, прикрепленных к двум разным таблицам внешнего ключа. Для других серверов баз данных правила могут быть другими.
Хорошо ... У меня разные пространства имен для каждой таблицы в Oracle, поэтому мне не нужна ссылка на себя.
Кажется, это обычное использование, но что делать людям, когда есть два внешних ключа, указывающих на одну и ту же таблицу. то есть таблица message имеет from_user_id и to_user_id, оба из них станут fk_message_user. Мне кажется, что по этой причине лучше использовать fk_tablename_columnname (fk_message_from_user_id в моем примере), а затем попытаться не указывать имена столбцов в целевой таблице (т.е. to_user_id явно относится к пользовательской таблице)
что, если в обеих таблицах есть символы подчеркивания, например. user_role и user_addresses? fk_user_addresses_user_role разве не сбивает с толку?
@govi Да, это сбивает с толку (мне пришлось сделать это для Oracle). Но для SQL Server паскаль предпочтительнее подчеркивания. Обычно я просто добавляю суффикс к имени столбца в конец - например, FK_UserAddresses_UserRole_ToUserID и FK_UserAddresses_UserRole_FromUserID.
@GregBeech Кроме того, вы можете добавить к этим именам числовой суффикс, если существует возможность множественных связей между двумя таблицами. Например, пользователь может «контролировать» несколько задач. В таких ситуациях вы можете назвать два внешних ключа FK_task_user_1, FK_task_user_2. Также вы можете использовать два символа подчеркивания в качестве разделителя (в случае таблиц с подчеркиванием в их именах), чтобы улучшить читаемость, как предлагает в один прекрасный день, когда.
Я использую два символа подчеркивания в качестве разделителя, т.е.
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))
...
Это абсолютно лучший ответ.
Я только что создал Derby DB с очень конкретным соглашением об именах, и этот здесь наиболее читаемый и отслеживаемый. Спасибо
Я предполагаю, что дело в использовании только имен таблиц ... два внешних ключа, указывающих на одну и ту же целевую таблицу ... вот почему я мог бы быть склонен включать имена полей ... без сомнения, сложная тема.
Основываясь на приведенных здесь ответах и комментариях, соглашение об именах, которое включает в себя таблицу 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, которое предлагает в своем ответе для таблиц, у которых есть подчеркивание в имени. Я лично использую подчеркивание только в таблицах перекрестных ссылок.
Если вы не часто ссылаетесь на свои FK и используете MySQL (и InnoDB), вы можете просто позволить MySQL назвать FK за вас.
Позже вы можете найдите нужное имя FK, выполнив запрос.
Я могу только объяснить свое голосование против. Практически каждая система баз данных позволяет системе называть ограничения. Можете ли вы представить себе, как вернуться назад и попытаться быстро выяснить во время производственной проблемы даже с базой данных из 100 таблиц, пытаясь расшифровать, к какой связи относится FK__123ee456ff? Это просто и просто УЖАСНАЯ практика. Когда вы построите индекс на этом FK, что тогда? система называет это тоже? Итак, когда индекс IX_007e373f5963 фрагментирован на 98%, как вы узнаете, где искать, чтобы понять, почему? Этого просто не должно быть.
Мой обычный подход
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
Вероятно, это перебор, но у меня это работает. Это очень помогает мне, особенно когда я имею дело с VLDB. Я использую следующее:
CONSTRAINT [FK_ChildTableName_ChildColName_ParentTableName_PrimaryKeyColName]
Конечно, если по какой-то причине вы не ссылаетесь на первичный ключ, вы должны ссылаться на столбец, содержащийся в ограничении уникальности, в этом случае:
CONSTRAINT [FK_ChildTableName_ChildColumnName_ParentTableName_ColumnInUniqueConstaintName]
Это может быть долго, да. Помогло ли это сделать информацию понятной для отчетов, или помогло мне быстро понять, что потенциальная проблема возникает во время оповещения о продукте. 100% хотели бы узнать мнение людей об этом соглашении об именах.
Попробуйте использовать UUID версии 4 в верхнем регистре с заменой первого октета на FK и '_' (подчеркивание) вместо '-' (тире).
Например.
FK_4VPO_K4S2_A6M1_RQLEYLT1VQYVFK_1786_45A6_A17C_F158C0FB343EFK_45A5_4CFA_84B0_E18906927B53Обоснование заключается в следующем
Эти загадочные идентификаторы - это то, от чего я изначально пытался уйти ... Я знаю, что MSSQL по умолчанию использует sourcetable_targettable_uid или что-то в этом роде ... хотя имена ограничений используются не часто, я думаю, что идея состоит в том, чтобы иметь человеческий -читаемая схема именования для соответствия версии, но также чтобы не выполнять дополнительный шаг для получения имени ограничения. По крайней мере, я так это вижу.
Примечание для читателей: многие из перечисленных ниже передовых практик не работают в Oracle из-за ограничения имени в 30 символов. Имя таблицы или столбца уже может содержать около 30 символов, поэтому соглашение, объединяющее их в одно имя, требует стандарта усечения или других уловок.