Postgresql

PostgreSQL 是否支持 ICU 排序規則的選項和設置?

  • October 4, 2019

ICU 指定不同的 LDML 排序規則設置。其中一些看起來很有趣,尤其是關於大小寫和口音的那些,

  • “忽略重音”:strength=primary
  • “忽略重音”,但要考慮大小寫:strength=primary caseLevel=on
  • “忽略大小寫”:strength=secondary
  • “忽略標點符號”(完全):strength=tertiary alternate=shifted
  • “忽略標點符號”但區分標點符號:strength=quaternary alternate=shifted可能是一種更好的方法

您還可以在此處查看這些文件PostgreSQL 10 ICU 排序支持是否支持這些 ICU 選項和設置?

CREATE COLLATION special (provider = icu, locale = 'en@strength=primary');
SELECT 'Å' LIKE 'A' COLLATE "special"; # returns false

我也試過CLDR BCP47

從 ICU 54 開始,排序屬性也可以通過語言環境關鍵字指定,在舊的語言環境擴展語法 (" el@colCaseFirst=upper") 或語言標記語法 (“el-u-kf-upper”) 中。關鍵字和值不區分大小寫。請參閱LDML 歸類規範、歸類設置和列出有效歸類關鍵字及其值的數據文件。(不支持已棄用的屬性 kh/colHiraganaQuaternary 和 vt/variableTop。)

為此,這看起來是正確的

CREATE COLLATION special (provider = icu, locale = 'en-ks-level1');
SELECT 'Å' LIKE 'A' COLLATE "special"; # returns false

也試過en-u-ks-level1那個方法似乎是文件的目的,

CREATE COLLATION german_phonebook (provider = icu, locale = 'de-u-co-phonebk');

在 PostgreSQL 12 之前不能使用不區分大小寫或不區分重音的排序規則,因為 PostgreSQL 在內部認為具有不同二進製表示的字元串是不相等的。當排序規則感知比較器說它們相等時,它使用非排序規則感知strcmp()函式作為tie-breaker,以獲得 Unicode 所謂的“確定性”比較而不進行規範化。

從 PostgreSQL 12 開始,排序規則有一個**deterministic**屬性,必須將其設置為false從非二進制相等字元串的相等性中受益。來自CREATE COLLATION

確定性

指定排序規則是否應使用確定性比較。預設值為真。確定性比較認為不按字節相等的字元串不相等,即使比較認為它們在邏輯上相等。PostgreSQL 使用逐字節比較來打破平局。不確定的比較可以使排序規則不區分大小寫或重音。為此,您需要選擇適當的 LC_COLLATE 設置並將排序規則設置為不確定。

僅 ICU 提供者支持非確定性排序規則。

問題中的確切查詢對於不確定的排序規則是不可能的,因為它們不支持LIKE或任何形式的模式匹配(從 PostgreSQL 12 開始)。此外,語言環境應該-u-在整理子標籤之前有一個,否則它們將被整理者默默地忽略。

什麼按預期工作:

=# CREATE COLLATION special (
    provider = icu, locale = 'en-u-ks-level1', deterministic=false
  );

=# SELECT 'Å' = 'A' COLLATE "special";
?column? 
----------
t

引用自:https://dba.stackexchange.com/questions/191905