方法一:ALTER TABLE 事後新增 (適用既有表)
ALTER TABLE TableName
ADD PRIMARY KEY (Column1, Column2);
- 簡潔、單一陳述式
- 預設建立**叢集索引** (若表無叢集索引)
- 自動檢查現有資料唯一性與非空性
方法二:CREATE TABLE 時顯式定義約束 (可控索引類型、命名、填充因子)
CREATE TABLE TableName (
Column1 INT NOT NULL,
Column2 NVARCHAR(13) NOT NULL,
Column3 ...,
ColumnN ...
);
GO
ALTER TABLE TableName WITH NOCHECK
ADD CONSTRAINT PK_TableName PRIMARY KEY NONCLUSTERED (
Column1,
Column2
);
GO
關鍵差異對照
| 特性 | 方法一 | 方法二 |
| 索引類型 | CLUSTERED (預設) | 可指定 NONCLUSTERED |
| 約束名稱 | 系統自動產生 | 自訂 (PK_TableName) |
| 填充因子 | 預設 (0/100) | 可加 WITH (FILLFACTOR=80) |
| 檢查既有資料 | CHECK (預設) | WITH NOCHECK 可跳過 (謹慎使用) |
| 適用場景 | 快速建立、既有表 | 新建表、需精細控制索引屬性 |
最佳實踐建議
- **主鍵欄位務必 NOT NULL** (定義時即指定)
- **命名規範**:
PK__ 利於辨識與腳本管理
- **叢集 vs 非叢集**:
- 窄、遞增、常用範圍查詢 → CLUSTERED
- 寬、非遞增、GUID、僅點查 → NONCLUSTERED + 另建叢集索引
- 複合主鍵欄位順序影響索引搜尋效率:
WHERE Col1 = ? AND Col2 = ? → (Col1, Col2) 最佳
- 避免在大表使用
WITH NOCHECK 跳過驗證,除非確定資料乾淨且需極速部署
驗證腳本
-- 查看主鍵資訊
SELECT
OBJECT_SCHEMA_NAME(parent_object_id) AS SchemaName,
OBJECT_NAME(parent_object_id) AS TableName,
name AS PK_Name,
type_desc AS IndexType,
is_unique
FROM sys.key_constraints
WHERE type = 'PK';
-- 查看索引欄位順序
SELECT
ic.index_column_id AS KeyOrder,
c.name AS ColumnName
FROM sys.index_columns ic
JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id
WHERE ic.object_id = OBJECT_ID('TableName') AND ic.index_id = 1; -- 1 = 叢集/主鍵
複合主鍵是實現多欄位唯一性約束的標準手段,選擇適當的建立方式與索引類型,能兼顧資料完整性與查詢效能。
- 上一篇文章: SQL CASE 運算式、子查詢與 JOIN 連接查詢綜合實戰指南
- 下一篇文章: SQL Server 表資料逐列處理:表變量 WHILE 迴圈 vs 游標 CURSOR 效能對比
Copyright ©
程式碼之家 All Rights Reserved