创建主键和外键时 CONSTRAINT 关键字是可选的吗?

koj*_*ow7 3 constraint

创建新表时,示例有时会显示用CONSTRAINT关键字定义的主键和外键,有时则不显示CONSTRAINT关键字。是使用CONSTRAINT关键字为约束命名的唯一原因吗?或者您是否有其他原因选择使用或不使用此关键字?

示例 1(不带关键字):

CREATE TABLE Persons (
    ID int NOT NULL,
    LastName varchar(255) NOT NULL,
    FirstName varchar(255),
    Age int,
    PRIMARY KEY (ID)
);
Run Code Online (Sandbox Code Playgroud)

示例 2(使用关键字):

CREATE TABLE Persons (
    ID int NOT NULL,
    LastName varchar(255) NOT NULL,
    FirstName varchar(255),
    Age int,
    CONSTRAINT PK_Person PRIMARY KEY (ID)
);
Run Code Online (Sandbox Code Playgroud)

除了分配指定的约束名称之外,DBMS 对这两个示例的看法是否不同?我特别在考虑 SQL Server、Oracle、MySQL 和 PostgreSQL。

Han*_*non 8

对于 SQL Server,Microsoft 文档非常清楚地说明了这一点(粗体是我的格式):

CONSTRAINT
是一个可选关键字,指示 PRIMARY KEY、NOT NULL、UNIQUE、FOREIGN KEY 或 CHECK 约束定义的开始。

因此,您无需CONSTRAINT xxxCREATE TABLE声明中指定。

但是请注意,如果您没有指定约束名称,如果您包含一个约束定义,SQL Server 将为您生成一个。此示例显示了如何创建PRIMARY KEY约束,但未对其进行命名。

CREATE TABLE dbo.ConstraintTest
(
    ConstraintTest_ID int NOT NULL
        PRIMARY KEY CLUSTERED
) ON [PRIMARY];

SELECT o_parent.name
    , o.name
FROM sys.key_constraints kc
    INNER JOIN sys.objects o ON kc.object_id = o.object_id
    INNER JOIN sys.objects o_parent on kc.parent_object_id = o_parent.object_id
WHERE o_parent.name = 'ConstraintTest';

DROP TABLE dbo.ConstraintTest
Run Code Online (Sandbox Code Playgroud)

SELECT上面语句的结果:

+----------------+-------------------------------- +
| 姓名 | 姓名 |
+----------------+-------------------------------- +
| 约束测试 | PK__Constrai__471ED41490593601 |
+----------------+-------------------------------- +

这导致了普遍接受的命名所有约束的最佳实践,如:

CREATE TABLE dbo.ConstraintTest
(
    ConstraintTest_ID int NOT NULL
        CONSTRAINT PK_ConstraintTest
        PRIMARY KEY CLUSTERED
) ON [PRIMARY];
Run Code Online (Sandbox Code Playgroud)

与往常一样,这里的“It Depends™”时刻是针对临时表的;我们几乎从不指定应用于临时表的约束的名称,因为我们希望它们是唯一的,并且允许 SQL Server 命名它们可以确保它们实际上是唯一的。如果您确实指定了约束名称,则在任何给定时间只能存在该临时表的一个副本;尝试创建多个临时表副本将导致错误:

消息 2714,级别 16,状态 5,第 19 行
数据库中已经有一个名为“PK_ConstraintTest”的对象。
消息 1750,级别 16,状态 0,第 19 行
无法创建约束。请参阅以前的错误。

您可以轻松地UNIQUE向没有名称的现有列添加约束;如:

ALTER TABLE dbo.Blah
ADD UNIQUE (SomeColumn);
Run Code Online (Sandbox Code Playgroud)

在您添加到问题的示例中,唯一的区别是您没有指定约束名称,从而允许 SQL Server 为约束生成名称。除了约束的名称外,两个表之间没有区别。