Postgresql
區分大小寫不一致
我正在嘗試學習和理解排序規則以及 postgresql 如何比較和排序字元串,但我發現不協調,我不知道我錯過了什麼。
查詢:
SELECT datname, datcollate FROM pg_database;
返回我的所有數據庫都使用 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;
返回所有列都有“C”排序規則,這意味著(根據我的研究)沒有指定排序規則。所以,我假設使用了數據庫排序規則,不是嗎?
編輯:我的錯誤在這裡。前面的查詢不會返回所有列的結果,只返回不為
collation_name
空的列,具有空排序規則的列是繼承數據庫排序規則的列。所以我認為 foo.bar 列有C
排序規則,但null
實際上是。好吧,當我執行查詢時出現了不一致:
SELECT "name" FROM foo.bar ORDER BY "name" ASC;
其中“名稱”列數據類型是文本,而 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;
它以類似機器的方式對結果進行排序,逐字節比較,因此在小寫之前排序大寫。
為什麼會有這種差異?我已經看到“table_name”列數據類型不是“文本”而是“名稱”,但我找不到它是否有事可做。
將數據庫排序規則設置為 en_GB.UTF-8 不足以以人類的方式比較文本?
謝謝你的時間。
PostgreSQL 中的排序規則是這樣確定的(簡化,詳細見文件):
- 如果存在顯式
COLLATE
子句,則確定排序規則- 否則,如果使用某種排序規則定義表列,則使用該排序規則
- 如果該列未使用排序規則定義(它具有“預設排序規則”),則使用數據庫排序規則。
現在該列
bar.name
未使用排序規則定義,因此en_GB.UTF-8
使用。但是
information_schema.columns
有 type 的列information_schema.sql_identifier
,它是數據類型的域name
,它總是使用C
排序規則。因此,在該查詢中,大寫字母排在小寫字母之前。要改變這一點,您應該明確指定排序規則:
ORDER BY table_schema COLLATE "en_GB.UTF-8", table_name COLLATE "en_GB.UTF-8", ordinal_position;