好的,我可以帮你整理一份针对 MySQL 字符集、排序规则问题及批量修改方法 的新人学习文档,结构清晰、示例完整,并涵盖 TP6/PHP 场景常见问题。
MySQL 字符集与排序规则学习指南(新手版)
1️⃣ 什么是字符集和排序规则(Collation)
-
字符集(Character Set) :定义存储字符的编码方式,例如
utf8、utf8mb4。-
utf8:MySQL 三字节 UTF-8,只能存储 BMP(基本多文种平面)字符。 -
utf8mb4:MySQL 四字节 UTF-8,支持所有 Unicode 字符,包括 emoji。
-
-
排序规则(Collation) :定义字符比较和排序方式,例如
utf8_general_ci、utf8mb4_general_ci。-
ci= case-insensitive(大小写不敏感) -
cs= case-sensitive(大小写敏感)
-
2️⃣ 常见错误
2.1 SQLSTATE[HY000]: General error: 1267 Illegal mix of collations
-
原因:查询条件中涉及的 两边字段/字符串的字符集或排序规则不一致。
-
例如:
CrystalSELECT * FROM pack WHERE pack_number = 'ABC123';-
pack_number字段是utf8_general_ci -
'ABC123'是 PHP UTF-8(可能是utf8mb4)→ 会报 1267 错误。
-
2.2 Lock wait timeout exceeded
-
虽然不是字符集问题,但常在大事务里出现。
-
原因:事务包裹大量更新/循环查询,导致表被长时间锁住。
3️⃣ 如何解决字符集问题
3.1 统一数据库、表和字段字符集
修改数据库默认字符集
ALTER DATABASE your_database_name
CHARACTER SET = utf8mb4
COLLATE = utf8mb4_general_ci;
查看数据库下所有表
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'your_database_name';
批量生成表字符集修改语句
Crystal
SELECT CONCAT('ALTER TABLE `', TABLE_NAME, '` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;') AS sql_statements
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = '数据库名'
AND TABLE_TYPE='BASE TABLE';
- 执行生成的 SQL,即可统一整个数据库所有表。
单独修改字段字符集(可选)
ALTER TABLE `pack_2020`
MODIFY `pack_number` VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
3.2 临时解决方法(只在查询时使用)
SELECT *
FROM pack_2020
WHERE pack_number COLLATE utf8mb4_general_ci = 'ABC123';
-
适合临时查询或测试。
-
不推荐在业务中大量使用,容易引起性能问题。
3.3 PHP/TP6 注意事项
-
数据库连接字符集:
// TP6 数据库配置 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_general_ci', -
避免循环里频繁查询数据库,尽量批量操作。
-
事务不要过大,避免锁超时。
-
队列任务中也要保持字符集一致性,避免异步写入出错。
4️⃣ 字符集检查与调试
- 查看表字符集:
Crystal
SHOW CREATE TABLE pack;
- 查看字段字符集:
Crystal
SELECT COLUMN_NAME, CHARACTER_SET_NAME, COLLATION_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA='your_database_name'
AND TABLE_NAME='pack';
5️⃣ 批量修改数据库示例流程
-
确认数据库名:
SELECT DATABASE();
-
查看所有表:
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='lazada100';
-
生成批量修改 SQL:
SELECT CONCAT('ALTER TABLE
', TABLE_NAME, 'CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;')
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA='lazada100'; -
执行生成的 SQL。
-
检查字段是否统一:
SELECT COLUMN_NAME, CHARACTER_SET_NAME, COLLATION_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA='lazada100';
6️⃣ 小结
-
字符集统一 是解决
Illegal mix of collations的根本方法。 -
utf8mb4_general_ci是现代系统推荐方案。 -
事务、循环查询 也是高并发系统中常见问题,要与字符集问题区分。
-
TP6/PHP 中要注意数据库配置和队列任务字符集一致。