介绍 mysql 中的 character set 与 collation

赞赏 2017-07-26

使用 mysql 创建数据表的时候, 总免不了要涉及到 character set 和 collation 的概念, 之前不是很了解。
这两天不是很忙, 就自己整理了一下。


先来看看 character set 和 collation 的是什么?

&. character set, 即字符集。

我们常看到的 utf-8, GB2312, GB18030 都是相互独立的 character set. 即对 Unicode 的一套编码。

那么如何理解 unicode 与 utf-8, GB2312 的区别呢?

打个比方,你眼前有一个苹果,在英文里称之为 apple, 而在中文里称之为苹果。

苹果这个实体的概念就是 unicode , 而 utf-8, GB2312 可以认为就是不同语言对苹果的不同称谓,本质上都是在描述苹果这个物。


&. collation, 即比对方法。

用于指定数据集如何排序,以及字符串的比对规则。(这样说可能比较抽象,后面会详细解释。)


character set 与 collation 的关系

软件国际化是大势所趋, 所以 unicode 是国际化最佳的选择。当然为了提高性能,有些情况下还是使用 latin1 比较好。

mysql 有两个支持 unicode 的 character set:

1. ucs2: 使用 16 bits 来表示一个 unicode 字符。

2. utf8: 使用 1~3 bytes 来表示一个 unicode 字符。

选择哪个 character set 视情况而定,例如 utf8 表示 latin 字符只需要一个字节,所以当用户数据大部分为英文等拉丁字符时,使用 utf8 比较节省数据库的存储空间。据说 SQL Server 采用的是 ucs2, 我表示怀疑。  

每个 character set 会对应一定数量的 collation. 查看方法是在 mysql 的 console 下输入:

mysql> show collation;

我们会看到这样的结果:


collation 名字的规则可以归纳为这两类:

1. <character set>_<language/other>_<ci/cs>

2. <character set>_bin


例如:

utf8_danish_ci


ci 是 case insensitive 的缩写, cs 是 case sensitive 的缩写。即,指定大小写是否敏感。

奇怪的是 utf8 字符集对应的 collation 居然没有一个是 cs 的。



那么 utf8_general_ci, utf8_unicode_ci, utf8_danish_ci 有什么区别? 他们各自存在的意义又是什么?


同一个 character set 的不同 collation 的区别在于排序、字符对比的准确度(相同两个字符在不同国家的语言中的排序规则可能是不同的)以及性能。


例如:

utf8_general_ci 在排序的准确度上要逊于 utf8_unicode_ci, 当然,对于英语用户应该没有什么区别。但性能上(排序以及比对速度)要略优于 utf8_unicode_ci. 例如前者没有对德语中

ß = ss

的支持。

而 utf8_danish_ci 相比 utf8_unicode_ci 增加了对丹麦语的特殊排序支持。


补充:

1. 当表的 character set 是 latin1 时,若字段类型为 nvarchar, 则字段的字符集自动变为 utf8.

可见 database character set, table character set, field character set 可逐级覆盖。


2. 在 ci 的 collation 下,如何在比对时区分大小写:

写道 

mysql> select * from pet;
+----------+-------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+----------+-------+---------+------+------------+-------+
| Whistler | Gwen | bird | NULL | 1997-12-09 | NULL |
| whistler | Gwen | bird | NULL | 1988-09-25 | NULL |
+----------+-------+---------+------+------------+-------+
2 rows in set (0.00 sec)

mysql> select * from pet where name = 'whistler';
+----------+-------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+----------+-------+---------+------+------------+-------+
| Whistler | Gwen | bird | NULL | 1997-12-09 | NULL |
| whistler | Gwen | bird | NULL | 1988-09-25 | NULL |
+----------+-------+---------+------+------------+-------+
2 rows in set (0.00 sec)

mysql> select * from pet where binary name = 'whistler';
+----------+-------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+----------+-------+---------+------+------------+-------+
| whistler | Gwen | bird | NULL | 1988-09-25 | NULL |
+----------+-------+---------+------+------------+-------+
1 row in set (0.00 sec)

mysql> select * from pet where name = binary 'whistler';
+----------+-------+---------+------+------------+-------+
| name | owner | species | sex | birth | death |
+----------+-------+---------+------+------------+-------+
| whistler | Gwen | bird | NULL | 1988-09-25 | NULL |
+----------+-------+---------+------+------------+-------+
1 row in set (0.00 sec)


推荐使用

mysql> select * from pet where name = binary 'whistler';

这样可以保证当前字段的索引依然有效, 而

mysql> select * from pet where binary name = 'whistler';

会使索引失效。


参考列表:

1. What is the best collation to use for mysql with php.

http://stackoverflow.com/questions/367711/what-is-the-best-collation-to-use-for-mysql-with-php


2. Unicode Character Sets

http://dev.mysql.com/doc/refman/5.0/en/charset-unicode-sets.html


3. Show Collation Syntax

http://dev.mysql.com/doc/refman/5.1/en/show-collation.html


4. The Binary Operator

http://dev.mysql.com/doc/refman/5.1/en/charset-binary-op.html

登陆后阅读全文
阅读 1503 赞赏 0 有用 3 没用 0 收藏 0 分享

   



0 条留言

山君的头像

山君

斯人若彩虹,遇上方知有

相关文章

Ubuntu安装MySQL提示Depends: mysql-server-5.5 but it is not going

Linux 系统下 MySQL 如何开启慢查询?

MySQL 上传报错#1064-You have an error in your SQL syntax

MySQL中如何查看慢 SQL 的日志?slowlog

mysql-bin.00000* 文件误删删除导致mysql启动不起来

mysql表名order,用命令行报错

Linux screen 提示:There is no screen to be resumed matching

或许你不知道的10条SQL技巧((sql 优化 sql索引优化))

Linux 如何安装 VNC Server图形化?

Windows Server 2012 R2 或 2016 无法安装 .Net 3.5.1

有料推荐

这世界欠我一个这样的老公!

高校学生模仿“世界名画”摆拍,可以说是戏精本精了

iPhone X 跌破发行价,苏宁200亿入股恒大 | 财经日日评

果然是高手!这次在日本,特朗普竹杠敲得不是一般狠

资深黄牛现身说法:iPhone X价格秒变不停,就像炒股一样

长一样的双胞胎也能识别?蚂蚁金服发布「眼纹识别」技术

苏联是怎么被阿富汗拖垮的?

美团或入局「分时租赁」共享汽车,王兴要大笔投入「泛出行」领域了? | 36氪独家

你或许被“一盘番茄炒蛋”刷屏了,但有人辛酸,有人质疑

iPhone X发售前夜,黄牛与苹果公司的不安

他的文章

百万司机车货匹配项目 从 300qps 至 3000qps 的优化之路

PostgreSQL 9.6.0 在线中文手册下载

postgresSQL可视化客户端Navicat for PostgreSQL

全文搜索引擎 ElasticSearch 入门教程

一波 navicat在线手册来袭!

微信含emoji表情昵称入库失败:HY000,1366, Incorrect string value

postman share Collection Get link出错

介绍 mysql 中的 character set 与 collation

介绍一款linux多线程下载工具axel(用以替代wget)

mysql命令行如何一次添加添加多个字段(列) 索引?

手机扫一扫
分享文章