约束命名的目的是什么?

79

给约束命名(unique,primary key,foreign key)的目的是什么?

假设我有一个使用自然键作为主键的表:

CREATE TABLE Order
(
    LoginName        VARCHAR(50)    NOT NULL,
    ProductName      VARCHAR(50)    NOT NULL,
    NumberOrdered    INT            NOT NULL,
    OrderDateTime    DATETIME       NOT NULL,
    PRIMARY KEY(LoginName, OrderDateTime)
);

给我的主键(如果有)命名会有什么好处?

例如:用以下方式替换:

    PRIMARY KEY(LoginName, OrderDateTime)

使用:

    CONSTRAINT Order_PK PRIMARY KEY(LoginName, OrderDateTime)

如果我的数据模型不是最好的,很抱歉,我是新手!


1
也许可以使用名称以后引用约束条件,例如当您想要删除或编辑它时? - Aziz
9个回答

148

以下是一些非常基本的原因:

(1) 如果一个查询(insert,update,delete)违反了约束条件,SQL 将生成一个包含约束名称的错误消息。如果约束名称清晰且易于理解,那么错误消息将更容易被理解;如果约束名称是随机的 GUID 命名,则不太清晰。特别是对于最终用户来说,他们可能会打电话给你并询问“FK__B__B_COL1__75435199”是什么意思。

(2) 如果以后需要修改约束条件(是的,这种情况确实会发生),如果你不知道它的名称,很难做到。(ALTER TABLE MyTable drop CONSTRAINT um...)。如果你从头开始创建多个数据库实例并使用系统生成的默认名称,则两个名称永远不会匹配。

(3) 如果支持你的代码的人(也就是 DBA)在星期日凌晨 3 点要处理无意义的 case(1) 或 case(2),那么他们很可能能够确定代码来自何处并做出相应反应。


回复:“特别是对于最终用户,他们可能会给你打电话并询问“FK__B__B_COL1__75435199”的含义。” - 我认为即使对于开发人员来说,看到类似“fk_payment_rental”这样的内容也更有用。 - Captain Man

13
为了在将来确定约束(例如您想在将来删除它),它应该具有唯一的名称。如果您没有为其指定名称,数据库引擎可能会为您分配一个奇怪的名称(例如包含随机内容以确保唯一性)。

这是否意味着仅为了方便人们更容易地识别约束而使用命名?换句话说,无论您是否命名约束,DBMS 都不会受到任何影响?您不能出于某种目的在代码中使用它吗?如果有不清楚的地方,请见谅。 - Andrew
1
这只是一个名称。名称并不会产生功能上的差异。当然,如果您将来想在代码中引用它,名称就很重要了。这就像在代码中使用变量名一样。 - Mehrdad Afshari
1
就像列名不会有任何影响一样。如果它们描述了它们所代表的内容(例如使用“ProductId”而不是“BJZ0_340”或“Fred”),那么它们将更加有用。 - Philip Kelley
在REFERENCES语句中,您可以使用约束名称吗? - Andrew
不。例如,您可以在“ALTER TABLE DROP CONSTRAINT [name]”中使用它。 - Mehrdad Afshari
如果您命名了约束,是否仍然可以使用系统生成的名称来指向该约束? - SiegeSailor

8

这将让数据库管理员感到满意,因此他们会将您的模式定义添加到生产数据库中。


哈哈...是的,我猜这是最重要的原因 :P - Andrew

3

当你的代码随机违反某些外键约束时,确定是哪个约束违反了可以节省调试时间。给它们命名可以极大地简化插入和更新的调试。


2

这有助于用户快速了解约束的作用,而不必查看实际约束,因为名称已经提供了所有所需信息。

因此,我可以知道它是主键、唯一键还是默认键,以及涉及的表和可能的列。


1
通过正确命名所有的约束,您可以快速将特定的约束与我们的数据模型相关联。这给我们带来了两个真正的优势:
  1. 我们可以快速识别和修复任何错误。
  2. 我们可以可靠地修改或删除约束。

0
通过为约束命名,您可以区分它们的违规情况。这不仅对管理员和开发人员有用,而且您的程序也可以使用约束名称。这比尝试解析错误消息要强大得多。通过使用约束名称,您的程序可以根据违反哪个约束来有所不同地做出反应。
约束名称还非常有用,可以在用户的语言中显示适当的错误消息,提到哪个字段导致了约束违规,而不仅仅是将数据库服务器的加密错误消息转发给用户。
请参见我的答案如何使用PostgreSQL和Java进行此操作

0
另一个命名约束的好处是,如果您在数据库架构上使用版本控制,则可以避免因为默认数据库命名(在我的情况下是SQL Server)而必须删除和重新创建约束时,导致提交的版本与工作副本之间存在差异。给约束指定一个明确的名称将避免将其标记为更改。

0

虽然 OP 的示例使用了永久表,但请记住,临时表上的命名约束的行为类似于永久表上的命名约束(即,如果没有将其命名为某个唯一名称,则不能有多个会话处理临时表的确切代码,否则会生成错误)。因为命名约束必须是唯一的,所以如果您绝对必须在临时表上命名约束,请尝试在其末尾使用某种随机 GUID(例如 SELECT NEWID())来确保它在会话之间具有唯一名称。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接