目录


文章目录

  • 目录
  • VARCHAR(255) 能够存储多少个汉字?
  • 查看 MySQL 版本
  • VARCHAR 的长度截断问题
  • MySQL 模式类型


VARCHAR(255) 能够存储多少个汉字?

  • MySQL 4.1 版本以前: VARCHAR 以 Byte 为单位存储,所以在 UTF8 每个汉字 3Bytes 的前提下,VARCHAR(255) 最多可存放约 85 个汉字;
  • MySQL >= 4.1 版本:VARCHAR 以 “CHAR” 为单位存储,所以不需要关心每个汉字存多少个 Bytes,VARCHAR(255) 可存放 255 个汉字;

参考:

查看 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 模式类型

  1. ANSI 模式:宽松模式,对插入数据进行校验,如果不符合定义类型或长度,对数据类型调整或截断保存,报 warning 警告。
  2. TRADITIONAL 模式:严格模式,当向 MySQL 数据库插入数据时,进行数据的严格校验,保证错误数据不能插入,报 error 错误。用于事务时,会进行事务的回滚。
  3. STRICT_TRANS_TABLES 模式:严格模式,进行数据的严格校验,错误数据不能插入,报 error 错误。只对支持事务的表有效。
  4. STRICT_ALL_TABLES 模式:严格模式,进行数据的严格校验,错误数据不能插入,报 error 错误。对所有表都有效。