长度函数是什么
算字符串长度时最关键的区别是「按字节」还是「按字符」:MySQL 的 LENGTH 数字节、CHAR_LENGTH 数字符;PostgreSQL 的 length 数字符、octet_length 数字节。utf8mb4 下一个汉字占 3 字节,混用这两种口径是中文业务里最典型的误判来源。
基本信息
| MySQL | LENGTH 数字节;CHAR_LENGTH 与 CHARACTER_LENGTH 数字符 |
|---|---|
| PostgreSQL | length 数字符;octet_length 数字节;bit_length 数位 |
| 编码占用 | utf8mb4 下一个汉字 3 字节,常见 emoji 占 4 字节 |
| VARCHAR(N) | N 指字符数,与 LENGTH() 返回的字节数不是一回事 |
| 典型用途 | 校验超长、截断前判断、估算存储占用 |
| NULL 输入 | 参数为 NULL 时返回 NULL,而不是 0 |
两库对照示例
两库对照示例
-- MySQL
SELECT LENGTH('你好') AS bytes, -- 6:utf8mb4 每字 3 字节
CHAR_LENGTH('你好') AS chars, -- 2
LENGTH('a你') AS mixed; -- 4:1 + 3
-- PostgreSQL
SELECT length('你好') AS chars, -- 2
octet_length('你好') AS bytes; -- 6校验长度的正确写法
校验长度的正确写法
-- MySQL:限制 20 个字符必须用 CHAR_LENGTH
SELECT id, nickname FROM users WHERE CHAR_LENGTH(nickname) > 20;
-- PostgreSQL:length 本来就是字符数
SELECT id, nickname FROM users WHERE length(nickname) > 20;
-- 估算字段实际最长占用,判断索引或传输是否够用
SELECT MAX(CHAR_LENGTH(nickname)) AS max_chars,
MAX(LENGTH(nickname)) AS max_bytes
FROM users; -- 含中文时字节数通常是字符数的 3 倍左右两库函数对照
| 需求 | MySQL 8 | PostgreSQL |
|---|---|---|
| 字符数 | CHAR_LENGTH(str) | length(str) |
| 字节数 | LENGTH(str) | octet_length(str) |
| 位数 | BIT_LENGTH(str) | bit_length(str) |
| 空字符串 | LENGTH('') = 0 | length('') = 0 |
| NULL 输入 | 返回 NULL | 返回 NULL |
| 按字符截取 | SUBSTRING 与 LEFT 都按字符计 | substring 与 left 同样按字符计 |
典型使用场景
- 表单校验:昵称、地址限制“多少个字”,必须按字符数判断
- 字段设计:VARCHAR 长度按字符定,存储占用按字节估算
- 展示截断:预览取前 N 个字符,避免把多字节字符截成乱码
- 报文与协议校验:长度字段常按字节定义,用字节数判断
- 排查导入失败:字段超长报错时先分清是字符超限还是字节超限
- 内容分析:按字符数分布看标题、摘要长度是否合理
MySQL 的 SUBSTRING 与 LEFT 都按字符计,不会把一个汉字截成半个字节;但连接字符集不是 utf8mb4 时,写入阶段就可能丢失或报错,排查长度问题时先确认连接字符集。
用 LENGTH(col) <= 20 做“不超过 20 个字”的校验,含中文时会误判:一个汉字按 3 个长度计算,用户实际只能输入 6 个多字。校验字符数务必使用 CHAR_LENGTH 或 length。