一個 emoji 引發的思考
MySQL 字符集相關梳理
故事背景
今天在做專案資料遷移,涉及到將 A 表中的某個欄位複製到 B 表,本地(MAC Mysql 8.0.25)完全沒問題,但是在伺服器上執行遷移檔案時報錯:
經過一番查閱資料發現是由於 emoji 字元導致的,由於伺服器中 Mysql 版本為 5.6 在 A 表中設定的字符集為 utf8mb4 而 B 表中預設使用 utf8,utf8 最大隻支援三個位元組,而 emoji 表情位元組佔用大於三個,因此匯入失敗。下面關於 MySQL 字元相關做如下梳理:
MySQL 字符集
版本與字符集
MySQL5.5 版本在 my.ini 上修改 character_set_server 為 utf8
MySQL8.0 以上版本預設 character_set_server 為 utf8mb4
utf8mb4 和 utf8 的區別
-
utf8mb4 是 utf8 的擴充套件版,支援更多的字碼形式
-
utf8mb4 最大支援 4 個位元組,utf8 最大支援三個位元組
其他編碼問題
ASCII 編碼:一個英文字母(不區分大小寫)佔用一個位元組的空間,一箇中文漢字佔用兩個位元組的空間。一個二進位制的數字序列,在計算機中作為一個數字單元儲存是,一般為 8 位二進位制,換算為十進位制,最小值0,最大值255
UTF-8:一個英文字元佔用一個位元組的儲存空間,一箇中文(含繁體)佔用三個位元組的儲存空間。
Unicode(萬國碼):一個英文佔用兩個位元組的儲存空間,一箇中文(含繁體)佔用兩個位元組的儲存空間
UTF-16:一個英文字元或一個漢字字元儲存都需要佔用兩個位元組的儲存空間
UTF-32L:在世界上任何字元的儲存都需要佔用4個位元組的儲存空間
Mysql 檢視和修改資料庫字符集方法
檢視字符集
- 檢視 Mysql 資料庫伺服器和資料庫字符集
# 方法一:檢視資料庫字符集
show variables like '%character%';
# 方法二:檢視資料庫排序字符集
show variables like '%collation%';
備註:建立資料庫時指定字符集:create database mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
- 檢視 Mysql 支援的所有字符集
show charset;
- 查看錶的字符集
show table status from 庫名 like '表名';
- 查看錶中所有列的字符集
show full columns from '表名';
設定字符集
-
設定字符集
設定字符集一般有兩種方法,一種是建立表的時候設定字符集,另一種是表建成之後修改字符集
-
建立的時候指定字符集
create database dbName default character set=字符集;
-
建立表時單獨指定字符集
create table 表名 default character set=字符集;
-
修改字符集
-
修改全域性字符集
/*建立連線使用的編碼*/ set character_set_connection=utf8; /*資料庫的編碼*/ set character_set_database=utf8; /*結果集的編碼*/ set character_set_results=utf8; /*資料庫伺服器的編碼*/ set character_set_server=utf8; /*儲存系統元資料的字符集*/ set character_set_system=utf8; /*客戶端請求資料的字符集*/ set character_set_client=utf8; set collation_connection=utf8; set collation_database=utf8; set collation_server=utf8;
-
修改資料庫字符集
alter database 庫名 default characher set 字符集;
-
修改表的字符集
alter table 表名 convert to characher set 字符集;
-
修改欄位字符集
alter table 表名 modify 欄位名 欄位屬性 character set 字符集;
MySQl 排序字符集
以前預設為 utf8_general_ci,MySQL 8.0 以上預設 utf8mb4_0900_ai_ci
常用的 utf8 排序字符集
-
utf8_general_ci 不區分大小寫,這個你在註冊使用者名稱和郵箱的時候就要使用。
-
utf8_general_cs 區分大小寫,如果使用者名稱和郵箱用這個 就會照成不良後果
-
utf8_bin:字串每個字串用二進位制資料編譯儲存。 區分大小寫,而且可以存二進位制的內容
-
utf8_unicode_ci和utf8_general_ci對中、英文來說沒有實質的差別。
-
utf8_general_ci校對速度快,但準確度稍差。(準確度夠用,一般建庫選擇這個)
-
utf8_unicode_ci準確度高,但校對速度稍慢。
常用的 utf8mb4 排序字符集
cii即case insensitive,不區分大小寫。沒有實現Unicode排序規則,在遇到某些特殊語言或者字符集,排序結果可能不一致,但是,在絕大多數情況下,這些特殊字元的順序並不需要那麼精確。另外,在比較和排序的時候速度更快。
-
utf8mb4_bin:將字串每個字元用二進位制資料編譯儲存,區分大小寫,而且可以存二進位制的內容。
-
utf8mb4_unicode_ci:不區分大小寫,基於標準的Unicode來排序和比較,能夠在各種語言之間精確排序,在特殊情況下,Unicode排序規則為了能夠處理特殊字元的情況,實現了略微複雜的排序演算法,所以相容度比較高,但是效能不高。
排序規則概念
定義:是指對指定字符集下不同字元的比較規則。排序規則有以下特徵:
- 它和字符集(CHARSET)相關
- 每種字符集都有多種它支援的排序規則
- 每種字符集都會預設指定一種排序規則為預設值。
排序規則作用
排序規則指定後,它會影響我們使用 ORDER BY語句查詢的結果順序,會影響到 WHERE條件中大於小於號的篩選結果,會影響 DISTINCT、GROUP BY、HAVING 語句的查詢結果。另外,mysql 建索引的時候,如果索引列是字元型別,也會影響索引建立,只不過這種影響我們感知不到。總之,凡是涉及到字元型別比較或排序的地方,都和排序規則有關。