MySQL中character set與collation的理解(轉)

character set和collation的是什麼?mysql

character set即字符集sql

咱們常看到的UTF-八、GB23十二、GB18030都是相互獨立的character set。即對Unicode的一套編碼。數據庫

那麼如何理解Unicode與UTF-八、GB2312的區別呢?app

打個比方,你眼前有一個蘋果,在英文裏稱之爲apple,而在中文裏稱之爲蘋果。性能

蘋果這個實體的概念就是Unicode,而UTF-8,GB2312能夠認爲就是不一樣語言對蘋果的不一樣稱謂,本質上都是在描述蘋果這個物。編碼

collation即比對方法spa

用於指定數據集如何排序,以及字符串的比對規則。3d

character set與collation的關係code

軟件國際化是大勢所趨,因此Unicode是國際化最佳的選擇。固然爲了提升性能,有些狀況下仍是使用latin1比較好。 blog

MySQL有兩個支持Unicode的character set:

  • ucs2:使用16bits來表示一個Unicode字符。
  • utf8:使用1~3bytes來表示一個Unicode字符。

選擇哪一個character set視狀況而定,例如utf8表示latin字符只須要一個字節,因此當用戶數據大部分爲英文等拉丁字符時,使用utf8比較節省數據庫的存儲空間。聽說SQL Server採用的是ucs2。

每一個character set會對應必定數量的collation。查看方法是在MySQL的Console下輸入:

show collation;

咱們會看到這樣的結果:

collation名字的規則能夠概括爲這兩類:

  • <character set>_<language/other>_<ci/cs>
  • <character set>_bin

例如:

utf8_danish_ci

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

utf8_bin是將字符串中的每個字符用二進制數據存儲,區分大小寫。

奇怪的是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增長了對丹麥語的特殊排序支持。 

補充:

一、當表的character set是latin1時,若字段類型爲nvarchar,則字段的字符集自動變爲utf8。可見database character set,table character set,field character set可逐級覆蓋。

二、在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)
複製代碼

推薦使用

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

這樣能夠保證當前字段的索引依然有效,而

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

會使索引失效。

相關文章
相關標籤/搜索