Mysql字符集

引言

今天遇到一个问题,我们在设计一个User表时,用户名需要保证唯一,且不区分大小写。开始设计是两个字段user_name(原始值),user_name_upcase(转大写值),这两个字段上都唯一索引。直到有位同学告诉我们可通过一个字段搞定,学习了,学习了。

字符集&校对规则

MySQL提供了字符集(character set)支持,可以使用各种字符集存储数据并根据各种校对规则(collations)进行比较。可以在server, database, table, column 指定字符集和校对规则。

什么是字符集?

简单来说,字符集就是符号和编码的集合。举个例子,假设我们有四个字母A,B,a,b。我们给每一个字符一个数值:A=0,B=1,a=2,b=3。A就是符号,数值0就是A的编码,字符和数字的编码规则的合集就是字符集。

什么是校对规则?

简单来说,是字符之间的比较规则,决定字符相等和排序等。接着上面的例子,比较符号A,B的大小,我们可以简单的认为A < B,因为0 < 1,我们称这种规则为binary collation。但是,当我们需要认为A=a,B=b 即忽略大小写时,我们成为case-insensitive collation。

读懂字符集

查看当前数据库支持哪些字符集(数据库版本8.0)

mysql> SHOW CHARACTER SET;
+----------+---------------------------------+---------------------+--------+
| Charset  | Description                     | Default collation   | Maxlen |
+----------+---------------------------------+---------------------+--------+
| big5     | Big5 Traditional Chinese        | big5_chinese_ci     |      2 |
| binary   | Binary pseudo charset           | binary              |      1 |
...
| latin1   | cp1252 West European            | latin1_swedish_ci   |      1 |
...
| ucs2     | UCS-2 Unicode                   | ucs2_general_ci     |      2 |
...
| utf8     | UTF-8 Unicode                   | utf8_general_ci     |      3 |
| utf8mb4  | UTF-8 Unicode                   | utf8mb4_0900_ai_ci  |      4 |
...

utf8 这个是mysql历史遗留的一个utf8编码字符集,最大长度是3个字节,而真正的utf8编码是最长4个字节。

utf8mb4 真正的utf8编码字符集,可以完美支持所有的utf8编码,推荐使用。

查看utf8mb4支持哪些校对规则

mysql> SHOW COLLATION WHERE Charset = 'utf8mb4';
+----------------------------+---------+-----+---------+----------+---------+---------------+
| Collation                  | Charset | Id  | Default | Compiled | Sortlen | Pad_attribute |
+----------------------------+---------+-----+---------+----------+---------+---------------+
| utf8mb4_0900_ai_ci         | utf8mb4 | 255 | Yes     | Yes      |       0 | NO PAD        |
| utf8mb4_bin                | utf8mb4 |  46 |         | Yes      |       1 | PAD SPACE     |
| utf8mb4_general_ci         | utf8mb4 |  45 |         | Yes      |       1 | PAD SPACE     |
....

校对规则名称后缀含义表

后缀 含义 说明
_ai Accent-insensitive 重音不敏感,多见于德语
_as Accent-sensitive 重音敏感
_ci Case-insensitive 大小写不敏感
_cs Case-sensitive 大小写敏感
_ks Kana-sensitive
_bin Binary 二进制比较

使用字符集

例如,我们创建如下表


CREATE TABLE `test_charset` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `text_bin` VARCHAR(45) COLLATE UTF8MB4_BIN NOT NULL,
    `text_ci` VARCHAR(45) COLLATE UTF8MB4_GENERAL_CI DEFAULT NULL,
    PRIMARY KEY (`id`),
    UNIQUE KEY `uk_text_ci` (`text_ci`)
)  ENGINE=INNODB AUTO_INCREMENT=10 DEFAULT CHARSET=UTF8MB4 COLLATE = UTF8MB4_BIN;

实际上,可以在服务器,数据库,表,字段上使用不同的字符集和校对规则,针对我们这种忽略大小写的需求,可以单独指定该列的校对规则为UTF8MB4_GENERAL_CI。

但是,没有特殊情况,建议还是一个数据库统一用一套配置,多了你自己不心慌吗?

UTF8MB4_GENERAL_CI 实现的源码分析

很好奇mysql里面到底是怎么处理忽略大小写这件事情的,这个就得看下mysql源码了,mysql源码地址:https://github.com/mysql/mysql-server,直接到最后ctype-utf8.cc这个源码文件。

1.png
2.png

通过mysql的源码,我们可以看到mysql服务内部会都转成小写进行比较。

总结

mysql包含的东西太多,多学习吧。

参考文档

https://github.com/mysql/mysql-server/blob/8.0/strings/ctype-utf8.cc
https://dev.mysql.com/doc/refman/8.0/en/charset.html
https://dev.mysql.com/doc/refman/8.0/en/charset-collation-names.html
https://dev.mysql.com/doc/refman/8.0/en/charset-mysql.html

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,049评论 5 473
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,478评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,109评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,097评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,115评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,280评论 1 279
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,748评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,398评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,553评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,440评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,487评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,176评论 3 317
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,750评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,821评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,049评论 1 257
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,559评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,150评论 2 341

推荐阅读更多精彩内容