完整性約束 是資料庫防止髒資料、保證語義正確的最後防線。SQL 標準定義四大類:實體完整性、參考完整性、域完整性、使用者自訂完整性。本文逐一拆解定義、實作語法與實務場景。
規定:主鍵欄位 不得為 NULL,且值 唯一。確保每個實體可被精確區分。
PRIMARY KEY (col) — 隱含 NOT NULL + UNIQUEUNIQUE (col) — 允許單一 NULL (SQL Server)IDENTITY / SEQUENCE — 自動產生唯一值CREATE TABLE Student (
StudentID INT PRIMARY KEY, -- 實體完整性:非空、唯一
Name NVARCHAR(50) NOT NULL
);
複合主鍵 PRIMARY KEY (StudentID, CourseID) 時,兩欄皆不可為 NULL。
規定:外鍵 (FK) 值必須**匹配**被參考表的主鍵 (PK) 值,或為 NULL (若允許)。防止「懸空參考」。
| 術語 | 說明 |
|---|---|
| 被參考表 (Referenced Table) | 擁有主鍵的父表 (如 Class) |
| 參考表 (Referencing Table) | 擁有外鍵的子表 (如 Student) |
| 外鍵 (Foreign Key) | 子表中對應父表主鍵的欄位 (如 ClassID) |
| 動作 | 行為 | 適用場景 |
|---|---|---|
NO ACTION (預設) | 拒絕父表刪除/更新,拋錯 | 嚴格業務,不可級聯 |
CASCADE | 級聯刪除/更新子表對應列 | 訂單-明細、主從強綁定 |
SET NULL | 子表 FK 設為 NULL (需 FK 允許 NULL) | 員工-部門,員工保留但解除歸屬 |
SET DEFAULT | 子表 FK 設為預設值 | 特定業務預設歸屬 |
CREATE TABLE Class (
ClassID INT PRIMARY KEY,
ClassName NVARCHAR(50)
);
CREATE TABLE Student (
StudentID INT PRIMARY KEY,
Name NVARCHAR(50),
ClassID INT,
CONSTRAINT FK_Student_Class FOREIGN KEY (ClassID)
REFERENCES Class(ClassID)
ON DELETE SET NULL -- 刪除班級時,學生班級設為 NULL
ON UPDATE CASCADE -- 班級 ID 變更時,學生自動同步
);
規定:限制欄位的**資料型別、格式、取值範圍、是否允許 NULL**。
INT, DECIMAL(10,2), DATE, NVARCHAR(100) 等CHECK (Age >= 0 AND Age <= 150)DEFAULT (GETDATE())、DEFAULT (0)定義:針對特定應用的**跨表、跨欄、複雜條件**約束,超越上述三類標準機制。
CHECK (EndDate >= StartDate)CREATE TRIGGER trg_CheckInventory ON SalesOrder
AFTER INSERT AS
BEGIN
IF EXISTS (SELECT 1 FROM inserted i JOIN Product p ON i.ProductID = p.ProductID
WHERE i.Qty > p.StockQty)
THROW 50001, '庫存不足', 1;
END;
| 類型 | 保護對象 | 核心機制 | 典型場景 |
|---|---|---|---|
| 實體完整性 | 列 (Tuple) | PK, UNIQUE, IDENTITY | 唯一識別學生、訂單、商品 |
| 參考完整性 | 表與表關聯 | FK, ON DELETE/UPDATE | 學生-班級、訂單-客戶、明細-主單 |
| 域完整性 | 欄位值 | 型別, CHECK, DEFAULT, NOT NULL | 年齡 0-150、薪資 > 0、郵件格式 |
| 使用者自訂 | 業務規則 | 觸發器, CHECK, 應用層 | 庫存扣減、信用額度、複雜狀態機 |
PK_Table, FK_Child_Parent, CK_Table_Rule 利於維護四大完整性層層設防,讓資料庫成為「不說謊的真相來源」,而非髒資料的垃圾場。