mysql如何修改字段类型_mysql alter table修改字段类型

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

ALTER TABLE MODIFY COLUMN 会丢失数据吗

直接用

MODIFY COLUMN
改字段类型,是否丢数据,取决于新旧类型的兼容性。比如从
VARCHAR(255)
缩成
VARCHAR(10)
,超长值会被截断;从
INT
改成
TINYINT
,超出 -128~127 范围的值会变成边界值或报错(取决于 SQL mode)。不是所有修改都安全,尤其涉及长度缩减、精度降低或类型跨大类(如字符串→数字)时

改宽不丢数据(
VARCHAR(10) → VARCHAR(200)
改窄大概率丢数据(
TEXT → VARCHAR(100)
,超长部分被截)
DECIMAL(10,2) → DECIMAL(5,2)
:整数位不够时,插入会报错或四舍五入(看版本和 sql_mode)
必须先查当前数据分布:
SELECT MIN(col), MAX(col), COUNT(*) FROM tbl WHERE col IS NOT NULL;

用 CHANGE COLUMN 还是 MODIFY COLUMN

CHANGE COLUMN
MODIFY COLUMN
都能改类型,但语义不同:
CHANGE
必须写两次字段名(旧名 新名),哪怕不改名也得重复;
MODIFY
只写一次,更简洁。两者在纯类型变更时行为一致,但
CHANGE
允许同时改名+改类型,
MODIFY
不允许改名。

只改类型、不改名 → 优先用
MODIFY COLUMN
(少写、不易错)
要改名又改类型 → 必须用
CHANGE COLUMN old_name new_name new_type
误写
CHANGE col col INT
是合法的,但多打一个
col
容易手滑漏掉,引发语法错误

修改 TEXT/BLOB 字段类型要加 ROW_FORMAT=DYNAMIC

MySQL 5.7+ 中,如果表用的是

COMPACT
REDUNDANT
行格式,直接对含
TEXT
BLOB
的字段执行
MODIFY
,可能报错:
ERROR 1118 (42000): Row size too large
。这是因为老行格式对单行总长有限制,而 TEXT 实际存储在行外,但元信息仍占空间。

先确认当前行格式:
SHOW TABLE STATUS LIKE 'tbl_name';
Row_format
若为
Compact
,建议先改行格式:
ALTER TABLE tbl_name ROW_FORMAT=DYNAMIC;
再执行字段修改,否则可能卡住或失败
DYNAMIC
是 InnoDB 默认(8.0+),但老表迁移后未必自动更新

在线修改字段类型真的“在线”吗

MySQL 5.6+ 支持部分

ALTER TABLE
操作的“在线”能力(即不锁表),但改字段类型是否真正不锁,要看具体操作和版本。例如
MODIFY COLUMN
VARCHAR
长度,在 5.7+ 中如果是扩大且字符集不变,通常可
ALGORITHM=INPLACE
;但缩容、改类型(如
VARCHAR → TEXT
)、或涉及全文索引时,大概率触发
COPY
算法,锁表 + 全量复制。

ALGORITHM=INPLACE, LOCK=NONE
强制指定,但 MySQL 会校验是否支持,不支持则报错
生产环境务必先在从库或测试库验证耗时与锁表现:
SHOW PROCESSLIST;
观察状态
大表(千万级+)改类型前,用
pt-online-schema-change
更稳妥
实际执行前,别跳过
SELECT ... LIMIT 5
看真实数据样例,还有那个容易被忽略的
sql_mode
设置——它会影响截断、零日期等行为的报错/警告策略。

相关推荐