length() 返回字节数而非字符数,char_length() 才按unicode字符计数;前者适用于二进制长度判断,后者用于准确统计字符个数,且二者对null均返回null。

LENGTH() 返回字节数,不是字符数
MySQL 的 LENGTH() 函数返回的是字符串所占的**字节数**,不是 Unicode 字符个数。在 utf8mb4 字符集下,一个中文、emoji 或某些特殊符号可能占 3 或 4 个字节,LENGTH() 就会返回对应字节数,容易误判“长度”。比如:
SELECT LENGTH('你好'), LENGTH('a'), LENGTH('??');结果可能是 6、1、4(取决于 emoji 编码方式),而非字符意义上的 2、1、1。
想按字符数统计,该用 CHAR_LENGTH() 而不是 LENGTH()
真正表示“有几个字符”的函数是 CHAR_LENGTH()(也可写作 CHARACTER_LENGTH()),它按 Unicode 字符计数,与字符集无关。对多字节字符更可靠:
-
CHAR_LENGTH('你好')→ 返回2 -
CHAR_LENGTH('a')→ 返回1 -
CHAR_LENGTH('??')→ 返回1(复合 emoji 在 MySQL 8.0+ 中通常视为单个字符)
注意:低版本 MySQL(如 5.7)对某些组合 emoji 支持不完整,CHAR_LENGTH() 可能仍拆分为多个码点,实际值需结合 COLLATION 和 CHARSET 验证。
LENGTH() 常用于判断二进制数据或字节限制场景
虽然不适合字符计数,LENGTH() 在以下情况反而更准确:
- 检查 BLOB / VARBINARY 字段的实际存储大小
- 验证 HTTP Header、Token、加密哈希值(如
SHA2('x',256)固定 64 字符,但LENGTH()返回 64 字节,而CHAR_LENGTH()也返回 64 —— 此时两者一致,因全是 ASCII) - 做字段是否超 MySQL 行限制的粗略估算(如 utf8mb4 下单行最大约 65535 字节,需用
LENGTH()累加各字段)
错误示例:用 LENGTH(name) > 10 拦截“超过 10 个汉字”的输入 —— 实际会拦住所有汉字(每个至少 3 字节),应改用 CHAR_LENGTH(name) > 10。
注意 NULL 和空字符串的返回值
LENGTH(NULL) 和 CHAR_LENGTH(NULL) 都返回 NULL,不是 0;而 LENGTH('') 和 CHAR_LENGTH('') 都返回 0。在 WHERE 条件或聚合中需显式处理 NULL:
WHERE CHAR_LENGTH(IFNULL(title, '')) > 0
直接写 CHAR_LENGTH(title) > 0 会把 title IS NULL 的行过滤掉(因为 NULL > 0 结果为 UNKNOWN),这点常被忽略。










