PostgreSQL:排序規則“C”和“C.UTF-8”之間的區別
C
在 PostgreSQL 中,排序規則和排序規則有什麼區別C.UTF-8
?兩者都出現在
pg_collation
. 不管數據庫的實際編碼是什麼,是否可能與編碼C.UTF-8
相同?C``UTF-8
PostgreSQL 文件還有很多不足之處(只是說’😼)。
首先,特定數據庫只有一種編碼,因此
C
在C.UTF-8
您的 UTF-8 數據庫中都使用 UTF-8 編碼。對於libc排序規則:*按照慣例,*通常排序規則名稱是以下結構的真正的兩部分名稱:
{locale_name}.{encoding_name}
“語言環境”(即“文化”)是一組特定於語言的排序規則(
LC_COLLATE
)和大小寫規則(LC_CTYPE
)。儘管有時會有重疊,但這實際上與這些數據的儲存方式沒有任何關係。“編碼”是數據的儲存方式(即什麼字節序列等同於哪個字元)。即使有時存在重疊,但這實際上與使用編碼的任何特定語言的排序和大寫規則沒有任何關係(某些編碼可以被多種語言使用,這些語言在其中一種或兩種中可能具有完全不同的規則那些領域)。
為了說明,考慮儲存韓國數據:
ko_KR
是語言環境。可用於此語言環境的可能編碼有:
EUC_KR
(擴展 UNIX 程式碼-KR)JOHAB
UHC
(統一韓文程式碼/Windows949)UTF8
(Unicode 的 8 位編碼)還要考慮以下內容,取自“排序規則支持:libc 排序規則”文件(強調添加):
例如,作業系統可能會提供一個名為
de_DE.utf8
. 然後將創建一個以編碼initdb
命名的排序規則……它還將創建一個帶有從名稱中剝離的標籤的排序規則。所以你也可以在 name 下使用排序規則,這樣寫起來不那麼麻煩,並且使 name 不那麼依賴於編碼……de_DE.utf8``UTF8``.utf8``de_DE
…
在任何特定數據庫中,只有使用該數據庫編碼的排序規則才有意義。中的其他條目
pg_collation
將被忽略。因此,剝離的排序規則名稱,例如,de_DE
可以被認為在給定數據庫中是唯一的,即使它不是全域唯一的。建議使用剝離的排序規則名稱,因為如果您決定更改為另一種數據庫編碼,它將減少您需要更改的事情。但是請注意,default
無論數據庫編碼如何,都可以使用C
、 和排序規則。POSIX
意思是,在使用 UTF-8 編碼的數據庫中,
en_US
是en_US.UTF8
等價的。但是,在該數據庫和使用LATIN1
編碼的數據庫之間,en_US
排序規則是不等價的。那麼,這是否意味著
C
和C.UTF-8
相同?不,那太容易了!!!
C
排序規則是上述行為的一個例外。排序規則是一組簡單的C
規則,無論數據庫的編碼如何,行為都應該是一致的(這可以通過僅將美國英語字母表“az”和“AZ”辨識為“字母”來實現) ,並按字節值排序,這對於您可用的編碼應該是相同的)。
C.UTF-8
與基本規則相比,排序規則實際上是一組稍微增強的規則C
。實際上可以看出這種差異,pg_collation
因為collcollate
和collctype
列的值在 和 的行之間是不同C
的C.UTF-8
。我整理了一組測試查詢來說明這兩個排序規則之間的一些相似之處和不同之處,以及與
en_GB
(和隱含的en_GB.utf8
)比較。我從Daniel Vérité 的回答中提供的查詢開始,對它們進行了增強,希望能更清楚地了解顯示和未顯示的內容,並添加了一些查詢。結果告訴我們:
C
並且C.UTF-8
實際上是不同的規則集,即使只是略有不同,基於它們在(最終查詢)中的collcollate
和collctype
列中的各自值pg_collation
C.UTF-8
擴展被認為是“字母”的字元C.UTF-8
,不像C
(但像en_GB
),辨識無效的Unicode程式碼點(即U + 0378)並將它們排序到頂部C.UTF-8
,類似C
(但不同en_GB
),按程式碼點對非美國英語字母字元進行排序ucs_basic
似乎等同於C
(在文件中說明)您可以在以下位置找到並執行查詢:db<>fiddle