索引是 MySQL 效能優化的關鍵,但 KEY、PRIMARY KEY、UNIQUE KEY、INDEX 等術語常令人困惑。本文從邏輯層面與物理實作層面雙向剖析,釐清它們的定義、差異與適用場景。
CREATE TABLE wh_logrecord (
logrecord_id int(11) NOT NULL auto_increment,
user_name varchar(100) default NULL,
operation_time datetime default NULL,
logrecord_operation varchar(100) default NULL,
PRIMARY KEY (logrecord_id),
KEY wh_logrecord_user_name (user_name)
);
KEY wh_logrecord_user_name (user_name):這是一個**普通索引**(非外鍵),名稱為 wh_logrecord_user_name,作用於 user_name 欄位KEY 是索引的同義詞,外鍵必須顯式使用 FOREIGN KEY 關鍵字PRIMARY KEY:主鍵約束,隱含 NOT NULL + UNIQUE,一張表僅能有一個KEY forum (status, type, displayorder) -- 多欄位聯合索引 KEY tid (tid) -- 單欄位索引
查詢優化器使用規則:
WHERE status=1 AND type=2 AND displayorder=3 → 可用索引WHERE status=1 AND type=2 → 可用索引(最左前綴)WHERE type=2 AND displayorder=3 → 無法使用(未包含最左列)KEY 是邏輯層面概念,描述表與資料庫設計(如參考完整性、唯一性約束)
INDEX 是物理層面實作,用於加速查詢存取
| 維度 | KEY (鍵) | INDEX (索引) |
|---|---|---|
| 層級 | 邏輯/模型層 | 物理/實作層 |
| 目的 | 資料完整性、約束 | 查詢效能優化 |
| 類型 | PRIMARY KEY, FOREIGN KEY, UNIQUE KEY | BTREE, HASH, FULLTEXT, SPATIAL |
| 自動建立 | 定義 PRIMARY KEY 時自動建立 UNIQUE INDEX | 手動建立或隱含建立 |
PRIMARY KEY 都會自動建立對應的 UNIQUE INDEX| 特性 | PRIMARY KEY | UNIQUE KEY |
|---|---|---|
| NULL 允許 | 不允許(隱含 NOT NULL) | 允許(多個 NULL 視為不重複) |
| 數量限制 | 每表僅一個 | 可建立多個 |
| 隱含索引 | 自動建立 UNIQUE INDEX | 自動建立 UNIQUE INDEX |
| 外鍵參考 | 可被外鍵參考 | 可被外鍵參考 |
ALTER TABLE t ADD CONSTRAINT uk_t_1 UNIQUE (a,b); INSERT INTO t (a,b) VALUES (NULL,1); -- 不可重複 INSERT INTO t (a,b) VALUES (NULL,NULL); -- 可重複(全 NULL 不記錄於索引)
-- 單欄位
CREATE TABLE Persons (
Id_P int NOT NULL,
LastName varchar(255) NOT NULL,
UNIQUE (Id_P)
);
-- 多欄位 + 命名約束
CREATE TABLE Persons (
Id_P int NOT NULL,
LastName varchar(255) NOT NULL,
CONSTRAINT uc_PersonID UNIQUE (Id_P, LastName)
);
-- 單欄位 ALTER TABLE Persons ADD UNIQUE (Id_P); -- 多欄位 + 命名 ALTER TABLE Persons ADD CONSTRAINT uc_PersonID UNIQUE (Id_P, LastName);
-- MySQL 使用 DROP INDEX(因為唯一約束實作為 UNIQUE INDEX) ALTER TABLE Persons DROP INDEX uc_PersonID;
PRIMARY KEY,業務唯一性用 UNIQUE KEY,單純加速查詢用 INDEXpk_表名、uk_表名_欄位、idx_表名_欄位深入理解這四者差異,能幫助你設計出既符合業務語義又具備高效能的資料庫結構。