安裝MySQL好多次了,每次都會糾結於數據庫的字符編碼配置,所以我決定這一次徹底把它理清。
MySQL的字符編碼結構比較細,它大方向分為兩個部分:數據存儲編碼和數據傳輸編碼。本篇討論數據存儲編碼部分,數據傳輸編碼在下一篇MySQL的字符編碼體系(二)——數據傳輸編碼中討論。
數據存儲的字符編碼配置是指定數據庫中存儲的數據默認采用什麼字符編碼。默認字符編碼的設置分為四個層次:服務器級、數據庫級、數據表級和列級。也就是說,可以為服務器設置一個默認字符編碼,再為服務器中的每一個數據庫設置不同的默認編碼,再為同一個數據庫中的每一個數據表設置不同的默認編碼,再為同一個數據表中的每一個列設置不同的默認編碼。
MySQL數據庫服務器的邏輯結構
那這四個層次的編碼設置到底如何起作用呢?如果新建數據庫時沒有指定字符編碼,就默認設置為服務器的編碼;如果新建數據表時沒有指定任何編碼,就默認設置為數據庫的編碼;如果向數據表添加新列或新建數據表時沒有特別指定某些列的編碼,那麼這些列就默認設置為數據表的編碼。注意這裡四個層次的編碼都是作為“默認”的存在,用戶創建數據庫、表或增加列時直接指定的編碼是最優先的。
另一方面,直接改變這四個層次的編碼並不會改變它們各自所有下層對象的當前編碼。比如修改只Server級,那麼所有已經存在的數據庫的默認編碼不變,數據表、表列以及每一行現有數據記錄的字符編碼都不變,但是如果新建一個數據庫且不指定其默認編碼,那它的默認編碼就會被設置為Server的默認編碼;同樣即使修改了所有四個層次的編碼,但是數據表中每一條現有記錄的字符字段仍然是按原來的編碼存儲的,但是如果向數據表中新插入一條記錄,數據庫將根據數據表當前各列的默認編碼來存儲該條記錄的各個字符字段。
修改Server以下各級編碼的SQL語句如下:
ALTER {DATABASE | SCHEMA} [db_name] [DEFAULT] CHARACTER SET [=] charset_name ALTER TABLE dbl_name [DEFAULT] CHARACTER SET [=] charset_name ALTER TABLE dbl_name MODIFY [COLUMN] col_name {CHAR[(length)] | TEXT} CHARACTER SET charset_name
注意上面第三條修改列字符編碼,實際上是通過完全重新定義列屬性的方式實現的,語法跟創建新數據表時指定列字段屬性一樣的。所以如果這裡只是想修改列字符編碼,那就必須完整地寫上創建該列時使用的所有定義修飾。
修改Server默認編碼可以通過運行時直接修改變量character_set_server實現,但這樣是臨時性的,客戶端關閉重啟後又會自動恢復。要想永久改變Server默認編碼需要在my.ini或my.cnf配置文件的“[mysqld]”區域中設定該變量的值,然後重啟服務器:
[mysqld] character_set_server=charset_name