資料庫架構(Schema)是對象容器與命名空間,完整性約束是關係模型的靈魂。本文詳細講解兩部分式命名規範,並逐一實戰驗證主鍵、唯一、外鍵、檢查、預設五大約束的行為細節與陷阱。
Cnblogs.Blogs)。dbo。CREATE TABLE Blogs (BlogId INT NOT NULL, BlogName VARCHAR(MAX) NOT NULL) ALTER TABLE dbo.Blogs ADD CONSTRAINT pk_constraint_blogId PRIMARY KEY(BlogId)

ALTER TABLE dbo.Blogs ADD CONSTRAINT uq_constraint_blogname UNIQUE(BlogName)

⚠️ 大字串類型限制: VARCHAR(MAX)/NVARCHAR(MAX)/TEXT/NTEXT 無法直接建立唯一約束(SQL 2008R2 可,2012+ 不可)。
| 特性 | 主鍵約束 | 唯一約束 |
|---|---|---|
| 表中數量 | 僅 1 個 | 可多個 |
| 允許 NULL | 完全禁止 | 允許單一 NULL(多 NULL 視為重複會報錯) |
| 預設索引類型 | 聚集索引 | 非聚集索引 |
| 語意 | 實體識別(行唯一) | 屬性唯一(列唯一) |
ALTER TABLE dbo.Blogs ADD CONSTRAINT uq_constraint_blogId UNIQUE(BlogId) -- 成功

✅ 同列可同時擁有主鍵與唯一約束(雖無實際意義)。
CREATE TABLE test (Id INT NOT NULL, NAME VARCHAR(MAX) NOT NULL) ALTER TABLE test ADD CONSTRAINT UNQ UNIQUE(Id) INSERT INTO TEST VALUES(NULL,'B') -- 失敗:Id 定義為 NOT NULL

結論:唯一約束允許 NULL,但前提是列定義允許 NULL。
CREATE TABLE test (Id INT NOT NULL PRIMARY KEY, Code INT) CREATE UNIQUE INDEX uq_ix ON dbo.test(Code) -- 唯一索引 ALTER TABLE test ADD CONSTRAINT uq_nonclster_ix UNIQUE(Code) -- 唯一約束

WHERE Code IS NOT NULL 建立篩選唯一索引;唯一約束不支援。CREATE UNIQUE NONCLUSTERED INDEX uq_code_filter ON test(Code) WHERE Code IS NOT NULL -- 成功

CREATE TABLE [dbo].[Department] ([DepartmentID] INT NOT NULL IDENTITY, [DepartmentName] VARCHAR(50)) CREATE TABLE [dbo].[Employee] ([EmployeeID] INT NOT NULL IDENTITY, [FirstName] VARCHAR(50), [LastName] VARCHAR(50), [DepartmentID] INT) -- 關鍵:被參考列必須有主鍵或唯一約束/索引 ALTER TABLE [dbo].[Department] ADD CONSTRAINT [PK_Department] PRIMARY KEY ([DepartmentID]) ALTER TABLE [dbo].[Employee] ADD CONSTRAINT [FK_Employee_Department] FOREIGN KEY ([DepartmentID]) REFERENCES [dbo].[Department] ([DepartmentID])

❌ 無主鍵時建 FK 失敗:被參考表無匹配主鍵或候選鍵。
✅ 解決:被參考列加主鍵,或加唯一索引/約束。
ALTER TABLE dbo.Employees ADD CONSTRAINT CHK_Employees_salary CHECK(salary > 0.00)
CHECK (end_date >= start_date)。ALTER TABLE dbo.Employees ADD CONSTRAINT DFT_Employees_updateTime DEFAULT(GETDATE()) FOR UpdateTime
NEWID()、NEWSEQUENTIALID() 等函數。