| 操作 | SQL 模板 | 示例 |
|---|---|---|
| 增加列 | ALTER TABLE tbl ADD COLUMN col_name type [constraints] [FIRST|AFTER col] | ALTER TABLE evan ADD COLUMN age2 VARCHAR(20) COMMENT '年齡' AFTER name; |
| 刪除列 | ALTER TABLE tbl DROP COLUMN col_name | ALTER TABLE evan DROP COLUMN age; |
| 修改列類型/約束/默認值(保留列名) | ALTER TABLE tbl MODIFY COLUMN col_name new_type [constraints] | ALTER TABLE evan MODIFY COLUMN age2 VARCHAR(30) COMMENT '年齡2' DEFAULT '0'; |
| 重命名列(可同時改類型) | ALTER TABLE tbl CHANGE COLUMN old_name new_name new_type [constraints] | ALTER TABLE evan CHANGE COLUMN age2 age INT COMMENT '年齡'; |
| 重命名表 | RENAME TABLE old_tbl TO new_tbl; | RENAME TABLE evan TO evan_v2; |
| 修改表註釋 | ALTER TABLE tbl COMMENT = '新註釋'; | ALTER TABLE evan COMMENT = '用戶基本信息表'; |
| 修改表字符集/排序規則(含列級轉換) | ALTER TABLE tbl CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; | ALTER TABLE evan CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; |
-- 一條 ALTER 多個動作(MySQL 5.6+ 支援)
ALTER TABLE evan
DROP COLUMN age,
ADD COLUMN age INT COMMENT '年齡' AFTER name,
MODIFY COLUMN email VARCHAR(128) NOT NULL,
CHANGE COLUMN phone mobile VARCHAR(20) COMMENT '手機號';
-- 生成批量 ALTER 腳本(如統一加 created_at/updated_at)
SELECT CONCAT('ALTER TABLE `', TABLE_NAME, '` ADD COLUMN `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, ADD COLUMN `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;')
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'biz_db' AND TABLE_TYPE = 'BASE TABLE';
MySQL 5.6+ ALGORITHM=INPLACE、LOCK=NONE 可在線執行大部分 DDL,但仍有複製表開銷。生產環境大表(>100萬行或 >5GB)強烈建議用:
# pt-osc 示例
pt-online-schema-change \
--alter "ADD COLUMN status TINYINT NOT NULL DEFAULT 1" \
D=biz_db,t=user \
--execute --max-load Threads_running=50 --critical-load Threads_running=100
VARCHAR(100) → VARCHAR(50) 會截斷數據,先 SELECT MAX(LENGTH(col)) 檢查。NOT NULL 列必須指定 DEFAULT,否則報錯。ALTER TABLE ... REORGANIZE PARTITION 專用語法,不可用普通 MODIFY。ALTER、CREATE、INSERT(建臨時表)權限。SHOW CREATE TABLE evan;
DESC evan;
SHOW COLUMNS FROM evan;
SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA='db' AND TABLE_NAME='evan';