前五篇聚焦查詢 (DML),本文轉向資料定義語言 (DDL),系統講解 CREATE TABLE、CREATE INDEX、CONSTRAINT 完整語法、選項與命名慣例,奠定資料庫結構設計基礎。
CREATE TABLE table_name (
column_name data_type [ (precision [, scale]) ] [ NULL | NOT NULL ]
[ DEFAULT default_expr ]
[ IDENTITY (seed, increment) ]
[ CONSTRAINT constraint_name constraint_type ... ]
[ , ...n ]
[ , table_constraint ] [ , ...n ]
);
| 選項 | 說明 | 範例 |
|---|---|---|
| 資料類型 | INT, BIGINT, DECIMAL(p,s), VARCHAR(n), NVARCHAR(n), DATE, DATETIME2, BIT, UNIQUEIDENTIFIER... | Price DECIMAL(10,2) |
| NULL/NOT NULL | 預設 NULL;主鍵隱含 NOT NULL | Email NVARCHAR(100) NOT NULL |
| DEFAULT | 插入時未指定值自動填入 | CreatedAt DATETIME2 DEFAULT SYSUTCDATETIME() |
| IDENTITY | 自動遞增數值 (僅整數類型),一表一欄 | ID INT IDENTITY(1,1) |
| 欄位層級 CONSTRAINT | PK、UQ、CK、FK、DEFAULT 命名綁定單欄 | CONSTRAINT CK_Age CHECK (Age >= 0) |
-- 複合主鍵
CONSTRAINT PK_OrderDetail PRIMARY KEY (OrderID, LineNo)
-- 複合唯一
CONSTRAINT UQ_User_Email UNIQUE (Email)
-- 複合外鍵
CONSTRAINT FK_Order_Customer FOREIGN KEY (CustID) REFERENCES Customer(CustID)
ON DELETE NO ACTION ON UPDATE CASCADE
-- 條件約束
CONSTRAINT CK_Order_Total CHECK (TotalAmount >= 0)
CREATE TABLE Sales.OrderHeader (
OrderID INT IDENTITY(1,1) NOT NULL,
OrderNumber NVARCHAR(20) NOT NULL,
CustomerID INT NOT NULL,
OrderDate DATETIME2(3) NOT NULL DEFAULT SYSUTCDATETIME(),
Status TINYINT NOT NULL DEFAULT 1,
TotalAmount DECIMAL(12,2) NOT NULL DEFAULT 0 CHECK (TotalAmount >= 0),
Remark NVARCHAR(500) NULL,
RowVer ROWVERSION NOT NULL,
CONSTRAINT PK_OrderHeader PRIMARY KEY CLUSTERED (OrderID),
CONSTRAINT UQ_OrderNumber UNIQUE NONCLUSTERED (OrderNumber),
CONSTRAINT FK_Order_Customer FOREIGN KEY (CustomerID)
REFERENCES Customer(CustomerID) ON UPDATE CASCADE,
CONSTRAINT CK_Status CHECK (Status IN (1,2,3,4,9))
);
CREATE INDEX IX_OrderHeader_CustomerDate ON Sales.OrderHeader (CustomerID, OrderDate DESC);
CREATE [UNIQUE] [CLUSTERED | NONCLUSTERED] INDEX index_name
ON table_name (column [ASC | DESC] [ ,...n ] )
[ INCLUDE (column [ ,...n ]) ] -- 覆蓋索引關鍵
[ WHERE filter_predicate ] -- 篩選索引 (SQL 2008+)
[ WITH (
FILLFACTOR = 80, -- 預留空間減少分頁
ONLINE = ON, -- 企業版:線上建立不鎖表
DATA_COMPRESSION = PAGE -- 壓縮減少 I/O
) ];
WHERE Status = 1 只索引熱門資料,極大縮小索引體積-- 新增 (表已存在)
ALTER TABLE OrderHeader
ADD CONSTRAINT CK_OrderDate CHECK (OrderDate <= SYSUTCDATETIME());
-- 刪除
ALTER TABLE OrderHeader DROP CONSTRAINT CK_OrderDate;
-- 停用檢查 (大量匯入加速)
ALTER TABLE OrderHeader NOCHECK CONSTRAINT FK_Order_Customer;
-- 匯入完成後重新啟用並驗證現有資料
ALTER TABLE OrderHeader WITH CHECK CHECK CONSTRAINT FK_Order_Customer;
| 類型 | 前綴 | 格式範例 |
|---|---|---|
| Primary Key | PK_ | PK_OrderHeader |
| Foreign Key | FK_ | FK_OrderHeader_Customer |
| Unique | UQ_ | UQ_Customer_Email |
| Check | CK_ | CK_OrderHeader_TotalAmount_Positive |
| Default | DF_ | DF_OrderHeader_OrderDate |
| Index | IX_ / CX_ | IX_OrderHeader_CustomerDate |
NULL 或 DEFAULT,避免破壞既有 INSERTONLINE=ON、FILLFACTOR、分批次sp_help 'TableName'、sys.tables/columns/indexes/constraints 定期匯出資料字典結語:DDL 是資料庫的骨架。嚴謹的命名、約束、索引設計,能讓後續 DML 查詢自然高效,減少 90% 的效能調校成本。