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),这点常被忽略。
