读书笔记之MySQL的字符集与比较规则小读

📘 第三章:字符集和比较规则------读书笔记

MySQL如何处理多语言文本数据文本排序比较。数据从存储到传输、比较的全过程编码逻辑,是解决"乱码"问题和优化文本查询性能的理论基础。


🎯 本章核心:解决两个问题

  1. 存储问题(字符集) :一个字符(如'我'、'A'、'🎉')在计算机中到底用什么二进制代码表示?

  2. 比较问题(比较规则):如何判断两个字符(如'a'和'A')是否"相等"?谁大谁小?

📖 详细内容拆解

3.1 字符集和比较规则简介

  • 字符集 (Charset) = 字符范围 + 编码规则

    • 定义了哪些字符可以被认可(如ASCII只有128个,GBK有汉字,UTF-8几乎包含所有)。

    • 定义了每个字符对应的唯一二进制编码(如'A' -> 0x41)。

  • 比较规则 (Collation) = 字符集的"排序规则"

    • 决定了字符如何比较大小和排序。

    • 同一字符集可以有多个比较规则(如utf8_general_ci不区分大小写,utf8_bin按二进制严格比较)。

3.2 MySQL中字符集

  • 区别 :MySQL中的 utf8 其实是 utf8mb3(最多3字节/字符),而 utf8mb4 才是真正的UTF-8(支持4字节,如表情符号)。

  • 现代应用一律使用 utf8mb4

  • 查看字符集支持项的sql语句

    复制代码
    SHOW CHARSET; -- 查看所有字符集及其默认比较规则
    SHOW COLLATION LIKE 'utf8mb4%'; -- 查看特定字符集的所有比较规则

3.3 字符集和比较规则的应用(四个层级)

规则:下级未指定时,自动继承上级的设定。

层级 说明 关键系统变量/语法
1. 服务器级 MySQL实例的默认设置 character_set_server, collation_server
2. 数据库级 创建数据库时可指定 CREATE DATABASE ... CHAR SET ... COLLATE ...
3. 表级 创建表时可指定,继承数据库 CREATE TABLE ... CHAR SET ... COLLATE ...
4. 列级 可为列单独指定,继承表 列名 VARCHAR(100) CHAR SET ... COLLATE ...

优先级从高到低 :

① 列级 > ② 表级 > ③ 数据库级 > ④ 服务器级

修改规则:只修改字符集,比较规则会自动变为新字符集的默认规则;反之亦然。

3.3.2 客户端与服务器通信中的字符集转换(⭐)

这是"乱码"产生的根源。一次简单的查询,数据可能经历多次编解码转换👇:

比如一次数据它的链路历程可能是这样的:
键盘输入 → 客户端编码 → 网络包 → 服务器"认为"的编码 → 连接字符集 → 存储字符集 → 返回字符集 → 终端显示

三个关键会话变量控制此流程

  1. character_set_client服务器认为客户端发送来的SQL语句是什么编码。

  2. character_set_connection:服务器将接收到的语句转换为何种编码进行处理(与字符串字面量比较相关)。

  3. character_set_results:服务器将结果集(包括数据、字段名等)转换为何种编码发回客户端。

一键设置SET NAMES 'charset_name'; 命令同时修改上述三个变量,通常用于确保连接使用统一的字符集,是解决乱码的常用方法。

3.3.3 比较规则的应用

  • 影响 ORDER BYGROUP BYDISTINCTWHERE 条件比较等所有涉及字符比较的操作。

  • 示例col列使用utf8mb4_general_ci(不区分大小写)排序时,'a''A'会被视为相同并排在一起;若使用utf8mb4_bin,则会被区分开。


💎 本章核心总结与最佳实践

1. 概念关系图

复制代码
字符集 (Charset)
    |
    |--- 包含多种 ---> 比较规则 (Collation)
    |                   |
    |                   |--- _ci: 不区分大小写
    |                   |--- _cs: 区分大小写
    |                   |--- _bin: 二进制比较
    |                    ci=case insensitive 不区分大小写
                         cs=case sensitive   区分大小写
                         bin=binary          按编码值二进制比
    |
    |
    |--- 常见种类 ---> utf8mb4 (推荐), gbk, latin1

2. 配置黄金法则

  • 统一 :服务器、数据库、表、连接字符集保持一致(都用 utf8mb4),拒绝乱码。

  • 连接即设 :在客户端程序连接后,立即执行 SET NAMES 'utf8mb4';(或配置连接参数),确保通信编码正确。

  • 列慎指定 :除非有特殊需求(如某列必须用latin1存储老数据),否则不需在列级指定,继承表设置即可。

3. 故障排查思路

如果出现乱码或排序不符合预期时,按以下顺序检查:

  1. 客户端发送的真实编码是什么?(代码文件编码、终端编码)

  2. 连接层的三个变量(client/connection/results)设置是否正确?(使用 SHOW VARIABLES LIKE 'character_set%'; 查看)

  3. 目标表/列的字符集和比较规则是什么?(使用 SHOW CREATE TABLE 表名; 查看)

4. 重要提醒

  • VARCHAR(100) 中的 100 指的是字符数 ,而非字节数。在utf8mb4下,最多可存储400字节。

  • 修改已有数据的列的字符集可能失败(如果新字符集无法表示原有数据)。

  • 选择_ci比较规则能提高模糊匹配的友好度,但需要确保业务逻辑允许。

相关推荐
码农很忙2 小时前
从0到1搭建智能分析OBS埋点数据的AI Agent:实战指南
数据库·人工智能
安当加密2 小时前
Oracle数据库透明加密实践:基于TDE架构的安全加固方案
数据库·oracle·架构
织元Zmetaboard2 小时前
什么是态势感知大屏?
网络·数据库
NineData2 小时前
NineData 支持 DB2 迁移到 PolarDB Oracle
数据库·oracle·ninedata·数据库迁移·数据库迁移工具·信创改造·智能数据管理平台
Saniffer_SH2 小时前
【每日一题】讲讲PCIe链路训练和枚举的前后关系
运维·服务器·网络·数据库·驱动开发·fpga开发·硬件工程
倔强的石头_3 小时前
金融行业数据库选型盘点——Kingbase PLSQL迁移指南
数据库
梓沂3 小时前
解决项目容器启动时MySQL端口检测的问题
数据库·mysql
计算机毕设VX:Fegn08953 小时前
计算机毕业设计|基于Java + vue水果商城系统(源码+数据库+文档)
java·开发语言·数据库·vue.js·spring boot·课程设计
川贝枇杷膏cbppg3 小时前
DmServiceDMSERVER.log是干嘛的
java·服务器·数据库