改字段精度本身不会丢数据,但alter table ... modify或change时若新定义比原值窄(比如decimal(10,2) → decimal(8,2)),mysql会静默截断——不是报错,而是直接砍掉高位整数部分,且不提示。
改字段精度本身不会丢数据,但alter table ... modify或change时若新定义比原值窄(比如decimal(10,2) → decimal(8,2)),mysql会静默截断——不是报错,而是直接砍掉高位整数部分,且不提示。
为什么修改精度后数据“看起来没变”却实际丢了?
MySQL在ALTER TABLE过程中对DECIMAL字段做类型变更时,只要新精度不足以容纳现有值,就会执行四舍五入或截断,具体行为取决于sql_mode。默认模式下(如STRICT_TRANS_TABLES未启用),它不会中断操作,而是默默修正数值再存回去。
-
DECIMAL(12,2)存着999999.99,改成DECIMAL(8,2)→ 变成9999.99(高位被砍) -
DECIMAL(10,4)存着123.456789,改成DECIMAL(10,2)→ 变成123.46(小数位四舍五入) - 如果原字段是
FLOAT或DOUBLE,转成DECIMAL时,那些本就失真的二进制浮点值会被“固化”为定点数,误差就此定型
phpMyAdmin界面改精度时容易踩的坑
phpMyAdmin的“更改”表单里点一下“保存”,背后执行的是ALTER TABLE ... CHANGE语句。它不会校验你填的新精度是否安全,也不会预览影响行数。
- 字段名、类型、长度全写在一行里,稍不注意就把
DECIMAL(15,2)输成DECIMAL(15,0)——小数位没了,所有.99变成整数 - 用“快速编辑”改类型,选了
DECIMAL但没填括号里的(M,D),phpMyAdmin可能默认补成DECIMAL(10,0),导致意外截断 - 批量改多个字段时,其中一个出错(比如超长),整个
ALTER可能失败回滚,但你只看到红字报错,未必意识到其他字段其实已生效
怎么安全地调整DECIMAL精度?
别信phpMyAdmin的单点修改,先查再动,分步验证。
- 先用
SELECT MAX(ABS(your_column)), COUNT(*) FROM your_table确认当前最大绝对值和记录数 - 算出所需最小
M:整数位数 + 小数位数(例如最大值1234567.89需DECIMAL(9,2)) - 执行
ALTER TABLE your_table MODIFY your_column DECIMAL(new_M,new_D) NOT NULL;(显式写全,避免隐式补值) - 立刻
SELECT your_column FROM your_table ORDER BY your_column DESC LIMIT 5;抽样比对,重点看末尾数字是否变动
最易被忽略的是:修改后即使SHOW CREATE TABLE显示类型已更新,也不代表数据完好——MySQL已完成静默修正,原始值不可恢复。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











