資料庫邏輯設計是一個廣泛且深度的議題。本文專注於在 MS SQL Server 開發應用中,資料表主鍵設計常遇到的問題與解決方案。透過實務案例分析,探討如何從傳統的業務複合主鍵轉向代理鍵設計,以提升系統效能、簡化開發複雜度並解決分頁難題。
以銷售系統為例,通常包含主表(銷售單)與明細表(商品明細)。主表以單據號為主鍵,明細表則將單據號與商品編碼組成聯合主鍵。當業務延伸至第三層(如不同價格策略),主鍵需包含單據號、商品號與價格類型,形成三層級的複合主鍵。
為解決上述問題,建議在存在主從關係的資料表中,額外新增一個非業務數值型欄位作為主鍵(代理鍵)。此欄位與業務邏輯無關,僅作為唯一識別碼。幾乎所有資料表皆可採用此設計模式。
雖然 SQL Server 的 IDENTITY 屬性可自動生成唯一值,但存在顯著限制:
建立序列管理表 T_DB_SEQ,包含序列名稱、擁有者、當前值、最小/最大值、步長、循環標記等欄位。透過三個核心函數實現序列功能:
F_create_SEQ(序列名):建立序列記錄F_GET_NEXT_SEQ_VAL(序列名):取得下一個值,保證並發一致性F_GET_SEQ_CUR_VAL(序列名):取得當前值輔助函數包含設定值、刪除序列、判斷存在性等。主從表關聯時,子表使用自身序列值為主鍵,父表序列值為外鍵。
改用代理鍵後,原業務主鍵(如使用者登入帳號)失去 PRIMARY KEY 約束。解決方式有二:
代理鍵特性:無重複值、極少更新。SQL Server 單表僅能有一個叢集索引,這寶貴資源應留給高頻範圍查詢、排序分組的業務欄位。因此代理鍵主鍵建議使用 NONCLUSTERED 索引。
B/S 架構下,大量資料分頁是效能關鍵。傳統前端分頁(全撈再切頁)在資料量大時會導致逾時。採用代理鍵設計配合儲存程序,在資料庫端完成分頁:
此方式大幅降低網路傳輸量與 Web 伺服器壓力,是大型系統分頁的標準解法。