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

Zom*_*ies 92 mysql foreign-keys naming-conventions

因为它们必须是唯一的,我应该在MySQL数据库中命名FK?

Dan*_*llo 132

在MySQL中,不需要为外键约束赋予符号名称.如果没有给出名称,InnoDB会自动创建一个唯一的名称.

无论如何,这是我使用的约定:

fk_[referencing table name]_[referenced table name]_[referencing field name]
Run Code Online (Sandbox Code Playgroud)

例:

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);
Run Code Online (Sandbox Code Playgroud)

我尝试在引用表和引用表中使用相同的字段名称,user_id如上例所示.如果这不可行,我还会将引用的字段名称附加到外键名称.

这个命名约定允许我仅通过查看表定义来"猜测"符号名称,此外它还保证唯一的名称.

  • 创建符号名称的原因是在需要/需要删除约束时进行引用.Oracle和SQL Server允许您禁用特定约束.如果名称中没有fk,则必须确认约束是外键约束... (13认同)
  • 我喜欢做的是在引用表名和引用的表名之间使用双下划线.这为您提供了按字母顺序列表的双重优势,将所有表格的FK保持在一起,同时在有多个单词表名称时帮助您避免名称冲突/混淆.当它很简单时,我也省略了名称的字段部分(即单个int字段引用另一个表的标识PK). (11认同)
  • 如果有超过1个外键怎么办?示例:`member_id`~>指向表成员的链接,`edited_id`~>已编辑用户的外键,也链接到表成员.我该如何命名? (2认同)
  • 如果名字太长怎么办? (2认同)

小智 28

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

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

CREATE TABLE messages(
   id int,
   user_id    int
);
Run Code Online (Sandbox Code Playgroud)

"messages"表中的"user_id"是一个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`
Run Code Online (Sandbox Code Playgroud)

注意:

  • 在某些情况下,您可以省略第二个元素([引用字段名称])
  • 这个fk可能是唯一的,因为如果存在"messages_user"表,引用字段名称应为"user_id"(而不仅仅是"id"),并且fk名称应为:

    fk_messages_user_user_id_users_id

换句话说,如果您还使用"引用/引用字段"命名约定(当然,您可以选择自己的命名约定),外键命名约定会确保您使用唯一名称.

  • 名称具有跨代码持久化的方式。最终,您会在某个地方找到一个`$ id`变量,而不知道它属于哪个表。您的代码库越老,使用它的人越多,则这种可能性就越大。 (3认同)

use*_*345 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;
Run Code Online (Sandbox Code Playgroud)

例如,您可能会从查询中收到以下内容:

+------------+-------------+-----------------+-----------------------+------------------------+
| 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                     |
+------------+-------------+-----------------+-----------------------+------------------------+
Run Code Online (Sandbox Code Playgroud)

如果这个额外的步骤对您来说不是太多,那么您应该能够轻松找到您正在寻找的fk.