外键命名方案

nic*_*ckf 139 database foreign-keys naming-conventions

我刚刚开始使用外键第一次使用外键,我想知道是否有一个标准的命名方案可用于它们?

鉴于这些表格:

task (id, userid, title)
note (id, taskid, userid, note);
user (id, name)
Run Code Online (Sandbox Code Playgroud)

任务具有Notes,任务由用户拥有,用户拥有Notes.

在这种情况下如何命名三个外键?或者,它甚至是否重要

更新:这个问题是关于外键名称,而不是字段名称!

Gre*_*ech 164

SQL Server中的标准约定是:

FK_ForeignKeyTable_PrimaryKeyTable
Run Code Online (Sandbox Code Playgroud)

因此,例如,笔记和任务之间的关键是:

FK_note_task
Run Code Online (Sandbox Code Playgroud)

任务和用户之间的关键是:

FK_task_user
Run Code Online (Sandbox Code Playgroud)

这使您可以"一目了然"查看密钥中涉及哪些表,因此可以轻松查看特定的(指定的第一个)依赖于哪些表(第二个名称).在这种情况下,完整的密钥集将是:

FK_task_user
FK_note_task
FK_note_user
Run Code Online (Sandbox Code Playgroud)

因此,您可以看到任务取决于用户,而笔记取决于任务和用户.

  • 这似乎是常用的,但是当有两个外键指向同一个表时,人们会怎么做.即`message`表有一个`from_user_id`和`to_user_id`这两个都会成为`fk_message_user`.在我看来,更好的方法是使用`fk_tablename_columnname`(在我的例子中为fk_message_from_user_id),然后尝试保持列名清楚目标表(即to_user_id显然是指用户表) (25认同)
  • 您在密钥中包含当前表名称以使其保持不同.FK名称位于SQL Server的全局命名空间中,因此您不能将两个名为FK_PrimaryKeyTable的FK附加到两个不同的外键表.其他数据库服务器的规则可能不同. (4认同)

one*_*hen 36

我使用两个下划线字符作为分隔符即

fk__ForeignKeyTable__PrimaryKeyTable 
Run Code Online (Sandbox Code Playgroud)

这是因为表名偶尔会包含下划线字符.这遵循约束的命名约定,因为数据元素的名称通常包含下划线字符,例如

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

  • 这绝对是最好的答案. (3认同)

Evi*_*ach 16

怎么样FK_TABLENAME_COLUMNNAME

ķ EEP 牛逼小号 imple 小号 tupid当过可能的.

  • 因为当你拥有一个包含大量密钥和表的巨大数据库并且在软件的模式更新期间出现错误时,很难找到甚至定义外键的位置,而无需搜索数据库创建脚本. (18认同)
  • @JohnC 如果 FK 列名在列名中有另一个表名,那么这不是很容易分辨吗?它会告诉您两个表及其定义的列名。例如:`FK_Animals_OwnerID` - 动物和所有者表,在 OwnerID 列上定义 (3认同)

Ste*_*yer 9

我通常只留下我的PK命名id,然后在其他表中命名FK时连接我的表名和键列名.我从不打扰骆驼套管,因为有些数据库会丢弃区分大小写,并且无论如何都只返回所有大写或小写的名称.在任何情况下,这是我的表格版本的样子:

task (id, userid, title);
note (id, taskid, userid, note);
user (id, name);
Run Code Online (Sandbox Code Playgroud)

请注意,我还以单数形式命名我的表,因为一行代表我持久存在的对象之一.其中许多约定都是个人偏好.我建议选择一个约会并且总是使用它比接受别人的约定更重要.


bvj*_*bvj 9

Microsoft关于SQL Server的说明:

FOREIGN KEY约束不必仅链接到另一个表中的PRIMARY KEY约束; 它也可以定义为引用另一个表中UNIQUE约束的列.

所以,我将使用描述依赖性的术语而不是传统的主要/外国关系术语.

当通过依赖(子)表中类似命名的列引用独立(父)表的PRIMARY KEY时,我省略了列名:

FK_ChildTable_ParentTable
Run Code Online (Sandbox Code Playgroud)

引用其他列时,或者两个表之间的列名称不同,或者只是显式:

FK_ChildTable_childColumn_ParentTable_parentColumn
Run Code Online (Sandbox Code Playgroud)

  • +1我发现,尽管很冗长,但您提供的最后一个示例是最不令人困惑且最直接的。我什至会使用双下划线,就像 @onedaywhen 在他的答案中建议的那样,对于名称中有下划线的表。我个人只在交叉引用表中使用下划线。 (2认同)

SSI*_*Off 5

这可能是过度杀伤,但它对我有用。特别是在处理 VLDB 时,它对我有很大帮助。我使用以下内容:

CONSTRAINT [FK_ChildTableName_ChildColName_ParentTableName_PrimaryKeyColName]
Run Code Online (Sandbox Code Playgroud)

当然,如果由于某种原因您没有引用主键,您必须引用包含在唯一约束中的列,在这种情况下:

CONSTRAINT [FK_ChildTableName_ChildColumnName_ParentTableName_ColumnInUniqueConstaintName]
Run Code Online (Sandbox Code Playgroud)

可以长吗,可以。它是否有助于保持报告的信息清晰,或者让我快速了解潜在问题是在 prod-alert 期间 100% 想知道人们对这个命名约定的想法。