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

时间:2010-02-10 22:51:40

标签: mysql naming-conventions foreign-keys

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

4 个答案:

答案 0 :(得分:121)

在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。如果这不可行,我还会将引用的字段名称附加到外键名称。

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

答案 1 :(得分:27)

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

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

CREATE TABLE messages(
   id int,
   user_id    int
);
表中的“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 

请注意:

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

    fk_messages_user_user_id_users_id

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

答案 2 :(得分:7)

如果你发现自己经常在创建之后引用fk,那么一个选择就是保持简单,让MySQL为你做命名(如Daniel Vassallo mentions in the beginning of his answer)。

虽然你无法独特地猜测"使用此方法的约束名称 - 您可以通过运行查询轻松找到外键约束名称:

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。

答案 3 :(得分:1)

itemCollection.find({
    "$where" : function(){

        var searchKey = 'find-this';
        var searchValue = 'please find me';

        return searchInObj(obj);

        function searchInObj(obj){                            
          for(var k in obj){       
            if(typeof obj[k] == 'object' && obj[k] !== null){
              if(searchInObj(obj[k])){
                return true;
              }
            } else {
              if(k == searchKey && obj[k] == searchValue){
                return true;
              }
            }          
          }                         
          return false;
        }       
    }    
}
}).toArray((error,result) => { console.log(result.length}); 

原因是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 表名添加到外键名是多余的。