創建主鍵和外鍵時,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) );
範例 2(使用關鍵字):
CREATE TABLE Persons ( ID int NOT NULL, LastName varchar(255) NOT NULL, FirstName varchar(255), Age int, CONSTRAINT PK_Person PRIMARY KEY (ID) );
除了分配一個指定的約束名稱之外,DBMS 對這兩個範例的看法是否不同?我特別考慮 SQL Server、Oracle、MySQL 和 PostgreSQL。
對於 SQL Server,Microsoft 文件非常清楚地說明了這一點(粗體是我的格式):
CONSTRAINT
是一個可選關鍵字,指示 PRIMARY KEY、NOT NULL、UNIQUE、FOREIGN KEY 或 CHECK 約束定義的開始。
因此,您無需
CONSTRAINT xxx
在CREATE 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
SELECT
上面語句的結果:+----------------+--------------------------------+ | 姓名 | 姓名 | +----------------+--------------------------------+ | 約束測試 | PK__Constrai__471ED41490593601 | +----------------+--------------------------------+
這導致了命名所有約束的普遍接受的最佳實踐,如:
CREATE TABLE dbo.ConstraintTest ( ConstraintTest_ID int NOT NULL CONSTRAINT PK_ConstraintTest PRIMARY KEY CLUSTERED ) ON [PRIMARY];
與往常一樣,這裡的“It Depends™”時刻是針對臨時表的;我們幾乎從不指定應用於臨時表的約束的名稱,因為我們希望它們是唯一的,並且允許 SQL Server 命名它們以確保它們實際上是唯一的。如果您確實指定了約束名稱,那麼在任何給定時間只能存在該臨時表的一個副本;嘗試創建多個臨時表副本將導致錯誤:
消息 2714,級別 16,狀態 5,第 19 行
數據庫中已經有一個名為“PK_ConstraintTest”的對象。
消息 1750,級別 16,狀態 0,第 19 行
無法創建約束。請參閱以前的錯誤。
您可以輕鬆地將
UNIQUE
約束添加到沒有名稱的現有列;如:ALTER TABLE dbo.Blah ADD UNIQUE (SomeColumn);
在您添加到問題的範例中,唯一的區別是您沒有指定約束名稱,從而允許 SQL Server 為約束生成名稱。除了約束的名稱之外,這兩個表之間沒有區別。