目录
VARCHAR(255) 能够存储多少个汉字?
- MySQL 4.1 版本以前: VARCHAR 以 Byte 为单位存储,所以在 UTF8 每个汉字 3Bytes 的前提下,VARCHAR(255) 最多可存放约 85 个汉字;
- MySQL >= 4.1 版本:VARCHAR 以 “CHAR” 为单位存储,所以不需要关心每个汉字存多少个 Bytes,VARCHAR(255) 可存放 255 个汉字;
参考:https://www.cnblogs.com/gomysql/p/3615897.html
查看 MySQL 版本
MySQL> select version();
VARCHAR 的长度截断问题
因为在 MySQL >= 4.1 版本中,VARCHAR(255) 指定了一个最大长度为 255 个 CHAR(不是字节数)的列。
默认情况下(宽松模式下),如果将一个长度超过 255 个字符的字符串插入到这个列中,MySQL 会截断这个字符串,只保存前 255 个字符,并触发 WARNING,但不会引发错误。这意味着如果你尝试插入一个长度为 260 个字符的字符串到一个 VARCHAR(255) 列中,MySQL 将保留该字符串的前 255 个字符,并丢弃剩余的字符。
显然,这会带来巨大的麻烦。因为数据被截断之后 ORM 就再无法使用常规的编解码格式(e.g. UTF8)进行正常处理。
所以,如果你希望在插入过长的字符串时引发错误,就可以启用 MySQL 的 “严格模式”。此时,MySQL 会拒绝插入长度超过列指定长度的字符串,并抛出一个错误(e.g. Data too long for column)。
MySQL> SET GLOBAL sql_mode='STRICT_ALL_TABLES';
或者你应该在代码逻辑中添加长度校验逻辑。参考:https://stackoverflow.com/questions/64227111/prevent-mysql-to-truncate-values-in-flask-sqlalchemy
MySQL 模式类型
- ANSI 模式:宽松模式,对插入数据进行校验,如果不符合定义类型或长度,对数据类型调整或截断保存,报 warning 警告。
- TRADITIONAL 模式:严格模式,当向 MySQL 数据库插入数据时,进行数据的严格校验,保证错误数据不能插入,报 error 错误。用于事务时,会进行事务的回滚。
- STRICT_TRANS_TABLES 模式:严格模式,进行数据的严格校验,错误数据不能插入,报 error 错误。只对支持事务的表有效。
- STRICT_ALL_TABLES 模式:严格模式,进行数据的严格校验,错误数据不能插入,报 error 错误。对所有表都有效。