mysql 字符集和字符校对规则

天地有正气,杂然赋流形

字符集和字符集较对规则

字符集 character: 定义mysql存储字符串的方式
较对规则 collation:定义mysql比较字符串的方式

字符集和较对规则是1对多的关系;我们可以使用 SHOW COLLATION LIKE 'utf8mb4%' 来得到具体字符集对应的所有较对规则。

我们来看常用的utf8mb4字符集对应的所有较对规则

utf8mb4_general_ci  utf8mb4 45  Yes Yes 1
utf8mb4_bin utf8mb4 46      Yes 1
utf8mb4_unicode_ci  utf8mb4 224     Yes 8
utf8mb4_icelandic_ci    utf8mb4 225     Yes 8
utf8mb4_latvian_ci  utf8mb4 226     Yes 8
utf8mb4_romanian_ci utf8mb4 227     Yes 8
utf8mb4_slovenian_ci    utf8mb4 228     Yes 8
utf8mb4_polish_ci   utf8mb4 229     Yes 8
utf8mb4_estonian_ci utf8mb4 230     Yes 8
utf8mb4_spanish_ci  utf8mb4 231     Yes 8
utf8mb4_swedish_ci  utf8mb4 232     Yes 8
utf8mb4_turkish_ci  utf8mb4 233     Yes 8
utf8mb4_czech_ci    utf8mb4 234     Yes 8
utf8mb4_danish_ci   utf8mb4 235     Yes 8
utf8mb4_lithuanian_ci   utf8mb4 236     Yes 8
utf8mb4_slovak_ci   utf8mb4 237     Yes 8
utf8mb4_spanish2_ci utf8mb4 238     Yes 8
utf8mb4_roman_ci    utf8mb4 239     Yes 8
utf8mb4_persian_ci  utf8mb4 240     Yes 8
utf8mb4_esperanto_ci    utf8mb4 241     Yes 8
utf8mb4_hungarian_ci    utf8mb4 242     Yes 8
utf8mb4_sinhala_ci  utf8mb4 243     Yes 8
utf8mb4_german2_ci  utf8mb4 244     Yes 8
utf8mb4_croatian_ci utf8mb4 245     Yes 8
utf8mb4_unicode_520_ci  utf8mb4 246     Yes 8
utf8mb4_vietnamese_ci   utf8mb4 247     Yes 8

其中,utf8mb4_general_ci是utf8mb4的默认较对规则;而utf8mb4_unicode_ci 是基于标准的Unicode来排序和比较,能够在各种语言之间精确排序;大多数情况下我们不需要使用到这种根据具体语言的精确排序,所以推荐使用默认的utf8mb4_general_ci,因为它在比较和排序的时候更快。

较对规则命名约定:

_ci 大小写不敏感
_cs 大小写敏感
_bin 二元比较时是基于字符编码的值而与language无关

我们应该如何对较对规则进行选择?

从两个方面入手:

1、需要什么样的排序方式。是按语言(a,b,c)字母排序,还是按字符编码排序;

我们来看utf8mb4_bin和utf8mb4_general_ci在排序上的区别:
创建一个表,并导入一些数据

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for testcode
-- ----------------------------
DROP TABLE IF EXISTS `testcode`;
CREATE TABLE `testcode`  (
  `id` int(11) NOT NULL,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of testcode
-- ----------------------------
INSERT INTO `testcode` VALUES (1, 'd');
INSERT INTO `testcode` VALUES (2, 'b');
INSERT INTO `testcode` VALUES (3, 'a');
INSERT INTO `testcode` VALUES (4, 'c');
INSERT INTO `testcode` VALUES (5, '`');

SET FOREIGN_KEY_CHECKS = 1;

现在使用 SELECT * FROM testcode ORDER BY name 对name进行排序查询;可以看到`符号在最后。

image.png

将name字段的比较规则修改为 utf8mb4_bin ;再次进行查询:

可以看到这次`符号在第一位,处在a之前;


image.png

原因很简单, utf8mb4_bin 是按字符编码进行排序的。而`符号的ASCII码的十进制值为96,a为97;刚好在a的前面

image.png

2、是否区分大小写
我们在上面实验的基础上将小写b改为大写的B,此时的较对规则是默认的 utf8mb4_general_ci ;显然,这里的B就被看做为b了。即大小写不敏感


image.png

然后将较对规则改为 utf8mb4_bin。再看看情况,这时B出现在第一行了。因为B的ASCII码是66,而b是98


image.png

mysql中如何设置字符集和较对规则?

mysql的可以设置 服务器、库、表、列 级别的字符集和较对规则;

但是要注意,虽说有这么几个设置字符集的地方。其实最终落脚点还是在列级别之上。像其它三个设置的地方只是提供了一种若没有指定,则继承之的功能;列继承表,表继承库,库继承服务器;只要我们显式的指定列的字符集和较对方式即可,这样就不用去管其它三个地方了。

还有一个额外的需要注意设置字符集和较对规则的地方:
连接字符集和较对规则

服务器级别

查看当前的服务器级别的字符集和字符较对规则

SHOW VARIABLES LIKE 'character_set_server'
SHOW VARIABLES LIKE 'collation_server'
image.png

在配置文件中指定服务器级别的字符编码和较对规则,当然不指定较对规则就使用字符集的默认较对规则

[mysqld]
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
库级别

查询当前库的字符集和较对规则

SHOW VARIABLES LIKE 'character_set_database'
SHOW VARIABLES LIKE 'collation_database'
表级别

使用show create table 查看

mysql> show create table testcode;
+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table    | Create Table                                                                                                                                                                                                         |
+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| testcode | CREATE TABLE `testcode` (
  `id` int(11) NOT NULL,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci |
+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.03 sec)
字段级别
ALTER TABLE `test`.`testcode` 
MODIFY COLUMN `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `id`;
image.png
连接字符集和较对规则

客户端在连接mysql服务时,必须将字符集统一:
character_set_client(客户端)、character_set_connection(连接)、character_set_results(返回结果) 三者必须统一

我们可以在配置文件中添加:

[mysqld]
init_connect='SET NAMES utf8mb4'

你可能感兴趣的:(mysql 字符集和字符校对规则)