Héc*_*tor 3 postgresql collation order-by
我正在尝试学习和理解排序规则以及 postgresql 如何比较和排序字符串,但我发现了一个不协调的地方,我不知道我错过了什么。
查询:
SELECT datname, datcollate FROM pg_database;
Run Code Online (Sandbox Code Playgroud)
返回我的所有数据库都使用 en_GB.UTF-8 排序规则。
和查询:
SELECT table_schema,
table_name,
column_name,
collation_name
FROM information_schema.columns
WHERE collation_name is not null
ORDER BY table_schema,
table_name,
ordinal_position;
Run Code Online (Sandbox Code Playgroud)
返回所有列都具有“C”排序规则,这意味着(根据我的研究)未指定排序规则。所以,我认为使用了数据库排序规则,不是吗?
编辑:我的错误就在这里。前面的查询不会返回所有列的结果,只会返回那些不collation_name
为 null 的列,并且具有 null 排序规则的列是继承 DB 排序规则的列。所以我认为 foo.bar 列有C
排序规则,但null
事实上确实如此。
好吧,当我运行查询时,不一致的情况出现了:
SELECT "name" FROM foo.bar ORDER BY "name" ASC;
Run Code Online (Sandbox Code Playgroud)
其中“name”列数据类型是文本,foo.bar 是用户创建的 schema.table 组合。结果是像人类一样按字母顺序排列。从a/A到Z/z,无论是大写还是小写。
但是如果我运行以下查询:
SELECT "table_name"
FROM information_schema.tables
WHERE
"table_name" ~ 'some_pattern'
AND table_schema = 'foo'
AND table_type = 'BASE TABLE'
ORDER BY "table_name" ASC;
Run Code Online (Sandbox Code Playgroud)
它以类似机器的方式对结果进行排序,逐字节比较,因此将大写字母排在小写字母前面。
为什么会有这样的差异呢?我已经看到“table_name”列数据类型不是“text”而是“name”,但我找不到它是否有关系。
将数据库排序规则设置为 en_GB.UTF-8 不足以以人类的方式比较文本吗?
谢谢你的时间。
PostgreSQL 中的排序规则确定如下(简化,详细信息请参阅文档):
\n如果有明确的COLLATE
子句,则确定排序规则
否则,如果表列是使用特定排序规则定义的,则使用该排序规则
\n如果该列未使用排序规则定义(它具有 \xe2\x80\x9c 默认排序规则\xe2\x80\x9d),则使用数据库排序规则。
\n现在该列bar.name
未使用排序规则定义,因此en_GB.UTF-8
已使用。
但information_schema.columns
具有类型 的列information_schema.sql_identifier
,它是数据类型 的域name
,始终使用C
排序规则。因此,在该查询中,大写字母会排在小写字母之前。
要改变这一点,您应该显式指定排序规则:
\nORDER BY table_schema COLLATE "en_GB.UTF-8",\n table_name COLLATE "en_GB.UTF-8",\n ordinal_position;\n
Run Code Online (Sandbox Code Playgroud)\n
归档时间: |
|
查看次数: |
114 次 |
最近记录: |