MySQL使用時,有一件很痛苦的事情確定是結果亂碼。將編碼格式都設置爲UTF8能夠解決這個問題,咱們今天來講下爲何要這麼設置,以及怎麼設置。html
在編程語言中,咱們爲了防止中文亂碼,會使用unicode
對中文字符作處理,而爲了下降網絡帶寬和節省存儲空間,咱們使用UTF8進行編碼。對這二者有什麼不一樣不夠了解的同窗,能夠參考Unicode字符集和UTF8編碼編碼的前世此生這篇文章。mysql
一樣在MySQL中,咱們也會有這樣的處理,咱們能夠查看當前數據庫設置的編碼方式(字符集):sql
mysql> show variables like '%char%'; +--------------------------+----------------------------------+ | Variable_name | Value | +--------------------------+----------------------------------+ | character_set_client | latin1 | | character_set_connection | latin1 | | character_set_database | latin1 | | character_set_filesystem | binary | | character_set_results | latin1 | | character_set_server | latin1 | | character_set_system | utf8 | | character_sets_dir | /usr/local/mysql/share/charsets/ | +--------------------------+----------------------------------+ 8 rows in set (0.00 sec)
表中就是當前設置的字符集,先看不用關注的幾個值:數據庫
character_set_filesystem | binary:
文件系統上的存儲格式,默認爲binary
(二進制)character_set_system | utf8:
系統的存儲格式,默認爲utf8
character_sets_dir | /usr/local/mysql/share/charsets/:
可使用的字符集的文件路徑剩下的幾個就是平常影響讀寫亂碼的參數了:- character_set_client:
客戶端請求數據的字符集- character_set_connection:
從客戶端接收到數據,而後傳輸的字符集- character_set_database:
默認數據庫的字符集;若是沒有默認數據庫,使用character_set_server
字段- character_set_results:
結果集的字符集- character_set_server:
數據庫服務器的默認字符集編程
字符集的轉換流程分爲3
步:segmentfault
character_set_client
字符集MySQL
實例收到客戶端發送的數據後,將其轉換爲character_set_connection
字符集進行內部操做時,將數據字符集轉換爲內部操做字符集:服務器
character set
設定值default character set
設定值default character set
設定值character_set_server
設定值character_set_results
說字符序以前,咱們須要瞭解一點基礎知識:網絡
(Character)
是指人類語言中最小的表義符號。例如’A’、’B’
等;(Encoding)
。例如,咱們給字符’A’
賦予數值0
,給字符’B’
賦予數值1
,則0
就是字符’A’
的編碼;(Character Set)
。例如,給定字符列表爲{‘A’,’B’}
時,{‘A’=>0, ‘B’=>1}
就是一個字符集;(Collation)
是指在同一字符集內字符之間的比較規則;(Default Collation)
;MySQL
中的字符序名稱聽從命名慣例:以字符序對應的字符集名稱開頭;以_ci
(表示大小寫不敏感,case insensitive
)、_cs
(表示大小寫敏感,case sensitive
)或_bin
(表示按編碼值比較,binary
)結尾。例如:在字符序「utf8_general_ci」
下,字符「a」
和「A」
是等價的;所以字符序不一樣於字符集,用於數據庫字段的相等或大小比較。咱們查看MySQL
實例設置的字符序:編程語言
mysql> show variables like 'collation%'; +----------------------+-------------------+ | Variable_name | Value | +----------------------+-------------------+ | collation_connection | latin1_swedish_ci | | collation_database | latin1_swedish_ci | | collation_server | latin1_swedish_ci | +----------------------+-------------------+ 3 rows in set (0.00 sec)
跟utf8對應的經常使用字符序是:utf8_unicode_ci/utf8_general_ci和utf8_bin
等,那麼他們的區別是什麼呢?測試
_bin
是用二進制存儲並比較,區別大小寫,存儲二進制內容時使用utf8_general_ci
:校對速度快,但準確度稍差,使用中英文時使用utf8_unicode_ci
:準確度高,但校對速度稍慢,使用德法俄等外語時使用詳細的區別能夠參考 Mysql中的排序規則utf8_unicode_ci、utf8_general_ci的區別總結。
若是在MySQL
鏈接時,出現了亂碼的問題,那麼基本能夠肯定是各個字符集/序設置不統一的緣由。MySQL
默認的latin1
格式不支持中文,因爲咱們在中國,因此選擇對中文和各語言支持都很是完善的utf8
格式。因此,咱們須要將須要關注的字符集和字符序都修改成utf8
格式。
你也能夠選擇utf8mb4
格式,這個格式支持保存emoji😈
表情。
咱們須要修改Mysql的配置文件,查看配置文件的位置有兩種方式:
1. $ mysql --help | grep 'my.cnf' /etc/mysql/my.cnf /etc/my.cnf ~/.my.cnf 2. ps aux | grep mysql
在(1)
中,/etc/my.cnf, /etc/mysql/my.cnf, ~/.my.cnf
這些就是mysql默認會搜尋my.cnf的目錄,優先級依次升高。能夠在各個配置文件裏都使用long_query_time
來測試一下。
而後,咱們修改或新增下面的配置項:
# 下面註釋的幾行能夠不設置,但若是你的沒有生效,也能夠試試看 [mysqld] character_set_server=utf8 collation-server=utf8_general_ci skip-character-set-client-handshake #init_connect='SET NAMES utf8' #[client] #default-character-set=utf8
這三行配置就能夠解決問題,最關鍵的是最後一行,參考mysql文檔,使用該參數會忽略客戶端傳遞的字符集信息,而直接使用服務端的設定;再加上咱們設定服務端的字符集和字符序均爲utf8
,這樣就保證了字符格式的統一,解決亂碼的問題。
重啓mysql
服務,若是提示找不到服務,請參考用service命令管理mysql啓停:
$ service mysqld restart Shutting down MySQL.. [ OK ] Starting MySQL. [ OK ]
鏈接到mysql
,查看當前編碼:
mysql> show variables like '%char%'; +--------------------------+----------------------------------+ | Variable_name | Value | +--------------------------+----------------------------------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | utf8 | | character_set_filesystem | binary | | character_set_results | utf8 | | character_set_server | utf8 | | character_set_system | utf8 | | character_sets_dir | /usr/local/mysql/share/charsets/ | +--------------------------+----------------------------------+ 8 rows in set (0.01 sec) mysql> show variables like 'collation%'; +----------------------+-----------------+ | Variable_name | Value | +----------------------+-----------------+ | collation_connection | utf8_general_ci | | collation_database | utf8_general_ci | | collation_server | utf8_general_ci | +----------------------+-----------------+ 3 rows in set (0.01 sec)
能夠看到一切都符合預期,請求和存儲的數據也再也不是亂碼了。
unknown variable 'default-character-set=utf8'
參考官方文檔,該參數自5.5.3
版本廢棄,改成了character-set-server
,改成這個參數便可。
但這個是在[mysqld]
下的配置,在[client]
下的配置依然使用default-character-set
參數。