MySQL ORD 为什么不等于 Unicode 码点
来源:17golang原创
时间:2026-11-10 08:31:39 466浏览 收藏
如果把 ORD('中') 当成 Unicode 码点,结果一定会让人困惑。ORD() 读取的是参数最左侧字符:遇到单字节字符时结果与 ASCII() 相同;遇到多字节字符时,MySQL 会把组成该字符的字节按 256 的幂组合成一个数。要看 Unicode 码点,不能直接把这个结果当成 U+4E2D。
官方资料:https://dev.mysql.com/doc/refman/8.4/en/string-functions.html
先确认 ORD 的触发场景和权限边界
ORD(str) 只处理 str 的最左侧字符;参数为 NULL 时返回 NULL。它不负责把字符转换成 Unicode 标准中的码点,而是根据字符串当前编码中的字节值计算结果。因此排查时,第一道门禁是确认输入不是空值,并确认连接使用的字符集不会让你误读字节。
ASCII 字符是最容易造成错觉的例子。字母 A 只有一个字节,所以 ORD('A') 和 ASCII('A') 都是 65;这个结论不能推广到中文、日文或 Emoji。

把字符、字节和码点放到同一条流水线
不要只输出一个 ORD() 数字。把字节序列、字节长度、字符长度和 ORD 结果一起列出来,才能知道问题发生在字符表示还是数值解释阶段:
-- 统一连接字符集,避免字符串字面量使用了意外的连接编码。
SET NAMES utf8mb4;
-- 同时查看 UTF-8 字节、字节长度、字符数量和 ORD 结果。
SELECT
'中' AS sample_char,
HEX('中') AS utf8_bytes,
LENGTH('中') AS byte_length,
CHAR_LENGTH('中') AS character_count,
ORD('中') AS ord_value;
-- ASCII 字符用于对照,确认单字节时 ORD 与 ASCII 一致。
SELECT ASCII('A') AS ascii_value, ORD('A') AS ord_value;
在 utf8mb4 字面量下,中 的 UTF-8 字节是 E4B8AD,LENGTH() 看到 3 个字节,CHAR_LENGTH() 看到 1 个字符。这里的 ORD() 结果对应字节组合,而不是 Unicode 码点 20013。
按公式还原为什么不是 U+4E2D
MySQL 文档给出的多字节计算形式是:第 1 个字节,加上第 2 个字节乘以 256,再加上第 3 个字节乘以 256^2,后续字节继续增加幂次。对 中 的 E4 B8 AD 而言,计算就是:
-- 把 HEX 看到的三个字节按 ORD 的权重组合,便于人工核对结果。 SELECT 0xE4 + 0xB8 * 256 + 0xAD * 256 * 256 AS ord_formula, CONV(0xADE4B8, 16, 10) AS same_decimal_value, CONV(0x4E2D, 16, 10) AS unicode_code_point;
前两列表达的是同一个字节计算值,第三列才是 Unicode 码点的十进制写法。两者数值不同并不是乱码,也不是排序错误,而是观察对象不同:ORD() 面向字符串编码中的字节,Unicode 码点面向抽象字符编号。
设置查询门禁,避免把错误数值送进业务逻辑
如果业务要判断“是不是某个 Unicode 字符”,不要把 ORD() 的结果直接和 0x4E2D 比较。更稳妥的分流方式如下:
| 目标 | 优先观察 | 原因 |
|---|---|---|
| 判断字符是否相等 | 字符比较与明确的排序规则 | 这是字符语义问题,不是字节编号问题 |
| 排查存储或传输编码 | HEX()、LENGTH() | 可以直接看到字节序列和字节数量 |
| 统计字符数量 | CHAR_LENGTH() | 按字符计数,多字节字符不会被拆成多个字节 |
| 读取首字节组合 | ORD() | 它的定义就是返回最左侧字符的编码计算值 |
一个常见失败处理是先用 HEX() 确认数据,再决定是否需要在应用层按 Unicode 码点遍历。不要为了让数字“看起来像码点”而截断、倒序或手工改写 ORD 的结果;那会把编码诊断变成新的数据错误。

失败处理与通知复盘
遇到“ORD 返回的数字和预期码点不一样”时,按固定顺序复盘:先看参数是否为 NULL,再看 HEX() 是否符合预期编码,接着比较 LENGTH() 与 CHAR_LENGTH(),最后确认调用者到底需要字节值、字符长度还是 Unicode 码点。这个顺序能把故障定位在输入、编码或业务解释中的一个阶段。
常见问题
ORD() 能直接返回中文的 Unicode 码点吗?
不能把它当作通用 Unicode 码点函数。多字节字符会按组成字节计算,结果与 Unicode 标准码点可能完全不同。
ORD() 和 ASCII() 什么时候结果相同?
当最左侧字符是单字节字符时,两者结果相同。这个相同关系来自输入的字节宽度,不表示两个函数对多字节字符也有相同语义。
LENGTH() 为什么和 CHAR_LENGTH() 不一样?
LENGTH() 按字节计数,CHAR_LENGTH() 按字符计数。多字节字符越多,两者的差距越明显。
因此,MySQL ORD() 的正确理解是“最左侧字符的编码字节组合值”。先把 ORD 放回字符集、字节和业务目标组成的流水线里,再决定使用哪个函数,就不会再把它误认为 Unicode 码点。
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
201 收藏
-
116 收藏
-
453 收藏
-
248 收藏
-
329 收藏
-
237 收藏
-
430 收藏
-
487 收藏
-
436 收藏
-
数据库 · MySQL | 8小时前 | MySQL · InnoDB · 数据库排查 · mysql innodb 隔离级别 间隙锁 READ COMMITTED REPEATABLE READ next-key lock141 收藏
-
285 收藏
-
数据库 · MySQL | 8小时前 | MySQL · 错误处理 · 存储过程 · 数据库开发 · mysql 存储过程 signal 业务错误 SQLSTATE MYSQL_ERRNO MESSAGE_TEXT404 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习