news 2026/5/21 11:48:44

<span class=“js_title_inner“>线上事故:为什么用户输入 `Abc` 却登录了 `abc` 的账号?</span>

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
<span class=“js_title_inner“>线上事故:为什么用户输入 `Abc` 却登录了 `abc` 的账号?</span>
关注我们,设为星标,每天7:30不见不散,每日java干货分享

案发场景:
你的团队开发了一个短链接系统(Short URL)。
核心逻辑是生成 6 位随机字符作为 ID,区分大小写(Base62 编码),以扩大 ID 容量。
灵异事件:

  • • 用户 A 生成了短链s.cn/AbCdEf,跳转到 Google。

  • • 用户 B 生成了短链s.cn/abcdef,跳转到 Baidu。

  • 结果:当用户访问s.cn/abcdef时,数据库竟然返回了用户 A 的 Google 链接!

原因:
MySQL 的默认字符集校对规则(Collation)通常是utf8mb4_general_ciutf8mb4_0900_ai_ci
注意后缀_ci(Case Insensitive)—— 意思是大小写不敏感。在 MySQL 眼里,'A' = 'a'是天经地义的真理。


1. 核心原理:从字符到字节

在默认的_ci校对规则下,MySQL 会将字符“归一化”后再比较。
而在BINARY操作符的作用下,MySQL 会强制将字符串转换为二进制字节流,然后进行逐字节比对。

  • 普通比较 (=):'A''a'被视为同一个东西。

  • BINARY 比较:'A'(Hex: 41) 和'a'(Hex: 61) 是完全不同的字节序列。


2. 实战演练:一字之差,谬以千里

场景一:短链接 / 邀请码 (Case Sensitive Codes)

这是最典型的场景。邀请码MyCodemycode必须代表两个不同的人。

Bug 写法:

SELECT * FROM invite_codes WHERE code = 'MyCode'; -- 结果:可能把 'mycode', 'MYCODE' 都查出来了

修正写法 (加照妖镜):

SELECT * FROM invite_codes WHERE BINARY code = 'MyCode'; -- 结果:只有 'MyCode' 能匹配,'mycode' 滚粗
场景二:API Key / Token 校验

背景:你分发给客户的AppSecret通常是一串乱码,比如k8Yt9z
风险:如果不加区分,黑客如果猜到了K8YT9Z,在默认配置下竟然也能通过校验!这大大降低了暴力破解的难度。

修正写法:

SELECT * FROM api_secrets WHERE app_id = 1001 AND BINARY secret_key = 'k8Yt9z';
场景三:数据清洗与去重 (Data Cleaning)

背景:历史遗留数据里,因为早期的 Bug,导致数据库里同时存在了Useruser两个标签。现在要合并去重。
如果你直接GROUP BY tag_name,MySQL 会把它们合成一组。

需求:必须把大小写不同的标签区分开统计。

-- 强制按二进制分组 SELECT tag_name, COUNT(*) FROM tags GROUP BY BINARY tag_name;
场景四:隐形字符的“显形” (Trailing Spaces)

冷知识:在某些 MySQL 版本和校对规则下,'a''a '(末尾有空格) 在比较时是相等的(PAD SPACE 行为)。
但加上BINARY后,空格的字节0x20无处遁形。

SELECT 'a' = 'a '; -- 可能返回 1 (True) SELECT BINARY 'a' = 'a '; -- 必定返回 0 (False)

3. 进阶:永久解决方案 (Collation)

BINARY操作符只是临时的“照妖镜”(Ad-hoc 查询)。
如果你的某个字段(如invite_code天生就必须区分大小写,那么在建表时就应该定好规矩,而不是每次查询都加BINARY

最佳实践:使用_bin后缀的校对规则。

CREATE TABLE invite_codes ( id INT PRIMARY KEY, -- 指定 collation 为 utf8mb4_bin (Binary) code VARCHAR(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin, UNIQUE KEY idx_code (code) );

效果:

  1. 1.自动区分:以后查询WHERE code = '...'自动区分大小写,不需要加BINARY关键字。

  2. 2.唯一性约束生效:你可以同时插入abcABC,数据库认为是两条不同的记录,不会报 Duplicate Key。


4. 避坑指南:索引失效危机

这是使用BINARY操作符最大的代价。

问题:
如果你的列code是默认的_ci校对规则,并且建了索引。
当你执行WHERE BINARY code = '...'时,索引可能会失效

原因:
索引树是按照“不区分大小写”的逻辑排序构建的。当你要求“区分大小写”时,MySQL 可能认为原本的索引树没法用了,只能全表扫描来逐个比对字节。

解决:
如果你需要高性能的精确匹配,请务必采用“进阶方案”,直接修改列的 Collation 为_bin,并重建索引。


5. 总结

BINARY 操作符是 MySQL 给开发者留的一个“严谨模式”开关。

  • 什么时候用?当业务逻辑依赖字符的精确匹配(邀请码、Token、密码散列值)时。

  • 注意什么?别滥用,小心索引失效。长治久安之策是修改 Table Collation。

推荐阅读 点击标题可跳转

50个Java代码示例:全面掌握Lambda表达式与Stream API

16 个 Java 代码“痛点”大改造:“一般写法” VS “高级写法”终极对决,看完代码质量飙升!

为什么高级 Java 开发工程师喜爱用策略模式

精选Java代码片段:覆盖10个常见编程场景的更优写法

提升Java代码可靠性:5个异常处理最佳实践

为什么大佬的代码中几乎看不到 if-else,因为他们都用这个...

还在 Service 里疯狂注入其他 Service?你早就该用 Spring 的事件机制了

看完本文有收获?请转发分享给更多人

关注「java干货」加星标,提升java技能

❤️给个「推荐 」,是最大的支持❤️

.cls-1{fill:#001e36;}.cls-2{fill:#31a8ff;}

.cls-1{fill:#001e36;}.cls-2{fill:#31a8ff;}

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/20 21:31:54

2026年电子器件与智能控制国际学术会议(EDIC 2026)

2026年电子器件与智能控制国际学术会议(EDIC 2026)将于2026年3月27日至29日在中国福建厦门隆重召开。本次会议汇聚全球电子器件与智能控制领域的专家、学者和行业精英,旨在交流最新研究成果与技术进展,推动学术合作与产业发展。会…

作者头像 李华
网站建设 2026/5/21 1:06:18

揭秘appium滑动屏幕技巧—实现用户仿真动作的多重方式

🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快在移动端应用中,基于简便的原因,用户通常会倾向于使用滑动操作来达到与应用程序中的控件进行交互的,这使得滑动成为自动化测试中…

作者头像 李华
网站建设 2026/5/20 9:37:06

深入理解大模型微调Checkpoint:从文件结构到生产部署

文章目录一 Checkpoint文件结构解析1.1 核心架构文件1.2 HuggingFace Trainer 原生状态1.3 分词器(Tokenizer)文件1.4 DeepSpeed ZeRO 优化器状态(分布式训练特有)1.5 Checkpoint 不能直接推理二 利用保存点进行推理的方法2.1 方案…

作者头像 李华
网站建设 2026/5/21 0:50:55

基于multisim的红外发射与报警接收电路设计

(1)设计一个红外发射器调制频率为30kHz。 (2)设计一个红外接收器,当无人遮挡红外光时,报警器不发报警信号。当有人遮挡光时,报警器发报警信号频率为800Hz。 (3)控制距离2m以上。 仿真图: 仿真演示与文件下载:基于mult…

作者头像 李华
网站建设 2026/5/20 17:56:06

Linux C/C++组件编译全解析:从源码到可执行文件的奥秘

引言:为什么需要了解文件后缀? 在Linux C/C开发中,不同文件后缀代表着不同的编译阶段和用途。作为开发者,理解这些后缀的含义不仅有助于构建系统,还能在调试和优化时提供重要线索。本文将基于QEMU项目中virtio-balloon…

作者头像 李华
网站建设 2026/5/21 1:27:44

CPU/内存/硬盘/网络信息提取——工业级一句话指令集

文章目录 🚀 CPU/内存/硬盘/网络信息提取——工业级一句话指令集 🔍 核心设计原则 🖥️CPU 信息(物理/逻辑/频率) 1. 物理CPU数 + 逻辑CPU数 + 每核线程数 2. 物理CPU型号 + 主频(实时 + 标称) 3. CPU架构 + 字长 + 字节序 4. CPU缓存层级(L1/L2/L3) 5. NUMA节点拓…

作者头像 李华