MySQL?字符集、排序規(guī)則與查詢關(guān)系最佳實踐
MySQL 查詢是否區(qū)分大小寫及重音敏感,取決于創(chuàng)建時指定的字符集(character set)和排序規(guī)則(collation)。
(1)字符集(Character Set):規(guī)定可存儲的字符,如 utf8、utf8mb4、latin1 等。
(2)排序規(guī)則(Collation):確定字符比較與排序規(guī)則,如是否區(qū)分大小寫、重音等。
注意:
(1)每個排序規(guī)則必須對應(yīng)特定的字符集,如 utf8mb4_bin 僅用于 utf8mb4 字符集。
(2)“重音敏感”(Accent Sensitive):指排序規(guī)則將帶重音符號的字母視為與基本字母相同或不同的特性,如 'cafe' 與 'café'。
在 MySQL 5.7 中,默認字符集和排序規(guī)則是 latin1 和 latin1_swedish_ci。實際應(yīng)用里,建議使用 utf8mb4 字符集以支持完整 Unicode 字符(含 emoji),并采用默認對應(yīng)的 utf8mb4_general_ci 排序規(guī)則,該規(guī)則下查詢不區(qū)分大小寫。
一、常見排序規(guī)則
排序規(guī)則 | 對應(yīng)字符集 | 大小寫敏感 | 重音敏感 | 適用版本 | 說明 |
---|---|---|---|---|---|
utf8_general_ci | utf8 | ? | ? | 所有版本 | 基本 Unicode 比較 |
utf8mb4_general_ci | utf8mb4 | ? | ? | 5.5.3+ | 默認的 utf8mb4 排序規(guī)則 |
latin1_swedish_ci | latin1 | ? | ? | 所有版本 | 傳統(tǒng)西歐默認排序規(guī)則 |
utf8mb4_unicode_ci | utf8mb4 | ? | ? | 5.5.3+ | 符合 Unicode 標(biāo)準(zhǔn)的更準(zhǔn)確排序 |
utf8mb4_0900_ai_ci | utf8mb4 | ? | ? | 8.0+ | 基于 Unicode 9.0 標(biāo)準(zhǔn) |
utf8_bin | utf8 | ? | ? | 所有版本 | 二進制比較(嚴格區(qū)分大小寫) |
utf8mb4_bin | utf8mb4 | ? | ? | 5.5.3+ | utf8mb4 的二進制比較 |
utf8mb4_unicode_cs | utf8mb4 | ? | ? | 5.5.3+ | 已棄用,改用 utf8mb4_bin |
utf8mb4_0900_as_cs | utf8mb4 | ? | ? | 8.0+ | 嚴格區(qū)分大小寫和重音 |
表格說明:
(1)可通過排序規(guī)則后綴判斷其是否支持大小寫和重音敏感,ci、cs、ai、as 分別表示不區(qū)分大小寫、區(qū)分大小寫、不區(qū)分重音和區(qū)分重音。
(2)帶 bin 后綴的排序規(guī)則基于二進制(Binary)比較,嚴格區(qū)分和重音。
二、設(shè)置方法
1. 數(shù)據(jù)庫實例級
# my.conf 或 my.ini [mysqld] character-set-server=utf8mb4 collation-server=utf8mb4_general_ci
2. 數(shù)據(jù)庫級
CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
3. 表級
CREATE TABLE case_sensitive_table ( id INT, username VARCHAR(50) ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
4. 列級
CREATE TABLE case_sensitive_table ( id INT, username VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin ) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
三、設(shè)置建議
1. 注意事項
(1)性能影響:使用區(qū)分大小寫的比較可能會影響查詢性能,混合使用不同字符集也可能影響查詢優(yōu)化
(2)存儲空間:不同字符集占用的存儲空間不同 (如 utf8mb4 比 latin1 占用更多空間)
(3)索引限制:某些情況下不同字符集的列不能直接比較或連接
(4)轉(zhuǎn)換風(fēng)險:修改已有數(shù)據(jù)的字符集前需謹慎,可能導(dǎo)致數(shù)據(jù)丟失或損壞
2. 最佳實踐
(1)盡量保持各表及表內(nèi)各列字符集和排序規(guī)則一致,除非有特殊需求
(2)修改已有數(shù)據(jù)的字符集前先備份數(shù)據(jù)
(3)對于需要區(qū)分大小寫的列 (如用戶名、驗證碼),明確指定使用_bin
排序規(guī)則
(4)應(yīng)文檔化說明使用不同字符集/排序規(guī)則的原因
(5)MySQL 8.0 默認使用 utf8mb4 + utf8mb4_0900_ai_ci,它符合更新的 Unicode 標(biāo)準(zhǔn)且性能更優(yōu)
四、查看方法
## 查看數(shù)據(jù)庫字符集和排序規(guī)則 SHOW VARIABLES LIKE 'character_set_server'; SHOW VARIABLES LIKE 'collation_server'; ## 查看某表字符集和序規(guī)則 SHOW CREATE TABLE `table_name`; # CHARSET 后面為字符集 SHOW TABLE STATUS LIKE 'table_name'; # Collation 列表示排序規(guī)則
五、查詢時如何強制區(qū)分大小寫
1. 強制方法
如遇到不支持區(qū)分大小寫的排序規(guī)則,可使用以下方法強制啟用:
(1)使用 COLLATE 指定區(qū)分大小寫的排序規(guī)則
SELECT * FROM table_name WHERE column_name COLLATE utf8mb4_bin = 'Value'; -- utf8mb4_bin 需適配字符集
(2)使用 BINARY 運算符
SELECT * FROM table_name WHERE BINARY column_name = 'Value';
(3)使用 LIKE BINARY 語法
SELECT * FROM table_name WHERE column_name LIKE BINARY 'Value';
(4)使用區(qū)分大小寫的函數(shù)
SELECT * FROM table_name WHERE CAST(column_name AS BINARY) = CAST('Value' AS BINARY);
(5)修改列或表的字符集排序規(guī)則
-- 修改列的排序規(guī)則 ALTER TABLE table_name MODIFY column_name VARCHAR(255) COLLATE utf8mb4_bin; -- 修改表的默認排序規(guī)則 ALTER TABLE table_name COLLATE utf8mb4_bin;
2. 各方法對比
方法 | 是否利用索引 | 持久性 | 字符集兼容性 | 推薦場景 | 缺點 |
---|---|---|---|---|---|
使用 COLLATE 指定區(qū)分大小寫的排序規(guī)則 | ? 是 | 僅當(dāng)前查詢 | 需匹配列字符集 | 臨時區(qū)分大小寫查詢 | 需顯式指定,字符集需一致 |
使用 BINARY 運算符 | ?? 部分場景 | 僅當(dāng)前查詢 | 任意字符集 | 快速兼容性寫法 | 某些版本無法利用索引 |
使用 LIKE BINARY 語法 | ?? 部分場景 | 僅當(dāng)前查詢 | 任意字符集 | 不推薦(語義混淆) | 性能差,模糊匹配語義不清晰 |
使用區(qū)分大小寫的函數(shù) | ?? 部分場景 | 僅當(dāng)前查詢 | 任意字符集 | 極特殊場景 | 性能最差,語法冗長 |
修改列或表的字符集排序規(guī)則 | ? 是 | ? 永久生效 | 需匹配列字符集 | 需要長期區(qū)分大小寫的字段 | 修改表結(jié)構(gòu)可能鎖表 |
3. 使用建議
如僅當(dāng)前查詢需區(qū)分大小寫,建議使用 COLLATE 指定區(qū)分大小寫的排序規(guī)則;如需永久生效,建議修改列或表的字符集排序規(guī)則。
到此這篇關(guān)于MySQL 字符集、排序規(guī)則與查詢關(guān)系詳解的文章就介紹到這了,更多相關(guān)MySQL 字符集、排序規(guī)則與查詢內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Navicat修改MySQL數(shù)據(jù)庫密碼的多種方法
這篇文章主要介紹了Navicat修改MySQL數(shù)據(jù)庫密碼,需要的朋友可以參考下2018-09-09(MariaDB)MySQL數(shù)據(jù)類型和存儲機制全面講解
下面小編就為大家分享一篇(MariaDB)MySQL數(shù)據(jù)類型和存儲機制全面講解,具有很的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-01-01MySQL關(guān)系型數(shù)據(jù)庫事務(wù)的ACID特性與實現(xiàn)
這篇文章主要介紹了MySQL關(guān)系型數(shù)據(jù)庫事務(wù)的ACID特性與實現(xiàn),ACID?是為保證事務(wù)transaction是正確可靠的,具備原子性、一致性、隔離性、持久性等特性2022-07-07sqoop export導(dǎo)出 map100% reduce0% 卡住的多種原因及解決
這篇文章主要介紹了sqoop export導(dǎo)出 map100% reduce0% 卡住的多種原因及解決,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01Ubuntu18.04 安裝mysql8.0.11的圖文教程
本文通過圖文并茂的形式給大家介紹了Ubuntu18.04 安裝mysql8.0.11的方法,非常不錯,具有一定的參考借鑒價值,需要的的朋友參考下吧2018-07-07