数据库中是否存在具有相同名称的约束?

时间:2009-09-09 05:18:48

标签: sql sql-server sql-server-2005 tsql constraints

这是我提出的问题here的后续问题。

数据库中的约束可以具有相同的名称吗?

说我有:

CREATE TABLE Employer
(
    EmployerCode    VARCHAR(20)    PRIMARY KEY,
    Address         VARCHAR(100)   NULL
)


CREATE TABLE Employee
(
    EmployeeID      INT            PRIMARY KEY,
    EmployerCode    VARCHAR(20)    NOT NULL,
    CONSTRAINT employer_code_fk FOREIGN KEY (EmployerCode) REFERENCES Employer
)


CREATE TABLE BankAccount
(
    BankAccountID   INT            PRIMARY KEY,
    EmployerCode    VARCHAR(20)    NOT NULL,
    Amount          MONEY          NOT NULL,
    CONSTRAINT employer_code_fk FOREIGN KEY (EmployerCode) REFERENCES Employer
)

这是允许的吗?它取决于DBMS(我在SQL Server 2005上)吗?如果不允许,是否有人对如何解决它有任何建议?

6 个答案:

答案 0 :(得分:50)

否 - 约束也是数据库对象,因此其名称必须是唯一的。

尝试添加例如

表示您的约束表格,这是唯一的。

CREATE TABLE BankAccount
(
    BankAccountID   INT            PRIMARY KEY,
    EmployerCode    VARCHAR(20)    NOT NULL,
    Amount          MONEY          NOT NULL,
    CONSTRAINT FK_BankAccount_Employer 
        FOREIGN KEY (EmployerCode) REFERENCES Employer
)

我们基本上使用“FK _”(子表)_(父表)来命名约束,并对这个命名约定非常满意。

来自MSDN的信息

该约束名称必须对于模式是唯一的(即,同一数据库中的两个不同模式都可以包含具有相同名称的约束)未明确记录。相反,您需要假设数据库对象的标识符在包含的模式中必须是唯一的,除非另有说明。因此约束名称为defined

  

是约束的名称。约束名称必须遵循标识符规则,但名称不能以数字符号(#)开头。如果未提供constraint_name,则会为约束分配系统生成的名称。

将此与index的名称进行比较:

  

是索引的名称。索引名称在表或视图中必须是唯一的,但在数据库中不必是唯一的。索引名称必须遵循标识符规则。

明确地缩小了标识符的范围。

答案 1 :(得分:22)

其他答案都很好,但我想我会在标题中添加问题的答案,即" 数据库中是否存在同名的约束?"

MS SQL Server的答案是肯定的 - 但只要约束在不同的模式中。约束名称必须在架构中唯一

答案 2 :(得分:8)

我总是感到困惑为什么约束名在数据库中必须是唯一的,因为它们似乎与表相关联。

然后我读到了SQL-99的ASSERTION约束,它类似于检查约束,但是除了任何单个表之外都存在。断言中声明的条件必须像任何其他约束一样得到满足,但断言可以引用多个表。

AFAIK没有SQL供应商实现ASSERTION约束。但这有助于解释为什么约束名称在数据库范围内。

答案 3 :(得分:2)

  

它是否依赖于DBMS(我在SQL Server 2005上)?

是的,显然它确实依赖于DBMS。

其他答案说这是不允许的,但我有一个MS SQL CE(“精简版”)数据库,其中我偶然在两个表中成功创建了两个具有相同约束名称的FK约束。

答案 4 :(得分:2)

这取决于DBMS。

例如在 PostgreSQL 上,答案是

  

因为PostgreSQL不要求约束名称是唯一的   在模式中(但只有每个表),有可能存在   指定约束名称的多个匹配项。

来源:https://www.postgresql.org/docs/current/static/sql-set-constraints.html

我看到外键约束名称在同一架构中的2个不同表上等于。

答案 5 :(得分:0)

好的做法是在开头创建指定表名的索引和约束名称。 有两种方法,在开头或结尾都有索引/约束类型),例如。

UQ_TableName_FieldName

TableName_FieldName_UQ

外键名称还应包含引用的表/字段的名称。

一个好的命名约定是以FullName_3LetterUniqueAlias的形式给出表名,例如。

Employers_EMR
Employees_EMP
BankAccounts_BNA
Banks_BNK

这使您有机会在查询中使用“预定义”别名,从而提高可读性,并且还可以更轻松地命名外键,例如:

EMPEMR_EmployerCode_FK
BNKEMR_EmployerCode_FK