排序规则

一、什么是排序规则

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.

排序规则是一组规则(在本例中,只有一条规则):“比较编码”。我们对所有可能的类别进行这个简单的二进制校对。

[En]

A collation is a set of rules (in this case, there is only one rule): “compare coding.” We take this simple binary collation of all possible categories.

https://dev.mysql.com/doc/refman/8.0/en/charset-general.html

《高性能mysql》中的说法

排序规则

《mysql是怎样运行的》中的说法

我找不到电子版,所以我不得不拍照。

[En]

I couldn’t find the electronic version, so I had to take pictures.

排序规则

二、我的理解

排序规则是针对字符串的,当有两个字符串想要更大时,它是有意义的。

[En]

Collation is for strings, and it makes sense when there are two strings that want to be larger.

类型对数据比较的影响

非字符串类型

要么天然就有排序规则(如:int,值的大小比较,就是他的排序规则;日期,日期及时间的早晚就是排序规则)
或者没有自然的比较方式(比如存储在二进制中的图片,虽然二进制本身可以比较,但比较的结果对图片没有意义)

[En]

Or there is no natural way to compare (for example, pictures stored in binary system, although the binary system itself can be compared, but the result of comparison is meaningless to the picture)

字符串类型

也有一种天然的比较方式,类似于Java中字符串String类型的compareTo方法,即使用字符串中的字符的对应编码的大小来比较。

特殊情况

但是,字符串比较有一些有趣的要求

[En]

However, there are some requirements for string comparison that are interesting

如中文’一二三四’对应的unicode字符编码是19968,20108,19977,22235,【这里使用unicode编码仅仅是用来举例,就算是其他编码也可能会出现类似情况】
使用Java代码计算编码

System.out.println((int)'一');
System.out.println((int)'二');
System.out.println((int)'三');
System.out.println((int)'四');

中文

比较
如果想比较’一百二十’与’一百三十’两个中文字符串

结果
显然,普通人期待的结果是:‘120’小于‘130’。

[En]

Obviously, the results expected by normal people are: ‘120’ is less than ‘130’.

然而以字符串对比来说,
先比较第一个字符’一’,相等;
再比较第二个字符’百’,也相等;
再比较第三个字符’二’与’三’,结果二比三大;
那么’一百二十’大于’一百三十’,
这一结果是反人类的,或者至少是反中国的。

[En]

This result is anti-human, or at least anti-Chinese.

可以使用Java代码计算比较结果

System.out.println("一百三十".compareTo("一百二十"));

执行结果是-131,
结果是负的,说明”一百三十”小于”一百二十”,这确实不是正常人期待的结果。

英语特殊情况举例

同理对比Apple和apple,正常人期待的结果是相等
使用Java代码

System.out.println("Apple".compareTo("apple"));

执行结果是-32
负的,说明”Apple”小于”apple”,这也不是正常人期待的结果。

他拉丁语系的特殊情况举例

我希望它不区分大小写,并且类似于英语。

[En]

I hope it is not case-sensitive and similar to English.

日语的特殊情况

期望:平假名和片假名被认为是平等的,下面的链接是日语中的情况。

[En]

Expectation: hiragana and katakana are considered equal, and the link below is the case in Japanese.

https://www.it1352.com/1898650.html

三、实现方式

同样,在一种语言中,当我们比较文本时,我们需要为一些大写或简写字符的相等制定特殊的规则。

[En]

Similarly, in a language, it is expected that when comparing texts, we need to make a special rule for the equality of some uppercase or simplified characters.

当该规则用于文本比较时,它被称为校对规则,在大多数情况下,只有在排序时才比较字符大小,因此它也被称为校对。

[En]

When this rule is used in text comparison, it is called a proofreading rule, and in most cases the size of characters is compared only when sorting, so it is also called a collation.

Java实现

当Java想排序时,要么你的泛型实现了接口Comparable,要么你实现一个Comparator接口的类。
类似的整数类型Integer天然的实现了接口Comparable,下面是类Integer的定义

public final class Integer extends Number implements Comparable

查看实现接口的方法compareTo,其实该方法就是实现一下当两个Integer类型比较时,返回值及表达怎么比较。
而比较器Comparator是描述两个泛型类的实例怎么比较。
那么实现接口Comparable代表着类的实例本身就可以比较,比较器Comparator代表着两个实例使用比较器来比较。

方法compareTo的理解

compareTo就是一个比较的方式,比如class是人,那么身高是一种比较方式,体重也是,财产也是,都可以比较。只是实现compareTo的方式不同,比较的结果就不同。

数据库实现

数据库搞出来个排序规则,其实就是类似Java的String类的compareTo方法怎么实现的,即是排序规则

public final class String
    implements java.io.Serializable, Comparable, CharSequence

即,建表时字符串列必须指定个排序规则,否则没有办法order by 该列,如果不指定即默认逻辑上级的排序规则。
上下级关系有:库、表、列。

[En]

The superior and subordinate relationships are: libraries, tables, columns.

因此,在构建库时,您必须指定排序规则,而不仅仅是编码。

[En]

Therefore, when building a library, you must specify the collation, not just the encoding.

四、用途

索引使用必须在具有相同归类的字段之间

[En]

Index usage must be between fields with the same collation

查看博客中: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;

Original: https://www.cnblogs.com/klarck/p/15784148.html
Author: 一剑破万法
Title: 排序规则

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/507888/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球