You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MySQL:Data too long与Data truncated错误差异及数据完整性疑问

问题背景

我在表doctor_offline_review中有一个name列,原本定义为varchar(255),但实际存储的最长字符串远不到255字符。考虑到该列存的是真实姓名,我认为最长不会超过50字符,于是执行了以下SQL语句修改列长度:

alter table doctor_offline_review modify name varchar(50);

结果抛出异常,提示部分姓名过长:

ERROR 1406 (22001): Data too long for column 'name' at row 1229425

之后我把目标长度改成80,执行:

alter table doctor_offline_review modify name varchar(80);

这次的异常和之前不一样:

ERROR 1265 (01000): Data truncated for column 'name' at row 5476907

最终我把列长度改成100才成功,但还有两个疑问:

  1. 为什么SQL语句类似但错误不同?ERROR 1406 (22001)和ERROR 1265 (01000)有什么区别?
  2. Data truncated是不是意味着可能存在数据完整性损失?(这次操作没出现数据受损的情况)

补充信息

  1. 行1229425的姓名内容为:
匿名患者[�Ϻ� �ɽ�]

通过以下语句查询得到:

select name from doctor_offline_review limit 1229424,1;

行5476907的姓名内容和它相近。
2. MySQL版本:Ver 8.0.36-0ubuntu0.22.04.1 for Linux on x86_64 ((Ubuntu)),操作系统:Ubuntu 22.04.4 LTS
3. 表结构:

mysql> desc doctor_offline_review;
+------------------+--------------+------+-----+---------+-------+
| Field            | Type         | Null | Key | Default | Extra |
+------------------+--------------+------+-----+---------+-------+
| review_id        | bigint       | NO   | PRI | NULL    |       |
| agree            | int          | YES  |     | NULL    |       |
| attitude         | varchar(4)   | YES  |     | NULL    |       |
| content          | varchar(40)  | YES  |     | NULL    |       |
| cost             | int          | YES  |     | NULL    |       |
| disease          | varchar(255) | YES  |     | NULL    |       |
| doctor_id        | bigint       | YES  | MUL | NULL    |       |
| effect           | varchar(4)   | YES  |     | NULL    |       |
| ill_condition    | varchar(50)  | YES  |     | NULL    |       |
| name             | varchar(100) | YES  |     | NULL    |       |
| patient_city     | varchar(50)  | YES  |     | NULL    |       |
| patient_province | varchar(20)  | YES  |     | NULL    |       |
| real_time        | datetime(6)  | YES  |     | NULL    |       |
| reason           | varchar(150) | YES  |     | NULL    |       |
| remedy           | varchar(255) | YES  |     | NULL    |       |
| skill            | varchar(255) | YES  |     | NULL    |       |
| status           | int          | YES  |     | NULL    |       |
| tag              | varchar(255) | YES  |     | NULL    |       |
| type_description | varchar(255) | YES  |     | NULL    |       |
+------------------+--------------+------+-----+---------+-------+
19 rows in set (0.00 sec)
问题解答

1. 两个错误码的区别

  • ERROR 1406 (22001):属于严格模式下的数据校验错误。当你的MySQL开启了严格模式(sql_mode包含STRICT_TRANS_TABLES或STRICT_ALL_TABLES),它会提前检测现有数据是否能适配新的列长度,一旦发现数据长度超过目标值,就直接终止修改操作,不会对数据做任何改动,目的是避免潜在的数据丢失。
  • ERROR 1265 (01000):属于截断操作异常错误。当目标长度80接近该行数据的实际字节长度时,MySQL尝试执行截断,但遇到了特殊字符(比如你看到的�这类乱码多字节字符),截断过程中无法正常处理这些字符,导致操作失败并抛出该错误。简单说,1406是"发现数据太长,直接拒绝操作",1265是"尝试截断但处理失败,报错终止"。

2. Data truncated与数据完整性损失

Data truncated字面意思是"数据被截断",正常情况下意味着MySQL会删除超出列长度的部分数据,这必然会造成数据完整性损失。但你这次操作没出现数据受损,是因为这个错误直接终止了修改操作——MySQL在尝试截断时失败,整个ALTER TABLE操作被回滚,所以数据没有被改动。

如果是在非严格模式下,MySQL可能不会报错,仅返回警告,此时过长的数据会被强制截断,就会导致数据完整性损失。你的场景中错误触发,操作未执行,所以数据不受影响。

内容的提问来源于stack exchange,提问作者Xuan Chen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 07:09:53