当前位置: 代码网 > it编程>数据库>Mysql > 详解MySQL collation 差异导致的类型比较行为不同

详解MySQL collation 差异导致的类型比较行为不同

2026年07月29日 Mysql 我要评论
当参数code为int时查询不到 为string时可查询到create table `users_amoe_record` ( `id` int not null auto_increment,

当参数code为int时查询不到 为string时可查询到

create table `users_amoe_record` (
  `id` int not null auto_increment,
  `user_id` int not null default '0',
  `key` varchar(255) collate utf8mb4_general_ci not null default '',
  `code` char(12) collate utf8mb4_general_ci not null default '',
  `status` tinyint(1) not null default '0' comment '0 初始化;1已创建;3 成功收到来信 4收到但过期 5收到但异常',
  `created_at` timestamp not null default current_timestamp,
  `updated_at` timestamp not null default current_timestamp on update current_timestamp,
  primary key (`id`),
  unique key `user_id` (`user_id`,`code`) using btree
) engine=innodb auto_increment=37494 default charset=utf8mb4 collate=utf8mb4_general_ci;

但是另外数据库的数据表, code为int也可以查询到

create table `users_amoe_record` (
  `id` int not null auto_increment,
  `user_id` int not null default '0',
  `key` varchar(255) not null default '',
  `code` char(12) not null default '',
  `status` tinyint(1) not null default '0' comment '0 初始化;1已创建;3 成功收到来信 4收到但过期 5收到但异常',
  `created_at` timestamp not null default current_timestamp,
  `updated_at` timestamp not null default current_timestamp on update current_timestamp,
  primary key (`id`),
  unique key `user_id` (`user_id`,`code`) using btree
) engine=innodb auto_increment=460090 default charset=utf8mb4 collate=utf8mb4_0900_ai_ci;

mysql collation 差异导致的类型比较行为不同

根本原因

两个库的区别:

问题库正常库
code 列 collationutf8mb4_general_ciutf8mb4_0900_ai_ci
mysql 版本通常 5.7 或早期 8.0mysql 8.0+ 默认

当 php 通过 pdo 绑定整数参数时:

  • utf8mb4_0900_ai_ci:mysql 8.0 新排序规则,对 char 列和整数的混合类型比较做了正确处理,能找到记录
  • utf8mb4_general_ci:旧排序规则,pdo 以 pdo::param_int 传入整数时,mysql 对 char(12) 列的类型推导出现偏差,比较失败,查不到记录

本质是:pdo 发送整数类型参数 + char 字符列 + general_ci 排序规则 = mysql 类型推导错误。

修复方案

callback() 里对 $code 强转为字符串,让 pdo 以字符串参数发送,与 char(12) 列类型一致:

read amoeservice.php (lines 120-129)edit amoeservice.php

modified

同理,getcaptcha 里查记录时也用了整数查询,也应该修:

read amoeservice.php (lines 70-77)

getcaptcha 的查询已经有 (string) 强转,不需要改。只需要修 callback 的这一处。

总结

说明
根因utf8mb4_general_ci 排序规则下,pdo 整数参数无法匹配 char(12) 列
为什么另一库没问题utf8mb4_0900_ai_ci(mysql 8.0 默认)正确处理了混合类型比较
修复$code = (string)$params["code"] — pdo 以字符串传参,与列类型一致
诊断日志确认问题后可以清理掉 iolog("1") 等调试打点

到此这篇关于详解mysql collation 差异导致的类型比较行为不同的文章就介绍到这了,更多相关mysql collation 差异内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com