可添加的检验规则类型
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 sjisCOLLATE sjis_japanese_ci); Query OK, 0 rows affected (0.01 sec) mysql>INSERT INTO t1VALUES ('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 gbkCOLLATE gbk_chinese_ci); Query OK, 0 rows affected (0.33 sec) mysql>INSERT INTO t1VALUES ('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 UTF8COLLATE utf8_general_ci); Query OK, 0 rows affected (0.01 sec) mysql>INSERT INTO t1VALUES ('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字符集”。
杂项校验
还有一些校验不属于任何先前的类别。