一、什么是排序規則
mysql官網的說法
The collation is a set of rules (only one rule in this case): “compare the encodings.” We call this simplest of all possible collations a binary collation.
排序規則是一套規則(在這種情況下,只有一個規則):“比較編碼,”我們把這種簡單的所有可能的歸類的二進制 排序規則,
https://dev.mysql.com/doc/refman/8.0/en/charset-general.html
《高性能mysql》中的說法

《mysql是怎樣運行的》中的說法
沒找到電子版,只能拍照了

二、我的理解
排序規則是針對字串而言的,當有兩個字串想要比較大小時,排序規則才有意義,
型別對資料比較的影響
非字串型別
要么天然就有排序規則(如:int,值的大小比較,就是他的排序規則;日期,日期及時間的早晚就是排序規則)
要么天然就沒有辦法比較(如二進制存盤的圖片,雖然二進制本身可以比較,但比較的結果對于圖片而言沒有意義)
字串型別
也有一種天然的比較方式,類似于Java中字串String型別的compareTo方法,即使用字串中的字符的對應編碼的大小來比較,
特殊情況
然而,有一些字串比較的需求就很有意思了
如中文’一二三四’對應的unicode字符編碼是19968,20108,19977,22235,【這里使用unicode編碼僅僅是用來舉例,就算是其他編碼也可能會出現類似情況】
使用Java代碼計算編碼
System.out.println((int)'一');
System.out.println((int)'二');
System.out.println((int)'三');
System.out.println((int)'四');
中文
比較
如果想比較’一百二十’與’一百三十’兩個中文字串
結果
顯而易見,正常人期待的結果都是:’一百二十’小于’一百三十’,
然而以字串對比來說,
先比較第一個字符’一’,相等;
再比較第二個字符’百’,也相等;
再比較第三個字符’二’與’三’,結果二比三大;
那么’一百二十’大于’一百三十’,
這個結果是反人類的,至少是反中國人的,
可以使用Java代碼計算比較結果
System.out.println("一百三十".compareTo("一百二十"));
執行結果是-131,
結果是負的,說明”一百三十”小于”一百二十”,這確實不是正常人期待的結果,
英語特殊情況舉例
同理對比Apple和apple,正常人期待的結果是相等
使用Java代碼
System.out.println("Apple".compareTo("apple"));
執行結果是-32
負的,說明”Apple”小于”apple”,這也不是正常人期待的結果,
他拉丁語系的特殊情況舉例
希望大小寫不敏感,雷同英語
日語的特殊情況
期待:平假名和片假名被視為相等,下面的鏈接是日語的情況,
https://www.it1352.com/1898650.html
三、實作方式
類似的在一個語言中,期望在文本比較時,針對某些大小寫或者簡繁體對應字符相等,我們需要專門制作一種規則
這種規則在文本比較時使用,就叫做校對規則,而大部分情況只有排序時才會比較字符的大小,所以也叫排序規則,
Java實作
當Java想排序時,要么你的泛型實作了介面Comparable,要么你實作一個Comparator介面的類,
類似的整數型別Integer天然的實作了介面Comparable,下面是類Integer的定義
public final class Integer extends Number implements Comparable<Integer>
查看實作介面的方法compareTo,其實該方法就是實作一下當兩個Integer型別比較時,回傳值及表達怎么比較,
而比較器Comparator是描述兩個泛型類的實體怎么比較,
那么實作介面Comparable代表著類的實體本身就可以比較,比較器Comparator代表著兩個實體使用比較器來比較,
方法compareTo的理解
compareTo就是一個比較的方式,比如class是人,那么身高是一種比較方式,體重也是,財產也是,都可以比較,只是實作compareTo的方式不同,比較的結果就不同,
資料庫實作
資料庫搞出來個排序規則,其實就是類似Java的String類的compareTo方法怎么實作的,即是排序規則
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence
即,建表時字串列必須指定個排序規則,否則沒有辦法order by 該列,如果不指定即默認邏輯上級的排序規則,
上下級關系是:庫,表,列
所以建庫時一定要指定排序規則,不能只指定編碼,
四、用途
索引使用必須在排序規則相同的欄位間
查看博客中:2020-08-02的文章《一次MySQL索引失效引發的思考》
https://www.cnblogs.com/klarck/p/13418706.html
排序規則不同索引會失效
select table_name,column_name,character_set_name,collation_name
from information_schema.columns where table_schema = '庫名' and data_type = 'varchar'
字串本身帶排序規則
測驗代碼如下
CREATE TABLE test1 (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(45) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_general_ci ;
SET @app_name = "test-text" COLLATE utf8mb4_unicode_ci ;
SELECT * FROM test1 WHERE name = @app_name
報錯資訊 Illegal mix of collations (utf8mb4_general_ci,IMPLICIT) and (utf8mb4_unicode_ci,IMPLICIT) for operation ‘=’
google翻譯:操作’=’的排序規則(utf8mb4_general_ci,IMPLICIT)和(utf8mb4_unicode_ci,IMPLICIT)的非法混合
可見,變數@app_name攜帶了排序規則utf8mb4_unicode_ci,
mysql字串可以比較大小
那么max可以計算字串欄位
例如以之前的表為例
SELECT MAX(name) FROM test1;
作者:
公敵依波拉 一劍破萬法
出處:
https://www.cnblogs.com/klarck/
本文著作權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利,
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/413158.html
標籤:MySQL
上一篇:資料連接池
