排序规则

database

一、什么是排序规则

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/

本文版权归作者和云海天共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

以上是 排序规则 的全部内容, 来源链接: utcz.com/z/536228.html

回到顶部