一、基本定義
- 主鍵:唯一識別資料列的欄位或欄位組合(如學號、身分證字號),不可為 NULL、不可重複,一張表僅能有一個。
- 外鍵:建立與另一張表主鍵的關聯(如訂單表的
CustomerID 參考客戶表 ID),可重複、可為 NULL,一張表可有多個。
二、主鍵 vs 外鍵 vs 索引
| 特性 | 主鍵 | 外鍵 | 唯一索引 |
| 目的 | 資料完整性、唯一識別 | 參考完整性、關聯 | 查詢效能、唯一性 |
| NULL | 不允許 | 允許 | 允許一個 |
| 重複 | 不允許 | 允許 | 不允許 |
| 數量 | 1 個 | 多個 | 多個 |
| 預設索引 | 叢集索引 | 無(需手動建立) | 非叢集索引 |
三、叢集 vs 非叢集索引
- 叢集索引:資料頁即為索引葉層,物理順序 = 邏輯順序,必為唯一(內部加唯一識別碼)。
- 非叢集索引:葉層儲存索引鍵 + 書籤(RID 或叢集鍵),指向資料頁。
四、主鍵設計五大原則
- 無業務含義:使用 Surrogate Key(代理鍵),避免業務變更導致 PK 更新。
- 單一欄位:提升 JOIN/篩選效能;複合鍵會傳遞至子表造成鍵膨脹。
- 永不更新:PK 唯一識別用途,無更新理由。
- 無動態資料:不含時間戳、建立日期等會變動欄位。
- 電腦自動產生:IDENTITY、SEQUENCE、UUID,避免人為干預。
五、主鍵選型策略比較
| 策略 | 優點 | 缺點 | 適用場景 |
| IDENTITY (INT/BIGINT) | 簡單、效能最佳、儲存小 | 合併資料庫易衝突、離線/分散式難預分配 | 單一資料庫、高寫入 |
| 手動號碼表 | 可控制號段、跨庫不衝突 | 增加 Round-trip、並發複雜 | 跨資料庫合併、需預分配 |
| UNIQUEIDENTIFIER (GUID) | 全域唯一、離線產生、無衝突 | 16 bytes、索引碎片嚴重、效能差 | 分散式、合併複寫 |
| COMB (GUID + 時間) | 保留唯一性、有序性降低碎片 | 仍較 INT 慢、實作複雜 | 需 GUID 又重視索引效能 |
六、COMB 實作
DECLARE @aGuid UNIQUEIDENTIFIER;
SET @aGuid = CAST(CAST(NEWID() AS BINARY(10)) + CAST(GETDATE() AS BINARY(6)) AS UNIQUEIDENTIFIER);
SELECT @aGuid; -- 後 6 bytes 為時間,索引較有序
結語
主鍵/外鍵設計是資料庫物理模型的基石,上線後極難變更。遵循「無意義、單欄、不更新、自動產生」原則,配合業務選型(INT IDENTITY 為首選),可兼顧效能、擴充性與維護性。