ALTER TABLE 必须指定表名和操作类型,仅作用于基表;ADD COLUMN 默认允许NULL,MODIFY/CHANGE需注意约束与版本差异;重命名表用RENAME TO,列用CHANGE或RENAME COLUMN;在线DDL受引擎和参数限制,大表建议用pt-online-schema-change。

ALTER TABLE 语法必须带表名和操作类型
MySQL 中 ALTER TABLE 不是万能补丁,它必须明确指定目标表和具体动作。漏写表名、错用关键字(比如把 ADD 写成 INSERT COLUMN)会直接报错 ERROR 1064。常见误操作包括在子查询或视图上执行 ALTER TABLE——它只作用于基表,对视图无效。
实操建议:
- 执行前先用
DESCRIBE table_name或SHOW COLUMNS FROM table_name确认当前结构 - 生产环境务必加
IF NOT EXISTS(仅限ADD COLUMN)或提前SELECT COUNT(*)验证数据量,避免长事务锁表 - MySQL 8.0+ 支持原子 DDL,但低版本(如 5.7)中部分操作(如修改列类型)仍会重建整表,需预留磁盘空间
添加/删除/修改字段要区分 NULL 和 DEFAULT 行为
ADD COLUMN 默认允许 NULL,即使没显式声明;而 MODIFY COLUMN 或 CHANGE COLUMN 若原列有非空约束,新定义未带 NOT NULL 就会失败。另外,DEFAULT 值在不同 MySQL 版本处理逻辑不同:5.7 要求 DEFAULT 必须是常量,8.0+ 支持表达式(如 CURRENT_TIMESTAMP),但仅限特定类型。
实操建议:
- 新增字段带默认值时,优先用
ADD COLUMN col_name TYPE DEFAULT 'val' NOT NULL,避免后续 UPDATE 全表 - 改字段类型慎用
MODIFY:它不改列名;若需同时改名和类型,用CHANGE COLUMN old_name new_name TYPE - 删除字段前检查是否有索引、外键、触发器依赖该字段,否则报错
ERROR 1025
重命名表和列的语法不能混用
重命名表用 RENAME TO,重命名列必须用 CHANGE COLUMN 或 RENAME COLUMN(MySQL 8.0.4+)。把 RENAME COLUMN 写成 RENAME TO 会导致语法错误;反过来,在老版本用 CHANGE COLUMN 重命名时,必须重复写出完整定义(类型、约束等),容易遗漏。
实操建议:
- 跨版本迁移脚本时,优先用
CHANGE COLUMN保证兼容性,而非依赖新版RENAME COLUMN - 重命名表前确认没有活跃连接正在使用该表名,否则可能触发
ERROR 139(表正被使用) - 若表有分区,
RENAME TO会保留分区定义,但某些存储引擎(如 MyISAM)不支持分区表重命名
在线 DDL 的关键参数取决于存储引擎和操作类型
MySQL 5.6+ 的 InnoDB 支持在线 DDL,但不是所有操作都真正“在线”。例如 ADD COLUMN 在 5.6 是拷表,8.0 才默认 ALGORITHM=INPLACE;而 DROP PRIMARY KEY 始终需要 ALGORITHM=COPY。是否阻塞读写,要看 LOCK 参数:LOCK=NONE 允许并发 DML,但很多操作根本不支持它。
实操建议:
- 执行前加
ALGORITHM=INPLACE, LOCK=NONE显式声明,让 MySQL 提前校验可行性,而不是等到中途失败 - 监控
INFORMATION_SCHEMA.INNODB_TRX和SHOW PROCESSLIST,确认无长事务卡住 DDL - 超大表(>10GB)建议用
pt-online-schema-change工具替代原生命令,避免主从延迟突增
最易被忽略的是隐式字符集继承:当对已有表执行 ADD COLUMN 且未指定 CHARACTER SET 时,新列会继承表默认字符集,但如果表本身是 utf8mb4 而列定义用了 VARCHAR(255) CHARACTER SET utf8,可能引发排序规则冲突或截断。动手前,先查 SHOW CREATE TABLE 看清默认设置。










