CHAR_LENGTH返回字符个数(Unicode码点),LENGTH返回字节个数;如'你好'的CHAR_LENGTH为2、LENGTH为6;前者用于用户感知场景,后者用于存储和传输字节计算。
CHAR_LENGTH 和 LENGTH 到底返回什么
这两个函数看起来都“算长度”,但底层逻辑完全不同:char_length 数字符个数(unicode 码点),length 数字节个数。中文、emoji、带重音的字母在 utf8 下常占多个字节,这时候两个结果就对不上了。
比如 '你好':
CHAR_LENGTH('你好') 返回 2,
LENGTH('你好') 在 UTF8 编码下返回 6(每个汉字占 3 字节)。
常见错误现象:用 LENGTH 做字段长度校验,结果在存入 emoji 或繁体字时突然超长报错;或者用 CHAR_LENGTH 估算存储空间,发现磁盘占用远超预期。
什么时候该用 CHAR_LENGTH,什么时候必须用 LENGTH
选哪个,取决于你关心的是“人眼看到多少个字”,还是“数据库/网络实际要传多少字节”。
- 做表单限制、显示截断、分页计数 → 用
CHAR_LENGTH(用户感知的是字符数) - 评估磁盘占用、计算 TCP 包大小、判断
TEXT类型是否超限(如 MySQL 的TINYTEXT最大 255 字节)→ 必须用LENGTH - 和外部系统交互(比如 HTTP header 有字节限制)、对接旧协议(只认字节流)→ 优先验证
LENGTH
不同数据库里 LENGTH 行为不一致
MySQL 的 LENGTH 默认按字节;PostgreSQL 的 LENGTH 实际等价于 MySQL 的 CHAR_LENGTH(它叫 octet_length 才是字节数)。SQLite 默认行为类似 MySQL,但受编译选项影响。
容易踩的坑:
- 写 SQL 时假设
LENGTH在所有库都返回字节数,迁移到 PG 就出错 - ORM 层封装了字符串长度方法(比如 Django 的
.count()),没注意底层调用的是哪个函数 - MySQL 里建表用
VARCHAR(255),以为能存 255 个汉字 —— 实际最多 85 个(255 ÷ 3),因为VARCHAR参数是字符数,但总字节不能超 65535,且每行还有额外开销
查某条数据的实际字节大小:别只信函数
函数只能告诉你“当前值”的长度,但真实存储还受字段类型、排序规则、NULL 处理、行格式影响。比如:
-
TEXT类型在 InnoDB 中可能外存,LENGTH返回的是内容本身字节数,不包括指针开销 - 启用
ROW_FORMAT=COMPRESSED后,实际磁盘占用远小于LENGTH结果 - 字段定义为
VARCHAR(100) CHARACTER SET utf8mb4,插入'a'占 1 字节,但插入'??'(ZWNJ 连接的 emoji)可能占 8 字节
真要定位某行某字段的物理大小,得结合 INFORMATION_SCHEMA.INNODB_BUFFER_PAGE(MySQL 8.0+)或 pg_total_relation_size(PG)看整体分布,单靠 CHAR_LENGTH/LENGTH 只能当第一层快速筛查。

















