为什么以大写字母开头的字符排在以小写字母开头的字符之前?

Why are chars that start with capital letter sorted before those that start with lower letter?

我正在 SQL 中进行一些基本排序,很久以前我就了解到:以大写字母开头的名称排在名称之前以小写字母 开头。示例:

sqlite> create table letters (letter text);
sqlite> insert into letters values ('A');
sqlite> insert into letters values ('C');
sqlite> insert into letters values ('b');
sqlite> insert into letters values ('d');

sqlite> select * from letters order by letter asc;

输出:

A
C
b
d

在这种情况下,我们需要键入:sqlite> select * from letters order by letter collate nocase asc;,这将给出预期输出:

A
b
C
d

但我的问题是为什么要这样排序?我试图找到答案,但我失败了。我唯一的猜测是 ASCII 为 "A"=65,而 "a"=9765<97,意思是 "A""a" 之前存储。 OS 真的是这样工作的还是我还缺少其他东西?它在幕后是如何运作的?

data types documentation.

中描述了 Sqlite3 如何选择比较函数来排序和比较字符串

基本上,如果您没有在表达式或相关列定义中使用 COLLATE 关键字显式声明一个,它会使用 BINARY 排序规则模式,就像 C memcmp() 函数用于比较值 - 它查看第一个不同字节的各个字节。

Sqlite 使用 Unicode 存储文本值(使用 UTF-8 或 UTF-16,参见 PRAGMA encoding)。 Unicode 的前 127 个代码点与 ASCII 相同,因此在 BINARY 排序规则中,具有较低值的大写英文字母将排在小写字母之前。

烦人的是,这意味着相同的数据可以根据底层编码以不同的方式排序:

$ sqlite3 test1.db
sqlite> PRAGMA encoding='UTF-16LE';
sqlite> CREATE TABLE test(word TEXT);
sqlite> INSERT INTO test VALUES ('A'), ('a'), ('B'), ('b'), (char(0x1F355));
sqlite> SELECT word, hex(word), unicode(word) FROM test ORDER BY word;
word  hex(word)  unicode(word)
----  ---------  -------------
     3CD855DF   127829       
A     4100       65           
B     4200       66           
a     6100       97           
b     6200       98
sqlite> .quit
$ sqlite3 test2.db
sqlite> PRAGMA encoding='UTF-16BE';
sqlite> CREATE TABLE test(word TEXT);
sqlite> INSERT INTO test VALUES ('A'), ('a'), ('B'), ('b'), (char(0x1F355));
sqlite> SELECT word, hex(word), unicode(word) FROM test ORDER BY word;
word  hex(word)  unicode(word)
----  ---------  -------------
A     0041       65           
B     0042       66           
a     0061       97           
b     0062       98           
     D83CDF55   127829
sqlite> .quit
$ sqlite3 test3.db
sqlite> PRAGMA encoding='UTF-8';
sqlite> CREATE TABLE test(word TEXT);
sqlite> INSERT INTO test VALUES ('A'), ('a'), ('B'), ('b'), (char(0x1F355));
sqlite> SELECT word, hex(word), unicode(word) FROM test ORDER BY word;
word  hex(word)  unicode(word)
----  ---------  -------------
A     41         65           
B     42         66           
a     61         97           
b     62         98           
     F09F8D95   127829