MySQL FK的正确命名约定是什么?


Answers:


141

在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 2010年

11
我想做的是在引用表名称和引用表名称之间使用双下划线。这为您提供了按字母顺序排列的列表的双重优势,可以将表的所有FK保持在一起,同时在有多个单词表名称时帮助您避免名称冲突/混淆。我也忽略了名称的字段部分,因为它很琐碎(即单个int字段引用了另一个表的身份PK)。
乔尔·布朗

2
如果有多个外键怎么办?示例:member_id〜>链接到表成员,〜>链接到已edited_id编辑用户,也链接到表成员。我该如何命名?
TomSawyer

@TomSawyer:我将'pk_'添加到所有外键,然后添加引用的表(例如'members'),再使用用法/感觉(例如'editor'或'author')。所以我有一些类似“ pk_members_author”或“ pk_members_editor”的东西。
Nrgyzer '17

28

我的选择是不同的。我认为,表应该有一个id字段,而不是一个字段user_id,因为table只是被称为user,所以:

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

CREATE TABLE messages(
   id int,
   user_id    int
);

user_idmessages表是一个FK场,因此必须作出明确哪个ID是(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丹尼斯

9

如果您发现创建fk时并没有经常引用它,那么一种选择是保持简单,让MySQL为您命名(如Daniel Vassallo在回答开始时提到的)。

虽然您无法使用此方法唯一地“猜测”约束名称,但是您可以通过运行查询轻松找到外键约束名称:

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。


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什么?userrole具有许多关系,user_role并且该表包含所有外键。应该是fk_user_role_role吗?
—NguyễnĐứcTâm19年

@NguyễnĐứcTâmFK-user_role的角色
VANQuyết
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.