主鍵是關係型數據庫表的核心標識,正確管理主鍵結構直接關係數據完整性與查詢性能。本文匯總 MySQL 主鍵全生命周期的高頻 SQL,涵蓋建表、增刪改查、自增調整、元數據查詢等實戰場景,並說明常見坑點。
-- 單列主鍵 + 自增
CREATE TABLE `order` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`order_no` VARCHAR(32) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 聯合主鍵(無自增)
CREATE TABLE `order_item` (
`order_id` BIGINT UNSIGNED NOT NULL,
`sku_id` INT UNSIGNED NOT NULL,
`qty` INT NOT NULL,
PRIMARY KEY (`order_id`, `sku_id`)
) ENGINE=InnoDB;
-- 添加主鍵(表無主鍵時)
ALTER TABLE `test2` ADD PRIMARY KEY (`id`);
-- 修改主鍵:必須先刪除舊主鍵
ALTER TABLE `test2` DROP PRIMARY KEY, ADD PRIMARY KEY (`id`);
-- 將現有列改為自增主鍵(需先確保列唯一非空)
ALTER TABLE `category`
MODIFY COLUMN `id` INT(11) NOT NULL AUTO_INCREMENT FIRST,
ADD PRIMARY KEY (`id`);
注意:InnoDB 表必須有主鍵,若不顯式定義,會隱式創建 6 字節 RowID,佔用空間且無業務含義,強烈建議顯式指定業務無關的自增 BIGINT。
ALTER TABLE `test2` DROP PRIMARY KEY;
刪除後表無顯式主鍵,InnoDB 將使用隱式 RowID,性能下降,生產環境極少這樣操作。
-- 查看當前自增值
SHOW TABLE STATUS LIKE 'test2'\G
-- Auto_increment: 1001
-- 重置自增值(需大於現有最大值)
ALTER TABLE `test2` AUTO_INCREMENT = 10000;
-- 歸零(僅限空表或 TRUNCATE 後)
TRUNCATE TABLE `test2`; -- 同時重置自增為 1
-- 方式 1:INFORMATION_SCHEMA(標準、跨版本穩定)
SELECT
kcu.TABLE_NAME,
kcu.COLUMN_NAME,
kcu.ORDINAL_POSITION
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu
JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
ON kcu.TABLE_NAME = tc.TABLE_NAME
AND kcu.TABLE_SCHEMA = tc.TABLE_SCHEMA
AND kcu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME
WHERE tc.CONSTRAINT_TYPE = 'PRIMARY KEY'
AND tc.TABLE_SCHEMA = 'your_db';
-- 方式 2:SHOW INDEX(直觀)
SHOW INDEX FROM `test2` WHERE Key_name = 'PRIMARY';
-- 方式 3:DESCRIBE(簡易判斷 Key=PRI)
DESCRIBE `test2`;
| 場景 | SQL 範例 | 備註 |
|---|---|---|
| 添加唯一鍵 | ALTER TABLE `test2` ADD UNIQUE (`userid`); | 允許一個 NULL |
| 添加普通索引 | ALTER TABLE `test2` ADD INDEX (`id`); | 非唯一 |
| 修改列類型+非空 | ALTER TABLE `t` MODIFY `col` BIGINT NOT NULL; | 5.6+ 支持 Online DDL |
| 重命名列 | ALTER TABLE `t` CHANGE `old` `new` BIGINT NOT NULL; | 需重複類型定義 |
| 刪除列 | ALTER TABLE `t` DROP COLUMN `col`; | 若列在索引中需先刪索引 |
ERROR 1062 或觸發隱式刪除+插入),設計階段務必確認不可變性。pt-online-schema-change 或 gh-ost 無鎖變更