1.1.1. 02.字符集与比较规则


1. 字符集简介

字符集就是建立字符与计算机使用的二进制之间的映射关系。

例如,采用1个字节编码一个字符的形式(一个字节有 8 位二进制),字符和字节的映射关系如下:

'a' -> 00000001 (十六进制:0x01) 'b' -> 00000010 (十六进制:0x02) 'A' -> 00000011 (十六进制:0x03) 'B' -> 00000100 (十六进制:0x04)

2. 比较规则简介

比较规则,就是如何比较两个字符的大小指定的规则。比方说字符'a'的编码为0x01,字符'b'的编码为0x02,所以'a'小于'b'。

比较规则有多种,满足不同需求。

比较规则的作用通常体现比较字符串大小的表达式以及对某个字符串列进行排序中。

一些重要的字符集
  • ASCII 字符集 共有 128 个字符,包括空格、标点符号、数字、大小写字母和一些不可见字符。由于总共才 128 个,所以是一个字节。
  • ISO 8859-1 字符集 共有 256 个字符,在 ASCII 上扩充了128个西欧常用字符(包括德法两国的字母)。也是一个字节。
  • GB2312字符集

    • 收录了汉字、拉丁字母、希腊字母、平假名片假名、俄语西里尔字母。兼容 ASCII 字符集。
    • 如果该字符在 ASCII 字符集中,则采用 1 字节
    • 否则采用 2 字节
  • GBK 字符集 在 GB2312 字符集上做了扩充。

  • UTF8 字符集 收录了地球上所有的字符,而且还在扩充。

Mysql 中的字符集和比较规则

MySQL中的 utf8 和 utf8mb4
  • utf8 = utf8mb3 : 阉割过的 utf8 字符集,只使用 1-3 个字节表示字符。
  • utf8mb4:正宗的 utf8 字符集,使用 1-4 个字节表示字符。
字符集的查看

通过 SHOW (CHARACTER SET|CHARSET) [LIKE 匹配模式]; 来查看。

mysql> SHOW CHARSET;
+----------+---------------------------------+---------------------+--------+
| Charset  | Description                     | Default collation   | Maxlen |
+----------+---------------------------------+---------------------+--------+
| big5     | Big5 Traditional Chinese        | big5_chinese_ci     |      2 |
...
| latin1   | cp1252 West European            | latin1_swedish_ci   |      1 |
| latin2   | ISO 8859-2 Central European     | latin2_general_ci   |      1 |
...
| ascii    | US ASCII                        | ascii_general_ci    |      1 |
...
| gb2312   | GB2312 Simplified Chinese       | gb2312_chinese_ci   |      2 |
...
| gbk      | GBK Simplified Chinese          | gbk_chinese_ci      |      2 |
| latin5   | ISO 8859-9 Turkish              | latin5_turkish_ci   |      1 |
...
| utf8     | UTF-8 Unicode                   | utf8_general_ci     |      3 |
| ucs2     | UCS-2 Unicode                   | ucs2_general_ci     |      2 |
...
| latin7   | ISO 8859-13 Baltic              | latin7_general_ci   |      1 |
| utf8mb4  | UTF-8 Unicode                   | utf8mb4_general_ci  |      4 |
| utf16    | UTF-16 Unicode                  | utf16_general_ci    |      4 |
| utf16le  | UTF-16LE Unicode                | utf16le_general_ci  |      4 |
...
| utf32    | UTF-32 Unicode                  | utf32_general_ci    |      4 |
| binary   | Binary pseudo charset           | binary              |      1 |
...
| gb18030  | China National Standard GB18030 | gb18030_chinese_ci  |      4 |
+----------+---------------------------------+---------------------+--------+
41 rows in set (0.01 sec)

mysql 总共有 41 个字符集,其中 default collation 是默认比较规则,maxlen 表示一个字节的最大字节长度。

需要记住

字符集名称 Maxlen
ascii 1
latin1 1
gb2312 2
gbk 2
utf8 3
utf8mb4 4
查看比较规则

通过 SHOW COLLATION [LIKE 匹配模式]; 来查看

mysql> SHOW COLLATION LIKE 'utf8\_%';
+--------------------------+---------+-----+---------+----------+---------+
| Collation                | Charset | Id  | Default | Compiled | Sortlen |
+--------------------------+---------+-----+---------+----------+---------+
| utf8_general_ci          | utf8    |  33 | Yes     | Yes      |       1 |
| utf8_bin                 | utf8    |  83 |         | Yes      |       1 |
| utf8_unicode_ci          | utf8    | 192 |         | Yes      |       8 |
| utf8_icelandic_ci        | utf8    | 193 |         | Yes      |       8 |
| utf8_latvian_ci          | utf8    | 194 |         | Yes      |       8 |
| utf8_romanian_ci         | utf8    | 195 |         | Yes      |       8 |
| utf8_slovenian_ci        | utf8    | 196 |         | Yes      |       8 |
| utf8_polish_ci           | utf8    | 197 |         | Yes      |       8 |
| utf8_estonian_ci         | utf8    | 198 |         | Yes      |       8 |
| utf8_spanish_ci          | utf8    | 199 |         | Yes      |       8 |
| utf8_swedish_ci          | utf8    | 200 |         | Yes      |       8 |
| utf8_turkish_ci          | utf8    | 201 |         | Yes      |       8 |
| utf8_czech_ci            | utf8    | 202 |         | Yes      |       8 |
| utf8_danish_ci           | utf8    | 203 |         | Yes      |       8 |
| utf8_lithuanian_ci       | utf8    | 204 |         | Yes      |       8 |
| utf8_slovak_ci           | utf8    | 205 |         | Yes      |       8 |
| utf8_spanish2_ci         | utf8    | 206 |         | Yes      |       8 |
| utf8_roman_ci            | utf8    | 207 |         | Yes      |       8 |
| utf8_persian_ci          | utf8    | 208 |         | Yes      |       8 |
| utf8_esperanto_ci        | utf8    | 209 |         | Yes      |       8 |
| utf8_hungarian_ci        | utf8    | 210 |         | Yes      |       8 |
| utf8_sinhala_ci          | utf8    | 211 |         | Yes      |       8 |
| utf8_german2_ci          | utf8    | 212 |         | Yes      |       8 |
| utf8_croatian_ci         | utf8    | 213 |         | Yes      |       8 |
| utf8_unicode_520_ci      | utf8    | 214 |         | Yes      |       8 |
| utf8_vietnamese_ci       | utf8    | 215 |         | Yes      |       8 |
| utf8_general_mysql500_ci | utf8    | 223 |         | Yes      |       1 |
+--------------------------+---------+-----+---------+----------+---------+
27 rows in set (0.00 sec)

可以看到这是 utf8 的比较规则,有几个特点

  • 都以 utf8_ 开头
  • 后面紧跟的是比较规则主要作用于哪种语言,比如utf8_polish_ci表示以波兰语的规则比较,utf8_spanish_ci是以西班牙语的规则比较,utf8_general_ci是一种通用的比较规则。
  • 后缀表示是否区分语言中的重音、大小写等:
后缀 英文释义 描述
_ai accent insensitive 不区分重音
_as accent sensitive 区分重音
_ci case insensitive 不区分大小写
_cs case sensitive 区分大小写
_bin binary 以二进制方式比较
比较规则的应用

比较规则共有 4 个级别:

  • 服务器级别
    • character_set_server 服务器级别的字符集
    • collation_server 服务器级别的比较规则
    • 这两个值在配置文件中修改。
  • 数据库级别

    • character_set_database 当前数据库的字符集
    • collation_database 当前数据库的比较规则

      CREATE DATABASE 数据库名
        [[DEFAULT] CHARACTER SET 字符集名称]
        [[DEFAULT] COLLATE 比较规则名称];
      
      ALTER DATABASE 数据库名
        [[DEFAULT] CHARACTER SET 字符集名称]
        [[DEFAULT] COLLATE 比较规则名称];
      
  • 表级别

       CREATE TABLE 表名 (列的信息)
          [[DEFAULT] CHARACTER SET 字符集名称]
          [COLLATE 比较规则名称]]
    
      ALTER TABLE 表名
          [[DEFAULT] CHARACTER SET 字符集名称]
          [COLLATE 比较规则名称]
    
  • 行级别

      REATE TABLE 表名(
          列名 字符串类型 [CHARACTER SET 字符集名称] [COLLATE 比较规则名称],
          其他列...
      );
    
      ALTER TABLE 表名 MODIFY 列名 字符串类型 [CHARACTER SET 字符集名称] [COLLATE 比较规则名称];
    

只修改字符集或比较规则:

  • 只修改字符集,比较规则变为修改后的字符集默认的比较规则。
  • 只修改比较规则,字符集变为修改后的比较规则对应的字符集。

字符集与比较规则的关系:

  • 如果创建时没有显示指定字符集和比较关系,则默认使用上一级的字符集与比较规则。行->表->库->服务器。

#

客户端和服务器中的字符集

如果客户端与服务器中的编码规则不一致,则会导致“乱码”。 客户端请求服务器,服务器处理并返回给客户端,这个过程中伴随多次字符集的转换。用到了三个系统变量

系统变量 描述
character_set_client 服务器解码请求时使用的字符集
character_set_connection 服务器运行过程中使用的字符集
character_set_results 服务器向客户端返回数据时使用的字符集

字符串转换过程

  • 服务器认为客户端传的请求是以 character_set_client 来编码的,如果不一致,则无法请求。
  • 服务器把得到的结果通过 character_set_results 来编码回传给客户端,如果不一致则乱码。
  • 所以,为了保证一致性,这三个系统变量通常统一设置成一个字符集。
    • SET character_set_client = 字符集名;
    • SET character_set_connection = 字符集名;
    • SET character_set_results = 字符集名;
Copyright © Kagami丶 2019 all right reserved,powered by Gitbook该文件修订时间: 2019-12-10 21:47:13

results matching ""

    No results matching ""