MySQL WEIGHT_STRING 怎样比较排序规则产生的权重
排查“为什么两个字符串在排序时看起来相等”时,直接把原文转成十六进制并不够,因为 MySQL 的字符比较会受字符集和排序规则影响。WEIGHT_STRING() 返回的不是原字符串,而是参与比较和排序的二进制权重;用 HEX() 包一层,就能把不可打印的二进制值变成便于对照的十六进制文本。
官方地址:https://dev.mysql.com/doc/refman/8.4/en/string-functions.html
最稳妥的看法是:先显式固定字符集与排序规则,再用HEX(WEIGHT_STRING(...))比较结果;如果输入本来就是BINARY,看到的则是字节值,不是字符排序权重。
先把排序权重变成可读结果
WEIGHT_STRING(str) 返回二进制字符串。对于 CHAR、VARCHAR、TEXT 等非二进制字符输入,它包含当前排序规则用于比较的权重;对于 BINARY、VARBINARY、BLOB 输入,它按字节值处理。调试时建议始终配合 HEX():
-- 用固定字符集和排序规则观察字符权重;HEX 只负责把二进制结果显示成可读文本
SET @s = _utf8mb4 'AB' COLLATE utf8mb4_0900_ai_ci;
SELECT @s, HEX(@s), HEX(WEIGHT_STRING(@s));
-- 预期观察形式:原文的 HEX 与权重的 HEX 是两列不同含义
-- @s = AB,HEX(@s) = 4142,权重 HEX 类似 1C471C60
这里的关键不是记住某一串十六进制数字,而是区分两层:HEX(@s) 是字符编码后的字节表现,HEX(WEIGHT_STRING(@s)) 才是排序规则参与比较的权重表现。官方手册把该函数定位为内部调试用途,因此不应把具体权重编码当作业务协议。
固定排序规则后,权重到底表示什么
排序规则改变时,同一段文本可能得到不同权重;同一排序规则也可能让大小写不同的文本得到相同权重。例如在大小写不敏感的排序规则下,AB 与 ab 的权重可以相同,这正是排序时被视为等价的原因之一:
-- 两个表达式显式使用同一排序规则,便于对照比较权重
SET @upper = _utf8mb4 'AB' COLLATE utf8mb4_0900_ai_ci;
SET @lower = _utf8mb4 'ab' COLLATE utf8mb4_0900_ai_ci;
SELECT
HEX(WEIGHT_STRING(@upper)) AS upper_weight,
HEX(WEIGHT_STRING(@lower)) AS lower_weight,
WEIGHT_STRING(@upper) = WEIGHT_STRING(@lower) AS same_weight;
-- 该结果用于解释排序规则;不要把权重字节直接保存为跨版本业务字段
按官方定义,如果两个权重相等,两个字符串在该比较语境下被视为相等;权重较小的字符串排在权重较大的字符串之前。注意,这个结论依赖输入携带的字符语义。只比较原始 UTF-8 字节,不能替代对排序规则的观察。

字符字符串和二进制字符串不要混着看
同样写成 AB,如果显式转换成二进制字符串,WEIGHT_STRING() 返回的就是输入字节本身。下面两组结果的差异,说明“字符排序权重”和“字节值”是两条不同的排查路线:
-- 字符串走排序规则权重;二进制字符串按每个字节的数值返回
SET @text_value = _utf8mb4 'AB' COLLATE utf8mb4_0900_ai_ci;
SET @binary_value = CAST('AB' AS BINARY);
SELECT HEX(WEIGHT_STRING(@text_value)) AS collation_weight;
SELECT HEX(WEIGHT_STRING(@binary_value)) AS byte_weight;
-- 字符输入的结果由排序规则决定;BINARY 输入通常与 4142 这类原始字节表示一致
因此,遇到排序结果与预期不同,先确认列是字符类型还是二进制类型,再确认表达式有没有显式 COLLATE。不要看到十六进制结果就直接断言“编码错了”。
AS CHAR 与 AS BINARY 怎样改变长度边界
AS 子句可以把输入强制成指定类型和长度。AS CHAR(N) 按字符计数,右侧用空格补齐;AS BINARY(N) 按字节计数,右侧用 0x00 补齐。若输入超过长度,都会截断且不会因为这个截断产生警告:
-- 对比字符长度和字节长度的补齐规则;N 的单位随类型变化
SELECT HEX(WEIGHT_STRING('ab' AS CHAR(4))) AS char_weight;
SELECT HEX(WEIGHT_STRING('ab' AS BINARY(4))) AS binary_weight;
-- CHAR(4) 的示例会体现空格补齐;BINARY(4) 会体现 0x00 补齐
-- 过长输入按目标长度截断,示例只用于定位长度边界
SELECT HEX(WEIGHT_STRING('abcdef' AS CHAR(4))) AS truncated_char;
SELECT HEX(WEIGHT_STRING('abcdef' AS BINARY(4))) AS truncated_binary;
这个差异很适合解释固定宽度字段、导入比较或排序异常:字符类型的长度单位是字符,二进制类型的长度单位是字节。多字节字符场景下,不能把两者的 N 当成同一个尺度。

实际排查时记住这三个边界
- 先固定语境:同时记录字符集、排序规则、输入类型和是否显式转换。
- 再看二进制:用
HEX(WEIGHT_STRING(...))观察,不要把终端的不可打印字符当成空结果。 - 最后定用途:它适合测试和调试排序规则,不适合把具体权重字节当作跨 MySQL 版本稳定的业务格式。
还要留意 NULL:输入为 NULL 时函数返回 NULL;非空结果的类型可能是 VARBINARY,长度超过上限时则可能是 BLOB。这些信息能帮助你把“没有看到权重”和“权重是不可打印二进制”区分开。
相关问题
WEIGHT_STRING 能不能替代 ORDER BY?
不建议。它是调试排序规则的函数,官方明确提示行为可能随 MySQL 版本变化。业务排序应直接表达字符列、排序规则和稳定的次排序键。
为什么需要 HEX?
因为返回值是二进制字符串,可能包含不可打印字节;HEX 只是把它转换成便于复制和比较的十六进制文本。
AS CHAR 和 AS BINARY 的 N 有什么区别?
前者按字符计数并使用空格填充,后者按字节计数并使用 0x00 填充;多字节字符下,两者的长度边界不能混用。
MySQL FORMAT 的 locale 参数怎样改变千分位符号
- 上一篇
- MySQL FORMAT 的 locale 参数怎样改变千分位符号
- 下一篇
- Redis TS.ALTER 修改 LABELS 为什么需要提供完整标签集
-
- 数据库 · MySQL | 1小时前 |
- MySQL FORMAT 的 locale 参数怎样改变千分位符号
- 443浏览 收藏
-
- 数据库 · MySQL | 1小时前 | MySQL · 数据库 · 权限管理 · mysql 默认角色 SET DEFAULT ROLE activate_all_roles_on_login
- MySQL SET DEFAULT ROLE 怎样影响下一次登录
- 454浏览 收藏
-
- 数据库 · MySQL | 1小时前 | MySQL · 数据库 · mysql CURRENT_ROLE SET ROLE 角色激活
- MySQL CURRENT_ROLE 为什么没有显示已经授予的全部角色
- 143浏览 收藏
-
- 数据库 · MySQL | 1小时前 | MySQL · mysql FROM_BASE64 TO_BASE64 Base64换行
- MySQL TO_BASE64 结果中的换行怎样影响数据交换
- 209浏览 收藏
-
- 数据库 · MySQL | 1小时前 |
- MySQL FROM_BASE64 怎样处理输入中的空白字符
- 369浏览 收藏
-
- 数据库 · MySQL | 1小时前 |
- MySQL EXPORT_SET 怎样为每一位生成不同的开关文本
- 400浏览 收藏
-
- 数据库 · MySQL | 1小时前 |
- MySQL JSON_DEPTH 怎样计算对象和数组混合时的嵌套层数
- 393浏览 收藏
-
- 数据库 · MySQL | 1小时前 | MySQL · JSON · mysql JSON JSON_STORAGE_FREE JSON_STORAGE_SIZE
- MySQL JSON_STORAGE_SIZE 为什么不等于 JSON 文本长度
- 164浏览 收藏
-
- 数据库 · MySQL | 17小时前 |
- MySQL SET_VAR hint 怎样为单条查询临时调整排序内存
- 257浏览 收藏
-
- 数据库 · MySQL | 17小时前 | MySQL · utf8mb4 ·
- MySQL utf8mb4_0900_ai_ci 怎样处理重音字符比较
- 369浏览 收藏
-
- 数据库 · MySQL | 17小时前 |
- MySQL gap lock 为什么阻塞范围外的插入
- 191浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 775次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 771次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 856次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 821次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 652次使用
-
- MySQL 明明加了索引,为什么查询还是很慢?先查这 6 个点
- 2026-06-27 374浏览
-
- golang MySQL实现对数据库表存储获取操作示例
- 2022-12-22 499浏览
-
- golang 基于 mysql 简单实现分布式读写锁
- 2023-01-07 384浏览
-
- 详解如何利用GORM实现MySQL事务
- 2023-01-07 184浏览
-
- Go语言实现操作MySQL的基础知识总结
- 2023-01-23 265浏览

