Каково правильное соглашение об именах для MySQL FK?

Ответы:

142

В MySQL нет необходимости давать символическое имя ограничениям внешнего ключа. Если имя не указано, InnoDB автоматически создает уникальное имя.

В любом случае, я использую следующее соглашение:

fk_[referencing table name]_[referenced table name]_[referencing field name]

Пример:

CREATE TABLE users(
    user_id    int,
    name       varchar(100)
);

CREATE TABLE messages(
    message_id int,
    user_id    int
);

ALTER TABLE messages ADD CONSTRAINT fk_messages_users_user_id 
    FOREIGN KEY (user_id) REFERENCES users(user_id);

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

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

Даниэль Вассалло
источник
13
Причина создания символического имени заключается в том, чтобы ссылаться, когда вы хотите / должны отказаться от ограничения. Oracle и SQL Server позволяют отключать определенные ограничения. Если у вас нет fk в имени, вы должны подтвердить, что ограничение является ограничением внешнего ключа ...
OMG Ponies,
11
Что мне нравится делать, так это использовать двойное подчеркивание между именем ссылающейся таблицы и именем указанной таблицы. Это дает вам двойное преимущество алфавитных списков, сохраняющих все FK таблицы вместе и в то же время помогая вам избежать конфликтов / путаницы имен при наличии нескольких имен таблиц слов. Я также опускаю полевую часть имени, когда она тривиальна (т.е. одно поле int ссылается на идентификатор PK другой таблицы).
Джоэл Браун
2
Что делать, если существует более одного внешнего ключа? Пример: member_id~> ссылка на элемент таблицы, edited_id~> внешний ключ для редактируемого пользователя, также ссылка на элемент таблицы. Как мне их назвать?
TomSawyer
@TomSawyer: я добавляю «pk_» ко всем внешним ключам, за которым следует указанная таблица (например, «члены»), за которой следует использование / смысл (например, «редактор» или «автор»). Итак, у меня есть что-то вроде pk_members_author или pk_members_editor.
Нргизер,
28

мой выбор другой. на мой взгляд, стол должен иметьid поле, а не user_idодно, потому что таблица просто вызывается user, поэтому:

CREATE TABLE users(
   id    int,
   name       varchar(100)
);

CREATE TABLE messages(
   id int,
   user_id    int
);

user_idв messagesтаблице есть поле fk, поэтому в нем должно быть ясно, какой идентификатор равен ( user_id).

полностью самоочевидное соглашение об именах, на мой взгляд, могло бы быть:

fk_[referencing table name]_[referencing field name]_[referenced table name]_[referenced field name]

i.e.: `fk_messages_user_id_users_id`

нота:

  • в некоторых случаях вы можете опустить второй элемент ([ссылающееся имя поля])
  • этот fk может быть уникальным, потому что, если messages_userтаблица существует, имя поля ссылки должно быть user_id(а не просто id), а имя fk должно быть:

    fk_messages_user_user_id_users_id

другими словами, соглашение об именовании внешнего ключа гарантирует, что вы будете иметь уникальные имена, если вы также используете соглашение об именовании «ссылающееся / указанное поле» (и вы, конечно, можете выбрать свое собственное).

Лоренцо
источник
4
Имена могут сохраняться в коде. В конце концов, вы найдете $idпеременную где-нибудь, не зная, к какой таблице она принадлежит. Чем старше ваша кодовая база и чем больше людей над ней работали, тем больше вероятность этого.
CJ Dennis
9

Если вы не часто ссылаетесь на fk после их создания, один из вариантов - сохранить простоту и позволить MySQL выполнять именование за вас (как упоминает Даниэль Вассалло в начале своего ответа ).

Хотя вы не сможете однозначно «угадать» имена ограничений с помощью этого метода, вы можете легко найти имя ограничения внешнего ключа, выполнив запрос:

use information_schema;
select TABLE_NAME,COLUMN_NAME,CONSTRAINT_NAME, REFERENCED_TABLE_NAME,REFERENCED_COLUMN_NAME from KEY_COLUMN_USAGE where REFERENCED_TABLE_SCHEMA = 'your_db_schema_name' ORDER BY TABLE_NAME;

Например, в результате запроса вы можете получить следующее:

+------------+-------------+-----------------+-----------------------+------------------------+
| TABLE_NAME | COLUMN_NAME | CONSTRAINT_NAME | REFERENCED_TABLE_NAME | REFERENCED_COLUMN_NAME |
+------------+-------------+-----------------+-----------------------+------------------------+
| note       | taskid      | note_ibfk_2     | task                  | id                     |
| note       | userid      | note_ibfk_1     | user                  | id                     |
| task       | userid      | task_ibfk_1     | user                  | id                     |
+------------+-------------+-----------------+-----------------------+------------------------+

Если этот дополнительный шаг не является для вас слишком сложным, то вы сможете легко найти нужный fk.

user12345
источник
1
fk-[referencing_table]-[referencing_field]

Причина в комбинации referencing_tableи referencing_fieldуникальна в базе данных. Таким образом упростите чтение имени внешнего ключа, например:

table `user`:
    id
    name
    role

table `article`:
    id
    content
    created_user_id /* --> user.id */
    reviewed_user_id /* --> user.id */

Итак, у нас есть два внешних ключа:

fk-article-created_user_id
fk-article-reviewed_user_id

Добавление userимени таблицы к имени внешнего ключа излишне.

Ван Куит
источник
Что, если имя базы данных user_role? userи roleимеют отношения многие-многие, и user_roleэто таблица, содержащая весь внешний ключ. Так должно быть fk_user_role_role?
Nguyễn
@ NguyễnĐứcTâm fk-user_role-role
Ван Куит