主鍵 (PRIMARY KEY) 是關係型數據庫表的唯一標識符,具有三大核心特性:
-- MySQL / MariaDB (推薦:自增整數主鍵)
CREATE TABLE persons (
p_id INT NOT NULL AUTO_INCREMENT,
last_name VARCHAR(255) NOT NULL,
first_name VARCHAR(255),
address VARCHAR(255),
city VARCHAR(255),
PRIMARY KEY (p_id)
);
-- SQL Server / Oracle / PostgreSQL / SQLite (標準寫法)
CREATE TABLE persons (
p_id INT NOT NULL PRIMARY KEY,
last_name VARCHAR(255) NOT NULL,
first_name VARCHAR(255),
address VARCHAR(255),
city VARCHAR(255)
);
-- 通用帶約束名寫法 (便於管理)
CREATE TABLE persons (
p_id INT NOT NULL,
last_name VARCHAR(255) NOT NULL,
first_name VARCHAR(255),
address VARCHAR(255),
city VARCHAR(255),
CONSTRAINT pk_persons PRIMARY KEY (p_id)
);
-- 訂單明細表:訂單ID + 產品ID 唯一標識一行
CREATE TABLE order_items (
order_id INT NOT NULL,
product_id INT NOT NULL,
quantity INT DEFAULT 1,
unit_price DECIMAL(10,2),
CONSTRAINT pk_order_items PRIMARY KEY (order_id, product_id)
);
-- 學生選課表:學生 + 課程 + 學期 三列組合
CREATE TABLE student_courses (
student_id INT NOT NULL,
course_id INT NOT NULL,
semester VARCHAR(20) NOT NULL,
grade DECIMAL(3,1),
CONSTRAINT pk_student_courses PRIMARY KEY (student_id, course_id, semester)
);
-- 前提:目標列必須已定義為 NOT NULL
ALTER TABLE persons ADD PRIMARY KEY (p_id);
-- 多列組合主鍵帶約束名
ALTER TABLE persons ADD CONSTRAINT pk_persons PRIMARY KEY (p_id, last_name);
-- MySQL 特有:一步添加自增主鍵列並設為主鍵
ALTER TABLE persons
ADD COLUMN id INT NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST;
-- MySQL / MariaDB (無需約束名)
ALTER TABLE persons DROP PRIMARY KEY;
-- SQL Server / Oracle / PostgreSQL (需指定約束名)
ALTER TABLE persons DROP CONSTRAINT pk_persons;
-- 查詢約束名方法
-- MySQL: SHOW CREATE TABLE persons;
-- SQL Server: SELECT name FROM sys.key_constraints WHERE parent_object_id = OBJECT_ID('persons');
-- Oracle: SELECT constraint_name FROM user_constraints WHERE table_name = 'PERSONS' AND constraint_type = 'P';
-- PostgreSQL: SELECT conname FROM pg_constraint WHERE contype = 'p' AND conrelid = 'persons'::regclass;
-- 查看表結構確認主鍵
DESCRIBE persons;
SHOW CREATE TABLE persons;
-- 修改自增起始值
ALTER TABLE persons AUTO_INCREMENT = 10000;
-- 獲取最後插入的自增 ID
INSERT INTO persons (last_name, first_name) VALUES ('Wang', 'Wu');
SELECT LAST_INSERT_ID(); -- 返回剛插入行的 p_id
-- 重置自增計數器 (慎用,生產環境需極度小心)
ALTER TABLE persons AUTO_INCREMENT = 1;
| 場景 | 推薦類型 | 理由 |
|---|---|---|
| 單機/主從架構業務表 | BIGINT UNSIGNED AUTO_INCREMENT | 性能最優、空間小、順序寫入、64位足夠大 |
| 分庫分表/分布式系統 | 雪花算法 ID (BIGINT) / UUID v7 | 全局唯一、趨勢遞減、含時間戳 |
| 數據遷移合併/異構同步 | UUID (CHAR(36)) / UUID v7 | 無協調全局唯一、避免衝突 |
| 字典/配置/關係表 | 業務自然鍵 / 組合主鍵 | 語義清晰、無額外存儲、符合范式 |
主鍵是表的「身份證」,設計原則是 短小、順序、業務無關、穩定不變。MySQL InnoDB 下自增 BIGINT 是 99% 場景的最優選。掌握創建/修改/刪除 DDL 語法、理解聚簇索引機制、避開常見反模式,能為系統性能與可維護性打下堅實基礎。