-- 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)
);
-- 學生選課表:學生ID + 課程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';
| 類型 | 適用場景 | 優點 | 缺點 |
|---|---|---|---|
| INT/BIGINT AUTO_INCREMENT | 絕大多數業務表 | 性能最好、占用空間小、順序寫入友好 | 分庫分表需解決全局唯一 |
| UUID/CHAR(36) | 分布式系統、數據遷移合併 | 全局唯一、無協調生成 | 占用空間大、無序寫入導致頁分裂、索引碎片 |
| 雪花算法 ID (BIGINT) | 高併發分布式系統 | 有序、全局唯一、含時間戳 | 依賴時鐘、需部署 ID 生成服務 |
| 業務自然鍵 | 字典表、配置表、關係表 | 語義清晰、無額外存儲 | 業務變更風險大、組合鍵複雜 |
原因:插入重複主鍵值、自增計數器異常、主從複製衝突
解決:檢查業務邏輯、重置自增值 ALTER TABLE t AUTO_INCREMENT = 1000、使用 INSERT IGNORE 或 ON DUPLICATE KEY UPDATE
風險:InnoDB 自動生成 6 字節隱藏主鍵 (GEN_CLUST_INDEX),無法控制、不利於複製、不可作為外鍵引用
建議:所有表顯式定義主鍵,哪怕是 id BIGINT AUTO_INCREMENT PRIMARY KEY
-- 父表
CREATE TABLE departments (
dept_id INT PRIMARY KEY,
dept_name VARCHAR(100)
);
-- 子表引用父表主鍵
CREATE TABLE employees (
emp_id INT PRIMARY KEY,
dept_id INT,
emp_name VARCHAR(100),
FOREIGN KEY (dept_id) REFERENCES departments(dept_id)
);
主鍵是關係型數據庫表的核心標識。正確設計主鍵(類型選擇、單列/組合、命名規範)、理解存儲引擎特性(特別是 InnoDB 聚簇索引機制)、掌握 DDL 操作語法,是數據庫設計與維護的基本功。遵循「短小、順序、業務無關」原則選擇主鍵,能為系統長期穩定運行奠定基礎。