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

 更新时间:2026年07月29日 09:45:07   作者:宁小法先森︿( ̄︶ ̄)︿  
MySQL数据库查询差异源于collation排序规则不同,本文就来详细的介绍一下MySQL collation 差异导致的类型比较行为不同,感兴趣的可以了解一下

当参数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 差异内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MySQL数据库数据类型的注意点和应用实例

    MySQL数据库数据类型的注意点和应用实例

    这篇文章主要介绍了MySQL数据库数据类型的注意点和应用的相关资料,MySQL数据类型主要包括tinyint、bit、float、decimal、char和varchar等,每种类型都有其特定的存储范围和适用场景,需要的朋友可以参考下
    2024-12-12
  • 解析如何使用Zend Framework 连接数据库

    解析如何使用Zend Framework 连接数据库

    本篇文章是对如何使用Zend Framework 连接数据库的方法进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • MySQL学习笔记1:安装和登录(多种方法)

    MySQL学习笔记1:安装和登录(多种方法)

    今天开始学习数据库,于数据库的大理论我就懒得写了,些考试必备的内容我已经受够了我只需要知道一点,人们整理数据和文件的行为在不断进化,以至现在使用数据库来更好的管理
    2013-01-01
  • SQL题目分析之计算用户的平均次日留存率

    SQL题目分析之计算用户的平均次日留存率

    留存率是指在特定时间段内,仍然继续使用某项产品或服务的用户占用户总数的百分比,这篇文章主要介绍了SQL题目分析之计算用户的平均次日留存率的相关资料,需要的朋友可以参考下
    2026-04-04
  • MYSQL row_number()与over()函数用法详解

    MYSQL row_number()与over()函数用法详解

    这篇文章主要介绍了MYSQL row_number()与over()函数用法详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • MySQL之JDBC编程用法及说明

    MySQL之JDBC编程用法及说明

    文章介绍了JDBC的概念、特点和工作流程,提供了开发环境的准备工作,并详细讲解了JDBC的核心API,包括DriverManager、DataSource、Connection、Statement、PreparedStatement和ResultSet,此外,还讨论了SQL注入的问题及解决方案,并给出了完整代码示例
    2026-05-05
  • Mysql高效分页详解

    Mysql高效分页详解

    这篇文章主要为大家详细介绍了Mysql高效分页的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-01-01
  • Linux安装Mysql8.0.20并配置主从复制(一主一从,双主双从)

    Linux安装Mysql8.0.20并配置主从复制(一主一从,双主双从)

    本文主要介绍了Linux安装Mysql8.0.20并配置主从复制,包含一主一从和双主双从,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-06-06
  • MySQL之InnoDB存储引擎中的页用法解读

    MySQL之InnoDB存储引擎中的页用法解读

    这篇文章主要介绍了MySQL之InnoDB存储引擎中的页用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-06-06
  • Windows mysql 双向同步设置方法 详细篇

    Windows mysql 双向同步设置方法 详细篇

    如果你需要windows mysql 主、备机双向同步环境,可按照以下步骤进行操作
    2011-05-05

最新评论