通常狀況下,咱們會設置MySQL默認的字符編碼爲utf8,可是近些年來,emoji表情的火爆使用,給數據庫帶來了意外的錯誤,就是emoji的字符集已經超出了utf8的編碼範疇😄mysql
談到字符編碼問題,會讓不少人感到頭疼,這裏不在深究各個字符編碼的特色和理論,這裏只說下Unicode和utf8字符編碼的關係sql
1 |
Unicode是編碼字符集,而UTF-8就是字符編碼,即Unicode規則字庫的一種實現形式。 |
簡單的說在計算機內存中,統一使用Unicode編碼,當須要保存到硬盤或者須要傳輸的時候,就轉換爲UTF-8編碼數據庫
用記事本編輯的時候,從文件讀取的UTF-8字符被轉換爲Unicode字符到內存裏,編輯完成後,保存的時候再把Unicode轉換爲UTF-8保存到文件vim
emoji是Unicode編碼,在MySQL中使用utf8編碼沒法正常顯示emoji的表情,爲了解決這個問題,MySQL在5.5.3版本以後,引進了新的字符編碼utf8mb4
,本篇文章主要介紹如何將已是utf8的database切換到utf8mb4字符編碼安全
utf8mb4最明顯的好處是解決了蘋果挖的坑-推廣了emoji表情。utf8mb4解決了MySQL數據庫存儲emoji表情的問題優化
utf8mb4是utf8的超集,理論上由utf8升級到utf8mb4字符編碼沒有任何兼容問題編碼
安全第一,備份全部須要升級字符編碼的數據庫spa
utf8mb4是MySQL5.5.3版本以後支持的字符集,so,若是你須要使用這個字符集,前提條件是你的MySQL版本必須 >= 5.5.33d
在MySQL中,能夠爲一個database設置字符編碼,能夠爲一張表設置字符編碼,甚至能夠爲某一個字段設置字符編碼rest
SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%';
show create database polarsnow;
show create table ps;
show full columns from ps;
ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci
雖然修改了database的字符集爲utf8mb4,可是實際只是修改了database新建立的表,默認使用utf8mb4,原來已經存在的表,字符集並無跟着改變,須要手動爲每張表設置字符集
ALTER TABLE table_name DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE table_name CHANGE column_name column_name VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
注:VARCHAR(191) 根據字段實例的類型填寫
因爲從utf8升級到了utf8mb4,一個字符所佔用的空間也由3個字節增加到4個字節,可是咱們當初建立表時,設置的字段類型以及最大的長度沒有改變。例如,你在utf8下設置某一字段的類型爲TINYTEXT
, 這中字段類型最大能夠容納255字節,三個字節一個字符的狀況下能夠容納85個字符,四個字節一個字符的狀況下只能容納63個字符,若是原表中的這個字段的值有一個或多個超過了63個字符,那麼轉換成utf8mb4字符編碼時將轉換失敗,你必須先將TINYTEXT
更改成TEXT
等更高容量的類型以後才能繼續轉換字符編碼
在InnoDB引擎中,最大的索引長度爲767字節,三個字節一個字符的狀況下,索引列的字符長度最大能夠達到255,四個字節一個字符的狀況下,索引的字符長度最大隻能到191。若是你已經存在的表中的索引列的類型爲VARCHAR(255)
那麼轉換utf8mb4時一樣會轉換失敗。你須要先將VARCHAR(255)
更改成VARCHAR(191)
才能繼續轉換字符編碼
SET NAMES utf8 COLLATE utf8_unicode_ci
becomes SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci
1 |
> vim /etc/my.cnf |
檢查修改
1 |
mysql> SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%'; |
注:character_set_system 一直都會是 utf8,不能被更改
1 |
> mysqlcheck -u root -p --auto-repair --optimize --all-databases |
不要在MySQL上使用utf8字符編碼,推薦使用utf8mb4
,至於爲何,引用國外友人的一段話:
Never use utf8 in MySQL — always use utf8mb4 instead. Updating your databases and code might take some time, but it’s definitely worth the effort. Why would you arbitrarily limit the set of symbols that can be used in your database? Why would you lose data every time a user enters an astral symbol as part of a comment or message or whatever it is you store in your database? There’s no reason not to strive for full Unicode support everywhere. Do the right thing, and use utf8mb4. 🍻