记录mysql创建数据库未指定字符集引发的问题及解决方法

问题描述

在执行某个存储过程时报告了以下错误:

复制代码
ERROR 1267 (HY000): Illegal mix of collations (utf8mb4_unicode_ci,IMPLICIT) and (utf8mb4_0900_ai_ci,IMPLICIT) for operation '='

检查所有参与比较的字段,使用的都是utf8mb4_unicode_ci排序规则,后确认是数据库默认排序规则为utf8mb4_0900_ai_ci导致。

  • 查看当前数据库默认排序规则

    SELECT DEFAULT_COLLATION_NAME
    FROM information_schema.SCHEMATA
    WHERE SCHEMA_NAME = 'your_db_name';

输出以下内容:

复制代码
+------------------------+
| DEFAULT_COLLATION_NAME |
+------------------------+
| utf8mb4_0900_ai_ci     |
+------------------------+
1 row in set (0.00 sec)
  • 查看会话默认

    SHOW VARIABLES LIKE 'collation%';

输出以下内容:

复制代码
+----------------------+--------------------+
| Variable_name        | Value              |
+----------------------+--------------------+
| collation_connection | utf8mb4_0900_ai_ci |
| collation_database   | utf8mb4_0900_ai_ci |
| collation_server     | utf8mb4_0900_ai_ci |
+----------------------+--------------------+
  • 查看数据库创建语句

    show create database your_db_name;

输出以下内容:

复制代码
CREATE DATABASE `your_db_name` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */

解决方案(任选其一)

1. 在存储过程中定义变量时指定排序规则

复制代码
DECLARE mchId VARCHAR(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

2. 修改数据库默认排序规则

  • 找到配置文件位置(常见路径):

    • Linux: /etc/my.cnf 或 /etc/mysql/my.cnf 或 /etc/mysql/mysql.conf.d/mysqld.cnf
    • Windows: my.ini(通常在 MySQL 安装目录下)
  • 在 mysqld 段落下添加:

    [mysqld]

    字符集和排序规则统一为 utf8mb4 + utf8mb4_unicode_ci

    character-set-server = utf8mb4
    collation-server = utf8mb4_unicode_ci

    可选:确保客户端也使用一致设置(避免连接层问题)

    skip-character-set-client-handshake
    init-connect='SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci'

skip-character-set-client-handshake 强制所有客户端使用服务器默认字符集(谨慎使用,某些旧客户端可能不兼容)。

  • 保存后重启 MySQL:

    Ubuntu/Debian

    sudo systemctl restart mysql

    CentOS/RHEL

    sudo systemctl restart mysqld

    Windows:通过服务管理器重启 MySQL

  • 验证配置是否生效

    SHOW VARIABLES LIKE 'character_set_server';
    -- 应返回 utf8mb4

    SHOW VARIABLES LIKE 'collation_server';
    -- 应返回 utf8mb4_unicode_ci

3. 修改现有数据库的默认排序规则(推荐)

  • 执行以下语句修改db排序规则

    ALTER DATABASE your_db_name CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

  • 修改现有表的字段排序规则

    -- 生成 ALTER TABLE 语句(检查是否有不一致的字段)
    SELECT
    CONCAT('ALTER TABLE ', TABLE_NAME, ' CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;') AS alter_sql
    FROM information_schema.TABLES
    WHERE TABLE_SCHEMA = 'your_db_name';

然后执行输出的 SQL(谨慎操作,先备份!)。

注意:CONVERT TO 会重建表并转换数据,大表需停机维护。

相关推荐
这个DBA有点耶14 分钟前
从反向扫描O(n)到正向扫描O(1):降序索引的物理机制与混合排序匹配规则
数据库
2501_933923251 小时前
解读Redis:单线程模型
数据库·redis·缓存
Tapdata3 小时前
被忽略的第三类上下文:Agent 进入真实业务后,还缺什么?
数据库·人工智能·架构
小科先生4 小时前
Java springboot调用数据库的基本流程
java·数据库·spring boot
星恒随风4 小时前
MySQL 从零入门(四):表的增删改查与基础查询详解
linux·服务器·数据库·笔记·mysql
Pniubi6 小时前
MySQL靠什么实现事务的?事务隔离级别有哪些?
java·数据库·mysql
数据库小学妹6 小时前
pgbouncer 事务池:prepared statement、临时表与会话状态
数据库·后端·postgresql
aiks_yuan6 小时前
MySQL 死锁怎么排查:看懂 INNODB STATUS 死锁日志,先查后插为什么必死锁(MySQL 8.2 实测)
mysql
Lucifer三思而后行8 小时前
最近折腾了一下金仓数据库的备份恢复
数据库·备份恢复
草莓熊Lotso9 小时前
【C++ 基于微服务的即时通讯系统】文件存储子服务实战:UUID生成、文件IO封装与全接口单元测试
开发语言·网络·数据库·c++·微服务·架构·单元测试