length()返回字节数,char_length()返回字符数;中文、emoji等在utf8mb4下占多字节但只算1字符,如'你好'的length()为6、char_length()为2。

MySQL里LENGTH()和CHAR_LENGTH()到底算什么
LENGTH()返回字节数,CHAR_LENGTH()返回字符数——这是最根本的区别。中文、emoji、带重音的字母在UTF8mb4下占多个字节,但都只算1个字符。
比如字符串 '你好' 在UTF8mb4编码下:LENGTH()返回6(每个汉字3字节),CHAR_LENGTH()返回2。
- 用LENGTH()判断存储是否超长?可能误判:字段定义为
VARCHAR(10),存入'???'(3个emoji)时,CHAR_LENGTH()=3,但LENGTH()=12,实际插入会失败 - 做截断处理时用错函数:用
SUBSTRING(str, 1, LENGTH(str)-1)删最后一个字节,可能切掉半个汉字,变成乱码 - 统计用户昵称“长度”(人眼感知的字数)必须用CHAR_LENGTH(),不是LENGTH()
PostgreSQL和SQL Server怎么处理字符串长度
PostgreSQL只有LENGTH(),但它默认按字符计算(类似MySQL的CHAR_LENGTH),不提供字节版函数;SQL Server的LEN()也按字符计,但会自动忽略末尾空格,而DATALENGTH()才返回字节数(含空格)。
- 迁移MySQL代码到PostgreSQL时,把
CHAR_LENGTH(col)直接换成LENGTH(col)即可,但LENGTH(col)不能照搬——它在MySQL里是字节,在PG里是字符 - SQL Server中
LEN('abc ')返回3,DATALENGTH('abc ')返回4(含1个空格字节),注意业务逻辑是否依赖末尾空格 - 跨数据库写通用SQL?别硬套函数名,优先在应用层统一用CHAR_LENGTH语义,或明确注释编码假设
为什么WHERE条件里用LENGTH()容易出错
因为LENGTH()对NULL返回NULL,不是0;而空字符串''的LENGTH()是0——这两者在WHERE中行为完全不同,容易漏数据或误过滤。
-
WHERE LENGTH(name) > 0排除NULL和空字符串,但无法区分NULL和''(两者都不满足条件) - 想只排除空字符串、保留NULL?得写成
WHERE name != '' OR name IS NULL,不能依赖LENGTH() - 在索引字段上用LENGTH()会强制全表扫描:MySQL无法用索引加速
LENGTH(title) > 50这类表达式
CHAR_LENGTH()在排序和分组时的隐性影响
当字段含多字节字符(如日文假名、越南文)时,CHAR_LENGTH()本身不影响排序规则,但它常被用于生成排序键或分组依据,这时编码和collation就关键了。
- 按“前5个字符”分组:
GROUP BY SUBSTRING(name, 1, 5)比GROUP BY SUBSTRING(name, 1, CHAR_LENGTH(name)/2)更稳定,后者在不同长度输入下分组逻辑会漂移 - ORDER BY CHAR_LENGTH(name) ASC 是合法的,但性能差:无法利用索引,每次都要实时计算
- 如果字段用了utf8mb4_unicode_ci,CHAR_LENGTH()结果不受collation影响,但LIKE匹配、大小写转换仍受其制约——长度和比较是两回事
字符集、排序规则、函数语义这三者咬合紧密,改其中一个,另外两个的行为边界就得重新验证。特别是从latin1迁移到utf8mb4后,LENGTH()值翻倍是常态,不是bug。










