MySQL字符集与校对集

MySQL字符集与校对集

创建数据库

创建数据库的时候,除了数据库名,还有两个参数:字符集(Character Set)和校对集(Collation)。

下图是我用“Sequel Pro”创建数据库时的界面(Sequel Pro只有macOS有),它需要选Encoding和Collation
16305113947013.jpg

用“Navicat Premium”创建数据库,它需要选Character Set和Collation

用命令创建数据库也可以指定编码(CHARSET)和校对集(COLLATE)

CREATE DATABASE `wordpress` DEFAULT CHARSET utf8mb4 COLLATE utf8mb4_0900_ai_ci;

编码与字符集的区别

以上两个软件中,数据库名我们就不用看了,另外的参数共有三个:

  • Encoding:编码,由于编码者是一个集合,我们一般叫它“编码集”;
  • Character Set:字符集;
  • Collation:Collation是校对的意思,但由于它其实就是一组规则的集合,所以我们一般叫它“校对集”,但“校对集”让人比较难理解,其实它就是“一组排序规则”。

创建数据库里的两个工具的对应上来看,Sequel Pro里的Encoding与Navicat Premium里的Character Set是一个意思,也就是说,从这两个软件上来看,编码与字符集是一个意思。

但事实上,编码和字符集是有区别的,对于ASCII字符集,它只有一种编码,那就是ASCII码,所以ASCII的编码集和字符集是一样的,但Unicode字符集就不止一种编码了,它有UTF-8、UTF-16、UTF-32三种编码。但我们平时说,都说字符集,不说编码集。

编码是什么,我想就不需要解释了吧,所有的文字、符号、表情要保存到硬盘中,最终肯定要变成一个数字,毕竟电脑的本名叫计算机,计算机计算机,当然就是计算数字用的,它的所有数据都是二进制的,只有数字才能变成二进制,所以字符必须编码成数字,最经典的就是ASCII码,在ASCII中,大写A是十进制的65,而小写a则是十进制的97,即65对应A,97对应a,这就是最基础的“编码”。
ASCII码

当然,ASCII只能表示26个英文字母+10个数字+常见的标点符号+少量的其它符号,但世界上有很多语言,每种语言的文字都不一样,所以每种文字都有自己的编码,比如中文常见的有GB2312和GBK(GB是国标的拼音首字母,K是扩展的“扩”字的拼音首字母,表示“扩展字符集”的意思)。

MySQL8.0默认的字符集(charset)是utfmb4编码的(Chapter 10 Character Sets, Collations, Unicode),我们建库的时候用这个编码就可以(文本中存emoji表情需要这个编码),mb是multibytes(多字节)的意思,4就是4个字节的意思,其实在mysql添加utf8mb4之前的那个“utf8”是“utf8mb3”,只不过没有把mb3写出来呗了。

校对集(Collation)

校对集,其实就是比较规则、排序规则,比如,按字母顺序排序,小写b肯定排在小写a后面,那为什么数据库会知道b排在a后面呢?因为b的ASCII是98,a的ASCII是97,从小到大排,98肯定排在97的后面。

然而,实际的排序,比a和b排序复杂的多,比如中文排序按拼音首字母、按声调、德语法语之类的也是有声调的,排序的时候,决定哪个字排前面,哪个字排后面的一组规则,就叫“校对集(Collation)”

utf8mb4_0900_ai_ci解释

  • 0900是排序算法的版本号;
  • ai表示accent insensitive(音调不敏感),比如在排序时,认为e, è, é, ê, ë是一样的;
  • as表示accent sensitive(音调敏感),比如在排序时,认为e, è, é, ê, ë是不同的;
  • ci表示case insensitive(大小写不敏感),即不区分大小写;
  • cs表示case sensitive(大小写敏感),表示区分大小写;
  • mysql8.0.1之后默认都是utf8mb4字符集以及utf8mb4_0900_ai_ci校对集(也就是排序时,不区分口音及大小写),在8.0.1之前默认校对集是utf8mb4_0900_general_ci。

查看当前数据库的字符集与校对集

SELECT @@character_set_database, @@collation_database; 

# 或者用这个,手打起来更方便
show create database <数据库名>;

查看mysql中的所有字符集

mysql> show variables like "%character%";
+--------------------------+------------------------------------------------------+
| Variable_name            | Value                                                |
+--------------------------+------------------------------------------------------+
| character_set_client     | utf8mb4                                              |
| character_set_connection | utf8mb4                                              |
| character_set_database   | utf8mb4                                              |
| character_set_filesystem | binary                                               |
| character_set_results    | utf8mb4                                              |
| character_set_server     | utf8mb4                                              |
| character_set_system     | utf8mb3                                              |
| character_sets_dir       | /usr/local/Cellar/mysql/8.0.29/share/mysql/charsets/ |
+--------------------------+------------------------------------------------------+
8 rows in set (0.00 sec)
+--------------------------+-----------------------------------------------------+
| 变量名                    | 含义                                                 |
+--------------------------+-----------------------------------------------------+
| character_set_client     | 客户端字符集                                          |
| character_set_connection | 连接字符集                                            |
| character_set_database   | 数据库字符集                                          |
| character_set_filesystem | 文件系统字符集                                         |
| character_set_results    | 查询结果字符集                                         |
| character_set_server     | 服务器字符集                                           |
| character_set_system     | 系统字符集                                            |
| character_sets_dir       | 字符集文件夹                                           |
+--------------------------+------------------------------------------------------+

其中character_set_system是指mysql用来存储标识符(identifiers)用的,比如存储数据库名、表名、字段名、索引名等用的字符集。

character_set_server则是mysql服务器内部操作字符集,比如查询表中的数据,暂存在内存中,这个数据也是要有字符集的。

MySQL中使用set names来设置字符集(单引号可省略不写)

SET NAMES 'utf8mb4';

相当于同时设置以下三个字符集

set character_set_client = utf8;
set character_set_results = utf8;
set character_set_connection = utf8;

如果你设置utf8,其实就是设置了utf8mb3,因为mb3是utf8默认的,所以就没把mb3写出来,即以下两个语句是等效的

SET NAMES 'utf8';
SET NAMES 'utf8mb3';

参考:
查看数据库、表的字符集
MySQL字符集及校对规则的理解

打赏

订阅评论
提醒
guest

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

0 评论
内联反馈
查看所有评论
0
希望看到您的想法,请您发表评论x

扫码在手机查看
iPhone请用自带相机扫
安卓用UC/QQ浏览器扫

MySQL字符集与校对集