mysql中ALTER TABLE修改表结构的语法与应用

来源:这里教程网 时间:2026-02-28 20:42:07 作者:

ALTER TABLE 添加字段时必须指定数据类型和非空约束

MySQL 不允许添加没有类型的列,

ADD COLUMN
后必须跟完整定义。常见错误是漏写
NOT NULL
却又没设默认值,导致执行失败。

正确写法:
ALTER TABLE users ADD COLUMN phone VARCHAR(20) NOT NULL DEFAULT '';
如果允许为空,显式写
NULL
更安全(避免某些版本默认行为差异):
ALTER TABLE users ADD COLUMN remark TEXT NULL;
添加自增主键需同时满足:字段为整型、
NOT NULL
AUTO_INCREMENT
、且表无其他自增列:
ALTER TABLE logs ADD COLUMN id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY FIRST;

修改字段类型或名称要用 CHANGE COLUMN 或 MODIFY COLUMN

CHANGE COLUMN
可改名+改类型,
MODIFY COLUMN
只能改类型(不改名)。二者都不能跳过字段定义——即使只改类型,也得把整个新定义写全。

重命名并调类型:
ALTER TABLE orders CHANGE COLUMN order_time created_at DATETIME NOT NULL;
仅扩大长度(比如从
VARCHAR(50)
VARCHAR(200)
):
ALTER TABLE products MODIFY COLUMN description VARCHAR(200);
注意:缩小长度可能失败(若已有数据超长),MySQL 会报错
ERROR 1406: Data too long for column

删除字段前务必确认外键和应用层依赖

DROP COLUMN
是高危操作,一旦执行无法回滚(除非有备份或 binlog 可恢复)。InnoDB 表删字段实际会重建表,大表耗时久、锁表时间长。

先查是否有外键引用:
SELECT CONSTRAINT_NAME, TABLE_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE COLUMN_NAME = 'user_id' AND REFERENCED_TABLE_NAME = 'users';
删字段语句很简单,但别手快:
ALTER TABLE user_profiles DROP COLUMN avatar_url;
生产环境建议在低峰期执行,并提前在测试库验证锁表现和耗时

给字段加索引要区分 UNIQUE 和普通 INDEX,避免重复创建

ADD INDEX
ADD UNIQUE INDEX
添加索引时,MySQL 不会提示“索引已存在”,而是直接报错
ERROR 1061: Duplicate key name
。名字冲突、字段顺序不同都会视为不同索引。

推荐显式命名索引,方便后续管理:
ALTER TABLE comments ADD INDEX idx_post_id_status (post_id, status);
唯一约束可直接在
ADD COLUMN
时加上:
ALTER TABLE accounts ADD COLUMN email VARCHAR(255) NOT NULL UNIQUE;
注意:对 TEXT/BLOB 字段建索引必须指定前缀长度,否则报错:
ALTER TABLE articles ADD INDEX idx_title (title(100));
加索引和删字段这类操作,在千万级表上可能卡住写入,不是语法对了就能安心跑。真正麻烦的往往不是怎么写,而是有没有查清依赖、评估过锁影响、留好退路。

相关推荐