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:
- 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增加了對丹麥語的特殊排序支持。
補充:
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)
推薦使用
select * from pet where name = binary 'whistler';
這樣可以保證當前字段的索引依然有效,而
select * from pet where binary name = 'whistler';
會使索引失效。
參考:
http://zhongwei-leg.iteye.com/blog/899227(以上內容轉自此篇文章)
http://blog.sina.com.cn/s/blog_9707fac301016wxm.html
http://blog.csdn.net/haiross/article/details/51273593
http://www.jb51.net/article/40854.htm
http://blog.csdn.net/chenghuan1990/article/details/10078931
http://stackoverflow.com/questions/367711/what-is-the-best-collation-to-use-for-MySQL-with-php
http://dev.MySQL.com/doc/refman/5.0/en/charset-Unicode-sets.html
http://dev.MySQL.com/doc/refman/5.1/en/show-collation.html
http://dev.MySQL.com/doc/refman/5.1/en/charset-binary-op.html