如何在SQL中用LENGTH或CHAR_LENGTH计算字符串长度?

作者:袖梨 2026-06-23
LENGTH返回字节数,CHAR_LENGTH返回字符个数;处理中文、emoji等utf8mb4字符串时,前者因编码差异导致数值偏大(如汉字3或4字节),后者恒为1,业务校验必须用CHAR_LENGTH,仅底层字节操作才用LENGTH。

LENGTH 和 CHAR_LENGTH 在 MySQL 中到底有什么区别?

MySQL 里 LENGTH 返回的是字节长度,CHAR_LENGTH 返回的是字符个数——这对中文、emoji 或 utf8mb4 编码的字符串影响极大。比如一个中文汉字在 utf8mb4 下占 3 或 4 字节,LENGTH 会返回 3 或 4,而 CHAR_LENGTH 始终返回 1。

  • 如果你要校验用户输入是否超过「10 个字符」,必须用 CHAR_LENGTH,否则中文输 3 个字就可能触发 LENGTH > 10
  • 如果你在做底层字节截断(比如适配旧协议限制),才考虑 LENGTH
  • 在 utf8mb4 + emoji 场景下,一个 ? 的 LENGTH 是 4,CHAR_LENGTH 是 1

PostgreSQL 和 SQL Server 怎么办?没有 CHAR_LENGTH?

PostgreSQL 只有 LENGTH,但它默认按字符计数(行为等价于 MySQL 的 CHAR_LENGTH);SQL Server 的 LEN 也按字符算,但会自动忽略末尾空格——这点容易误判。

  • PostgreSQL:LENGTH('你好') → 2,安全可用
  • SQL Server:LEN('abc ') → 3,要用 DATALENGTH('abc ') 才得 6(字节数),且注意 DATALENGTH 返回的是字节数,不是字符数
  • 跨数据库写法?别硬套函数名,先确认目标库的文档里该函数定义是「字符」还是「字节」

WHERE 条件里用 LENGTH/CHAR_LENGTH 性能很差?

是的,在大表上对字段套 CHAR_LENGTH(name) > 10 基本无法走索引——MySQL 无法为函数结果建立普通 B+Tree 索引(除非用生成列 + 索引)。

  • 更高效的做法:加一个 name_length TINYINT UNSIGNED AS (CHAR_LENGTH(name)) STORED 生成列,再给它建索引
  • 或者业务层控制:插入前就计算并存入 name_len 字段,查询直接用 name_len > 10
  • 临时查?可以接受全表扫描时再用,但别放在高频查询的 WHERE 里

遇到 NULL 或 TEXT 字段时要注意什么?

CHAR_LENGTH(NULL) 返回 NULL,不是 0;对 TEXT 类型字段调用 CHAR_LENGTH 没问题,但某些老版本 MySQL 对超长 TEXT(如 > 65535 字节)可能截断计算结果。

  • 判断空值要写成 CHAR_LENGTH(col) IS NULL OR CHAR_LENGTH(col) = 0,不能只写 = 0
  • 如果字段类型是 MEDIUMTEXTLONGTEXT,建议在应用层校验长度,避免数据库隐式转换开销
  • COALESCE(CHAR_LENGTH(col), 0) 统一转成数字,方便后续比较
实际用哪个,取决于你真正想量的是「人眼看到的字符个数」还是「存储占了多少字节」——这两个概念在多字节编码里从不相等,混淆它们是线上出 bug 的常见源头。

相关文章

精彩推荐