• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 可添加的检验规则类型

    MySQL实现了几种类型的校验规则:

    8位字符集的简单校验

    这种校验规则是使用256个权重的数组实现的,该数组定义了从字符代码到权重的一对一映射。latin1_swedish_ci是一个例子。这是不区分大小写的校验规则,因此字符的大写和小写版本具有相同的权重,并且它们比较时相等。

    mysql> SET NAMES 'latin1' COLLATE 'latin1_swedish_ci';
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> SELECT HEX(WEIGHT_STRING('a')), HEX(WEIGHT_STRING('A'));
    +-------------------------	+-------------------------	+
    | HEX(WEIGHT_STRING('a')) 	| HEX(WEIGHT_STRING('A')) 	|
    +-------------------------	+-------------------------	+
    | 41                      	| 41                      	|
    +-------------------------	+-------------------------	+
    1 row in set (0.01 sec)
    
    mysql> SELECT 'a' = 'A';
    +-----------	+
    | 'a' = 'A' 	|
    +-----------	+
    |         1 	|
    +-----------	+
    1 row in set (0.12 sec)
    

    有关实现的说明,请参见“向8位字符集添加简单校验”。

    8位字符集的复杂校验

    此类校验是使用C源文件中的函数实现的,该函数定义了如何对字符进行校验,如“添加字符集”中所述。

    非Unicode多字节字符集的校验规则

    对于这种类型的校验规则,对8位(单字节)和多字节字符的处理方式有所不同。对于8位字符,字符代码以不区分大小写的方式映射到权重。(例如,单字节字符'a''A'两个字符的权重均为0x41。)对于多字节字符,字符代码和权重之间存在两种关系:

    • 权重等于字符代码。sjis_japanese_ci是这种校验规则的一个示例。多字节字符'ぢ'的字符代码为0x82C0,权重也为0x82C0

      mysql> CREATE TABLE t1
             (c1 VARCHAR(2) CHARACTER SET sjis COLLATE sjis_japanese_ci);
      Query OK, 0 rows affected (0.01 sec)
      
      mysql> INSERT INTO t1 VALUES ('a'),('A'),(0x82C0);
      Query OK, 3 rows affected (0.00 sec)
      Records: 3  Duplicates: 0  Warnings: 0
      
      mysql> SELECT c1, HEX(c1), HEX(WEIGHT_STRING(c1)) FROM t1;
      +------	+---------	+------------------------	+
      | c1   	| HEX(c1) 	| HEX(WEIGHT_STRING(c1)) 	|
      +------	+---------	+------------------------	+
      | a    	| 61      	| 41                     	|
      | A    	| 41      	| 41                     	|
      | ぢ    	| 82C0    	| 82C0                   	|
      +------	+---------	+------------------------	+
      3 rows in set (0.00 sec)
      
    • 字符代码一对一地映射到权重,但是代码不一定等于权重。gbk_chinese_ci是这种校验规则的一个示例。多字节字符'膰'的字符代码为,0x81B0但权重为0xC286

      mysql> CREATE TABLE t1
             (c1 VARCHAR(2) CHARACTER SET gbk COLLATE gbk_chinese_ci);
      Query OK, 0 rows affected (0.33 sec)
      
      mysql> INSERT INTO t1 VALUES ('a'),('A'),(0x81B0);
      Query OK, 3 rows affected (0.00 sec)
      Records: 3  Duplicates: 0  Warnings: 0
      
      mysql> SELECT c1, HEX(c1), HEX(WEIGHT_STRING(c1)) FROM t1;
      +------	+---------	+------------------------	+
      | c1   	| HEX(c1) 	| HEX(WEIGHT_STRING(c1)) 	|
      +------	+---------	+------------------------	+
      | a    	| 61      	| 41                     	|
      | A    	| 41      	| 41                     	|
      | 膰    	| 81B0    	| C286                   	|
      +------	+---------	+------------------------	+
      3 rows in set (0.00 sec)
      

    有关实现的说明,请参见“添加字符集和校验规则”。

    Unicode多字节字符集的校验规则

    这些校验中的一些校验基于Unicode校验算法(UCA),而其他则不基于。

    非UCA校验具有从字符代码到权重的一对一映射。在MySQL中,此类校验不区分大小写和变音。utf8_general_ci是一个例子:'a''A''À',和'á'每个都具有不同的字符代码,但是都具有的重量0x0041和比较结果为相等。

    mysql> SET NAMES 'utf8' COLLATE 'utf8_general_ci';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> CREATE TABLE t1
           (c1 CHAR(1) CHARACTER SET UTF8 COLLATE utf8_general_ci);
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> INSERT INTO t1 VALUES ('a'),('A'),('À'),('á');
    Query OK, 4 rows affected (0.00 sec)
    Records: 4  Duplicates: 0  Warnings: 0
    
    mysql> SELECT c1, HEX(c1), HEX(WEIGHT_STRING(c1)) FROM t1;
    +------	+---------	+------------------------	+
    | c1   	| HEX(c1) 	| HEX(WEIGHT_STRING(c1)) 	|
    +------	+---------	+------------------------	+
    | a    	| 61      	| 0041                   	|
    | A    	| 41      	| 0041                   	|
    | À    	| C380    	| 0041                   	|
    | á    	| C3A1    	| 0041                   	|
    +------	+---------	+------------------------	+
    4 rows in set (0.00 sec)
    

    MySQL中基于UCA的校验具有以下属性:

    • 如果一个字符有权重,则每个权重使用2个字节(16位)。
    • 角色的权重可能为零(或权重为空)。在这种情况下,角色是可忽略的。示例:“ U + 0000 NULL”没有权重并且可忽略。
    • 一个角色可能有一个分量。示例:'a'权重为0x0E33

      mysql> SET NAMES 'utf8' COLLATE 'utf8_unicode_ci';
      Query OK, 0 rows affected (0.05 sec)
      
      mysql> SELECT HEX('a'), HEX(WEIGHT_STRING('a'));
      +----------	+-------------------------	+
      | HEX('a') 	| HEX(WEIGHT_STRING('a')) 	|
      +----------	+-------------------------	+
      | 61       	| 0E33                    	|
      +----------	+-------------------------	+
      1 row in set (0.02 sec)
      
    • 一个角色可能有很多权重。这是一个扩展。示例:德语字母'ß'(SZ连字或SHARP S)的权重为0x0FEA0FEA

      mysql> SET NAMES 'utf8' COLLATE 'utf8_unicode_ci';
      Query OK, 0 rows affected (0.11 sec)
      
      mysql> SELECT HEX('ß'), HEX(WEIGHT_STRING('ß'));
      +-----------	+--------------------------	+
      | HEX('ß')  	| HEX(WEIGHT_STRING('ß'))  	|
      +-----------	+--------------------------	+
      | C39F      	| 0FEA0FEA                 	|
      +-----------	+--------------------------	+
      1 row in set (0.00 sec)
      
    • 许多字符可能具有一个权重。这是收缩。示例:'ch'是捷克语中的单个字母,权重为0x0EE2

      mysql> SET NAMES 'utf8' COLLATE 'utf8_czech_ci';
      Query OK, 0 rows affected (0.09 sec)
      
      mysql> SELECT HEX('ch'), HEX(WEIGHT_STRING('ch'));
      +-----------	+--------------------------	+
      | HEX('ch') 	| HEX(WEIGHT_STRING('ch')) 	|
      +-----------	+--------------------------	+
      | 6368      	| 0EE2                     	|
      +-----------	+--------------------------	+
      1 row in set (0.00 sec)
      

    多字符到多权重的映射也是可能的(这是扩展的收缩),但是MySQL不支持。

    有关非UCA校验的实现说明,请参见“添加字符集和校验规则”。有关UCA校验,请参见“将UCA检验添加到Unicode字符集”。

    杂项校验

    还有一些校验不属于任何先前的类别。