当前位置: 首页 > news >正文

MySQL字符集与排序规则全解析

这段文本是 MySQL 官方文档中关于“字符集(Character Set)和排序规则(Collation)”的详细说明,出自 MySQL 8.0 手册的第12章第3节。它系统地解释了 MySQL 如何在不同层级处理字符编码与排序规则。

下面我将用清晰、结构化的方式帮你理解这一大段内容,并提炼出核心要点,帮助你掌握其逻辑和实际应用。


🔍 一、整体结构概览

MySQL 的字符集与排序规则支持 四级默认机制(从高到低):

层级默认来源
1. 服务器(Server)启动参数或编译时设定
2. 数据库(Database)创建数据库时指定,否则继承服务器
3. 表(Table)创建表时指定,否则继承数据库
4. 列(Column)定义列时指定,否则继承表

原则:越靠近数据定义的地方优先级越高。

此外还有:

  • 字符串字面量(Literal)
  • 连接会话(Connection)
  • 国家字符集(National Character Set)

📚 二、逐节解析与通俗理解

12.3.1 排序规则命名规范(Collation Naming Conventions)

排序规则名称是有规律的,格式如下:

字符集_语言_版本_敏感性后缀
常见后缀含义:
后缀含义
_ai不区分重音(accent-insensitive),如 é = e
_as区分重音(accent-sensitive),如 é ≠ e
_ci不区分大小写(case-insensitive),如 A = a
_cs区分大小写(case-sensitive),如 A ≠ a
_ks区分片假名/平假名(kana-sensitive,日语专用)
_bin按二进制比较(区分大小写+按编码值排序)
示例:
  • utf8mb4_0900_ai_ci:utf8mb4 字符集,基于 Unicode 9.0 算法,不区分重音和大小写。
  • latin1_swedish_ci:latin1 字符集,瑞典语排序规则,不区分大小写。
  • utf8mb4_bin:utf8mb4 字符集,按二进制比较(区分大小写)。

⚠️ 注意:如果名字里没有 _ai_as,则由 _ci_cs 决定:

  • _ci → 隐含 _ai
  • _cs → 隐含 _as

12.3.2 服务器级字符集与排序规则(Server Level)

这是全局默认值。

设置方式:
mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_0900_ai_ci

如果不设置,默认就是 utf8mb4utf8mb4_0900_ai_ci(MySQL 8.0+)。

查看当前设置:
SHOW VARIABLES LIKE 'character_set_server';
SHOW VARIABLES LIKE 'collation_server';

✅ 作用:当创建数据库时未指定字符集,就使用这两个值作为默认。


12.3.3 数据库级字符集与排序规则(Database Level)

创建数据库时可以指定:

CREATE DATABASE mydbCHARACTER SET latin1COLLATE latin1_swedish_ci;
选择逻辑(按优先级):
  1. 显式指定 CHARACTER SETCOLLATE → 使用
  2. 只指定字符集 → 使用该字符集的默认排序规则
  3. 只指定排序规则 → 自动使用该排序规则对应的字符集
  4. 都不指定 → 使用服务器的默认值
查看数据库字符集:
-- 方法1:切换数据库后查看
USE mydb;
SELECT @@character_set_database, @@collation_database;-- 方法2:直接查 information_schema
SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME
FROM INFORMATION_SCHEMA.SCHEMATA
WHERE SCHEMA_NAME = 'mydb';

💡 影响范围:

  • 新建表的默认字符集
  • LOAD DATA 读取文件时的编码
  • 存储过程参数的默认字符集

12.3.4 表级字符集与排序规则(Table Level)

创建表时也可以指定:

CREATE TABLE t1 (name VARCHAR(50)
) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
选择逻辑:
  1. 显式指定 → 使用
  2. 只指定字符集 → 使用其默认排序规则
  3. 只指定排序规则 → 自动推导字符集
  4. 都不指定 → 继承数据库的设置

✅ 表字符集是 MySQL 扩展功能,标准 SQL 没有。


12.3.5 列级字符集与排序规则(Column Level)

这是最细粒度的控制,适用于 CHAR, VARCHAR, TEXT, ENUM, SET 类型。

CREATE TABLE users (username VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin,nickname VARCHAR(50) COLLATE utf8mb4_general_ci
);
选择逻辑:
  1. 显式指定 → 使用
  2. 只指定字符集 → 使用其默认排序规则
  3. 只指定排序规则 → 推导出对应字符集
  4. 都不指定 → 继承表的设置

✅ 这是标准 SQL 支持的功能。

⚠️ 修改列字符集可能造成数据丢失(如从 utf8mb4 改为 latin1)。


12.3.6 字符串字面量的字符集与排序规则(String Literals)

比如 'hello' 这样的字符串,在 SQL 中也有字符集和排序规则。

默认情况:
SELECT 'hello'; -- 使用连接会话的 character_set_connection 和 collation_connection
可以用“引介符”(Introducer)指定:
SELECT _latin1'hello';                    -- 指定字符集为 latin1
SELECT _utf8mb4'你好' COLLATE utf8mb4_bin; -- 指定字符集+排序规则

🔔 引介符 _charset 只是“标记”,不会转换字符串本身!

重要提醒:转义字符 \n, \t 等总是按 character_set_connection 解析!

例如:

SET NAMES latin1;
SELECT HEX(_sjis'à\n'); -- \n 被解释为换行(0A),即使用了 _sjis 引介符

因为 \n 是在解析阶段处理的,而引介符是在语义阶段起作用。


12.3.7 国家字符集(National Character Set)

SQL 标准中的 NCHAR, NVARCHAR, N'string' 表示“国家字符集”。

在 MySQL 中:

  • N'abc' 等价于 _utf8'abc'
  • NCHAR(10) 等价于 CHAR(10) CHARACTER SET utf8mb3

⚠️ 警告:utf8mb3 已被弃用!未来会被 utf8mb4 替代。

建议写成:

CHAR(10) CHARACTER SET utf8mb4
-- 或
N'abc' -- 但要注意未来兼容性

12.3.8 字符集引介符(Character Set Introducers)

就是前面说的 _charset 语法,可用于:

  • 字符串:_utf8'abc'
  • 十六进制:_latin1 X'4D7953514C'
  • 位值:_binary b'1000001'
关键点:
  • _binary 可以强制让十六进制/位值作为二进制字符串而非数字处理
  • 否则 MySQL 默认把 X'...' 当作数字

示例:

SET @v1 = X'000D' | X'0BC0';           -- 结果是 BIGINT 数字
SET @v2 = _binary X'000D' | X'0BC0';   -- 结果是 binary string
SELECT HEX(@v1), HEX(@v2);             -- 输出不同(高位0是否保留)

12.3.9 实际例子分析(Examples)

例1:列覆盖表
CREATE TABLE t1 (c1 CHAR(10) CHARACTER SET latin1 COLLATE latin1_german1_ci
) DEFAULT CHARACTER SET latin2 COLLATE latin2_bin;

✅ 结果:c1 是 latin1 + latin1_german1_ci,不受表影响。

例2:列只指定字符集
CREATE TABLE t1 (c1 CHAR(10) CHARACTER SET latin1
) DEFAULT CHARACTER SET latin1 COLLATE latin1_danish_ci;

✅ 结果:c1 的排序规则是 latin1_swedish_ci(latin1 的默认),不是 latin1_danish_ci

❗重点:列的默认排序规则来自字符集本身,而不是表!

例3:列完全依赖表
CREATE TABLE t1 (c1 CHAR(10)
) DEFAULT CHARACTER SET latin1 COLLATE latin1_danish_ci;

✅ 结果:c1 使用表的设置 → latin1 + danish_ci

例4:层层继承
CREATE DATABASE d1 DEFAULT CHARACTER SET latin2 COLLATE latin2_czech_cs;
USE d1;
CREATE TABLE t1 (c1 CHAR(10));

✅ 结果:c1 使用数据库的设置 → latin2 + czech_cs


🧠 总结:核心原则与最佳实践

项目原则
优先级顺序列 > 表 > 数据库 > 服务器 > 连接
显式 > 隐式越靠近数据定义的地方越优先
字符集与排序规则绑定每个排序规则只属于一个字符集
引介符 _charset是“标记”不是“转换”
转义字符解析始终按 character_set_connection 解析
N’…’ 的风险对应 utf8mb3,已弃用,建议避免

✅ 最佳实践建议

  1. 统一使用 utf8mb4
    支持完整 Unicode(包括 emoji),避免乱码。

  2. 推荐排序规则:

    • 通用:utf8mb4_0900_ai_ci(不区分大小写和重音)
    • 区分大小写:utf8mb4_0900_cs_0900_as_cs
    • 二进制比较:utf8mb4_bin
  3. 建库时明确指定:

    CREATE DATABASE app_dbCHARACTER SET utf8mb4COLLATE utf8mb4_0900_ai_ci;
    
  4. 建表时也建议指定(防止继承错误):

    CREATE TABLE users (name VARCHAR(100)
    ) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;
    
  5. 关键字段明确指定(如用户名区分大小写):

    username VARCHAR(50) COLLATE utf8mb4_bin
    
  6. 避免使用 N'...',改用 _utf8mb4 显式标记:

    SELECT _utf8mb4'你好世界';
    
  7. 连接时设置正确字符集:

    SET NAMES utf8mb4;
    

    或在客户端连接时设置 charset=utf8mb4


📌 常用查询命令汇总

-- 查看服务器默认
SHOW VARIABLES LIKE 'character_set_server';
SHOW VARIABLES LIKE 'collation_server';-- 查看当前数据库默认
SELECT @@character_set_database, @@collation_database;-- 查看某个数据库的设置
SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME
FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'your_db';-- 查看支持的字符集和默认排序规则
SHOW CHARACTER SET;-- 查看某个字符集的所有排序规则
SHOW COLLATION WHERE Charset = 'utf8mb4';

如果你正在设计数据库或遇到乱码问题,可以根据这个层级模型一步步排查:
从客户端 → 连接 → 数据库 → 表 → 列 → 字符串字面量,确保每一层都一致或明确。

需要我根据你的具体场景(比如建表语句、乱码问题)进一步分析吗?

http://www.dtcms.com/a/469925.html

相关文章:

  • 在云计算环境中实施有效的数据安全策略
  • 建设电子商务网站的意义巴中市建设厅官方网站
  • DES 加密算法:核心组件、加解密流程与安全特性
  • 游戏怎么做充值网站天津市建设工程监理公司网站
  • 01-Python简介与环境搭建-练习
  • Flink面试题及详细答案100道(81-100)- 部署、优化与生态
  • 机器学习实践项目(一)- Rossman商店销售预测 - 预处理数据
  • spring-Integration
  • SQL核心语言详解:DQL、DML、DDL、DCL从入门到实践!
  • 相亲网站怎么做的免费做网站tk
  • 在阿里巴巴上做网站要多少钱怎样制作自己的app
  • 数据湖Hudi - 二级索引:配置方法、存储位置与自动构建全解析(附电商实操案例)
  • 基于K近邻(KNN)算法的高光谱数据分类MATLAB实现
  • 石油网页设计与网站建设万网如何上传网站
  • 乐迪信息:智慧煤矿输送带安全如何保障?AI摄像机全天候识别
  • VMware vCenter 基础命令的 6 大核心模块
  • 龙华建设局网站做社区生意的网站
  • 【STM32项目开源】基于STM32的智能语音台灯系统
  • 构建和部署Spark、Hadoop与Zeppelin集成环境
  • 网站建设引擎广西住房和城乡建设厅领导班子
  • 把dxf转化成图片喂给vlm实现图纸检查比如尺寸有没有漏标
  • C++基础:(十一)vector深度剖析:底层原理与模拟实现
  • 【自用】request.ts 封装,带 token 过期后自动刷新 token 的功能
  • 成都定制网站建设服合肥公司注册地址
  • 分布式事务在前后端分离场景下的最终一致性实现
  • 农产品电子商务网站建设要求锦州网站建设公司
  • SSH命令建立隧道
  • [GazeTracking] 依赖项管理 | Docker化执行环境
  • uniapp web-view相互通信方法
  • (2)Kafka架构原理与存储机制