MySQL 使用 ALTER TABLE 陳述式新增欄位,支援指定位置、預設值、註解、索引等選項。本文說明標準語法、反引號用途、線上 DDL 行為與生產環境操作建議。
ALTER TABLE `database_name`.`table_name`
ADD COLUMN `column_name` COLUMN_DEFINITION
[FIRST | AFTER `existing_column`];
-- 在 PPIDChanged 欄位後新增 PROCID,VARCHAR(6) 不可為空,預設空字串
ALTER TABLE `mydb`.`orders`
ADD COLUMN `PROCID` VARCHAR(6) NOT NULL DEFAULT '' AFTER `PPIDChanged`;
-- 新增帶註解、預設當前時間的 DATETIME 欄位
ALTER TABLE `users`
ADD COLUMN `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間' FIRST;
-- 新增並同時建立索引
ALTER TABLE `products`
ADD COLUMN `sku` VARCHAR(32) NOT NULL DEFAULT '',
ADD INDEX `idx_sku` (`sku`);
| 項目 | 說明 |
|---|---|
| 反引號 \` \` | MySQL 標識符引用符號 (鍵盤 ESC 下方鍵)。資料庫名、表名、欄位名**建議全部包裹**,避免保留字衝突、特殊字元、大小寫敏感問題。 |
| 位置指定 | FIRST 放最前;AFTER col 放指定欄位後;省略則放最後。僅影響邏輯順序,不影響儲存順序 (InnoDB 依主鍵叢集)。 |
| DEFAULT | 新增欄位於既有資料列**必須**提供預設值 (或 NULL),否則報錯。NOT NULL 欄位無 DEFAULT 會在嚴格模式下失敗。 |
| 線上 DDL (Online DDL) | 5.6+ ALGORITHM=INPLACE 多數 ADD COLUMN 無需鎖表、不重建表 (僅修改元資料),瞬間完成。大表加索引才會重建。可加 LOCK=NONE 強制無鎖。 |
| 複制/備份影響 | 主從複制下,DDL 會同步至從庫;大表操作建議低峰期執行,監控 Seconds_Behind_Master。 |
mysqldump --single-transaction db table > backup.sql。SHOW PROCESSLIST; 觀察 Alter table 狀態;SHOW ENGINE INNODB STATUS 看線上 DDL 進度。ERROR 1067 (42000): Invalid default value for 'col'
-- 原因:DATETIME/TIMESTAMP 預設值需為常數或 CURRENT_TIMESTAMP,不能用 NOW()
-- 解決:DEFAULT CURRENT_TIMESTAMP 或應用層寫入
ERROR 1118 (42000): Row size too large (> 8126)
-- 原因:單行超過 65535 位元組上限 (含 VARCHAR 實際長度)
-- 解決:將大欄位改為 TEXT/BLOB、拆分表、啟用 innodb_large_prefix + ROW_FORMAT=DYNAMIC
-- 刪除欄位
ALTER TABLE `t` DROP COLUMN `col`;
-- 修改欄位定義 (型別、預設值、註解)
ALTER TABLE `t` MODIFY COLUMN `col` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '新註解';
-- 修改欄位名稱同時修改定義
ALTER TABLE `t` CHANGE COLUMN `old_name` `new_name` VARCHAR(20) NOT NULL DEFAULT '';