这是我提出的问题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上)吗?如果不允许,是否有人对如何解决它有任何建议?
答案 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