我們都知道電腦實際儲存的是二進位資料,那是怎麼儲存字元的呢?
可以想像的就是必須讓字元映射成二進位資料(編碼)進而儲存。
因此我們必須制定哪些字元可以映射?映射的規則是什麼?
這就是字元集的功用。
我們先來看看幾個重要知識點
Unicode統一碼
由於我們所在的世界太大了,不同的地區訂出不同的字元集,包含的字元及編碼的規則都不一樣,導致混亂,因此才有了Unicode通一碼,它致力於解決這個問題,幾乎包含了世界上所有語言的字元。最初希望透過16位元編碼收錄所有字元,但礙於要讓所有軟體符合16位元編碼標準需耗費太大的成本,因此衍生出UTF-8(使用1-4個位元組來編碼)、UTF-16(使用2或4個位元組來編碼)、UTF-32(使用4個位元組來編碼)三種字元集,相同的字元在三種字元集內皆為相同的編碼,彼此兼容,此外也可兼容於ASCII字元集。
一個位元組就是xxxxxxxx,ex:10001111
ASCII字元集
總共收錄128個字元,因此使用1個位元組即可編碼,映射了控制字符(換行、換頁、刪除、退一格等)、通信字符(請求、收到通知、回應等)、大小寫英文字母、標點符號和阿拉伯數字。以中文字‘我’來說就沒有在ASCII裡面。
UTF8MB3及UTF8MB4字元集
由於使用的字元集(不同的最大位元組長)會影響到系統儲存與效能,MySQL工程師因此定義了UTF8MB3,它是閹割過的UTF-8字元集,只使用1-3個位元組來編碼以提升效能,在MySQL中UTF-8指的就是UTF8MB3。
而UTF8MB4就是原先正宗的的UTF-8字元集。
(補充:在MySQL8.0中最佳化了UTF8MB4的性能,將其設為預設的字元集,在下面我查詢本機MySQL字元集的時候可以看到)
再來相信大家一定對utf8_general_ci不陌生
那它到底是什麼東西呢?
它其實是一種校對規則,分成3個部分來看。
可以透過以下指令查詢目前伺服器使用什麼樣的字元集和校對規則。
mysql> show variables like 'character_set_server';
+----------------------+---------+
| Variable_name | Value |
+----------------------+---------+
| character_set_server | utf8mb4 |
+----------------------+---------+
1 row in set (0.15 sec)
mysql> show variables like 'collation_server';
+------------------+--------------------+
| Variable_name | Value |
+------------------+--------------------+
| collation_server | utf8mb4_0900_ai_ci |
+------------------+--------------------+
1 row in set (0.02 sec)
這邊可以發現MySQL8.0預設已使用UTF8MB4字元集
校對規則出現了0900,它是符合Unicode9.0規範的意思(Unicode規範也是不斷地在更新的)。
最後補充說明字元集與校對規則的階層與套用順序。
MySQL的階層為 伺服器 => 資料庫 => 表 => 列(欄位)
伺服器有自己的字元集與校對規則
資料庫也有自己的字元集與校對規則
表也有自己的字元集與校對規則
列(各個欄位)也有自己的字元集與校對規則
在創建資料庫時不指定字元集與校對規則,預設就是照伺服器的設定。
在創建表時不指定字元集與校對規則,預設就是照資料庫的設定。
在創建欄位時不指定字元集與校對規則,預設就是表的設定。
今日篇幅雖短但每個知識點都非常重要唷!
Take a break ~ 明日再戰