外键命名方案

时间:2008-10-13 23:59:32

标签: database naming-conventions foreign-keys

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

鉴于这些表格:

task (id, userid, title)
note (id, taskid, userid, note);
user (id, name)

如果任务包含Notes,则任务由用户拥有,而用户则为Notes。

在这种情况下如何命名三个外键?或者,甚至可以解决这个问题

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

10 个答案:

答案 0 :(得分:157)

SQL Server中的标准约定是:

FK_ForeignKeyTable_PrimaryKeyTable

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

FK_note_task

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

FK_task_user

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

FK_task_user
FK_note_task
FK_note_user

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

答案 1 :(得分:35)

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

fk__ForeignKeyTable__PrimaryKeyTable 

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

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))
        ...

答案 2 :(得分:14)

FK_TABLENAME_COLUMNNAME怎么样?

K eep t S 实施 S tupid。

答案 3 :(得分:9)

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

task (id, userid, title);
note (id, taskid, userid, note);
user (id, name);

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

答案 4 :(得分:7)

Microsoft关于SQL Server的说明:

  

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

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

当通过 dependent(child)表中类似命名的列引用独立(父)表的PRIMARY KEY时,我省略了列名(一个或多个):

FK_ChildTable_ParentTable

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

FK_ChildTable_childColumn_ParentTable_parentColumn

答案 5 :(得分:1)

我通常的做法是

FK_ColumnNameOfForeignKey_TableNameOfReference_ColumnNameOfReference

或其他方面

FK_ChildColumnName_ParentTableName_ParentColumnName

这样我可以命名两个引用同一个表的外键,例如来自history_info table表的column actionBy and actionTo users_info

就像

FK_actionBy_usersInfo_name - For actionBy
FK_actionTo_usersInfo_name - For actionTo

请注意:

我没有包含子表名,因为这对我来说似乎是常识,我在孩子的桌子上,所以我可以很容易地假设孩子的表名。 它的总字符是26,非常适合查尔斯·伯恩斯在评论here

上所述的oracle 的30个字符限制
  

读者注意:下面列出的许多最佳实践都不起作用   因为它的30个字符名称限制在Oracle中。表名或   列名可能已经接近30个字符,因此是一个约定   将两者合并为一个名称需要截断标准或   其他技巧。 - 查尔斯伯恩斯

答案 6 :(得分:1)

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

CONSTRAINT [FK_ChildTableName_ChildColName_ParentTableName_PrimaryKeyColName]

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

CONSTRAINT [FK_ChildTableName_ChildColumnName_ParentTableName_ColumnInUniqueConstaintName]

可以很长,是的。它是否有助于保持信息清晰的报告,或者让我快速了解潜在的问题是在产品警报期间100%希望了解人们对此命名惯例的看法。

答案 7 :(得分:0)

根据此处的答案和评论,包含FK表,FK字段和PK表(FK_FKTbl_FKCol_PKTbl)的命名约定应避免FK约束名称冲突。

所以,对于这里的给定表:

fk_task_userid_user
fk_note_userid_user

因此,如果您添加一列来跟踪上次修改任务或注释的人...

fk_task_modifiedby_user
fk_note_modifiedby_user

答案 8 :(得分:0)

尝试使用大写的第4版UUID,第一个八位字节替换为FK和“_”(下划线),而不是“ - ”(短划线)。

E.g。

  • FK_4VPO_K4S2_A6M1_RQLEYLT1VQYV
  • FK_1786_45A6_A17C_F158C0FB343E
  • FK_45A5_4CFA_84B0_E18906927B53

基本原理如下

  • 严格生成算法=> 统一名称;
  • 密钥长度小于30个字符,这是Oracle中的命名长度限制(12c之前);
  • 如果您的实体名称发生更改,则不需要像基于实体名称的方法那样重命名您的FK (如果数据库支持表重命名运算符);
  • 很少使用外键约束的名称。例如。 DB工具通常显示约束适用的内容。不需要害怕神秘的外表,因为你可以避免使用它来“解密”。

答案 9 :(得分:-2)

如果您不经常使用MySQL(和InnoDB)引用您的FK,那么您可以让MySQL为您命名FK。

以后你可以find the FK name you need by running a query