当前位置:首页 > 文章列表 > 数据库 > MySQL > MySQL WEIGHT_STRING 怎样比较排序规则产生的权重

MySQL WEIGHT_STRING 怎样比较排序规则产生的权重

来源:17golang原创 2026-10-29 15:42:59 0浏览 收藏

排查“为什么两个字符串在排序时看起来相等”时,直接把原文转成十六进制并不够,因为 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 字节,不能替代对排序规则的观察。

字符表达式经过字符集和排序规则进入 WEIGHT_STRING 并由 HEX 展示权重的静态结构图
图1:排序规则与权重输出的结构说明图,展示字符输入、比较权重和十六进制观察层的关系;这是静态说明图,不是运行截图。

字符字符串和二进制字符串不要混着看

同样写成 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 当成同一个尺度。

原始字符串分别进入 AS CHAR 和 AS BINARY 后产生空格或零字节填充的静态结构图
图2:AS CHAR 与 AS BINARY 的长度边界说明图,突出字符补空格、二进制补 0x00 及截断差异;这是静态说明图,不是运行截图。

实际排查时记住这三个边界

  • 先固定语境:同时记录字符集、排序规则、输入类型和是否显式转换。
  • 再看二进制:用 HEX(WEIGHT_STRING(...)) 观察,不要把终端的不可打印字符当成空结果。
  • 最后定用途:它适合测试和调试排序规则,不适合把具体权重字节当作跨 MySQL 版本稳定的业务格式。

还要留意 NULL:输入为 NULL 时函数返回 NULL;非空结果的类型可能是 VARBINARY,长度超过上限时则可能是 BLOB。这些信息能帮助你把“没有看到权重”和“权重是不可打印二进制”区分开。

相关问题

WEIGHT_STRING 能不能替代 ORDER BY?

不建议。它是调试排序规则的函数,官方明确提示行为可能随 MySQL 版本变化。业务排序应直接表达字符列、排序规则和稳定的次排序键。

为什么需要 HEX?

因为返回值是二进制字符串,可能包含不可打印字节;HEX 只是把它转换成便于复制和比较的十六进制文本。

AS CHAR 和 AS BINARY 的 N 有什么区别?

前者按字符计数并使用空格填充,后者按字节计数并使用 0x00 填充;多字节字符下,两者的长度边界不能混用。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
MySQL FORMAT 的 locale 参数怎样改变千分位符号MySQL FORMAT 的 locale 参数怎样改变千分位符号
上一篇
MySQL FORMAT 的 locale 参数怎样改变千分位符号
Redis TS.ALTER 修改 LABELS 为什么需要提供完整标签集
下一篇
Redis TS.ALTER 修改 LABELS 为什么需要提供完整标签集
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    775次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    771次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    856次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    821次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    652次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码