Postgresql
如何選擇國際數據庫的排序規則?
我正在設計一個數據庫,它將以不同的語言儲存數據(使用 UTF-8),所以我認為顯示查詢結果的最佳方法是在查詢過程中根據使用者的語言對其進行排序(因為有不止一個正確的方法),如下:
SELECT a < b COLLATE "de_DE" FROM test1;
假設這是處理國際數據的正確方法,那麼數據庫本身的最佳排序規則是什麼?PostgreSQL 文件說:
C 和 POSIX 排序規則都指定了“傳統 C”行為,其中只有 ASCII 字母“A”到“Z”被視為字母,並且嚴格按字元程式碼字節值進行排序。
我認為這是這種情況下的最佳選擇,還是我錯了?
(獎勵問題:在查詢本身中選擇排序規則是否太慢?)。
**
C
**排序規則是正確的選擇。沒有語言環境,一切都會快一點。並且由於無論如何沒有排序規則是正確的,因此創建沒有排序規則的數據庫,即使用
C
.必須為許多操作提供排序規則可能會很痛苦。不過,預設排序規則和臨時排序規則之間的速度不應該有明顯差異。畢竟它只是未排序的數據,排序時會應用排序規則。
請注意,Postgres 建立在底層作業系統提供的語言環境設置之上,因此您需要為要使用的每個語言環境生成語言環境。更多關於 SO here和here的相關答案。
但是,正如@Craig 已經提到的那樣,索引是這種情況下的瓶頸。在涉及字元數據的許多情況下,索引的排序規則必須與應用運算符的排序規則相匹配。
您可以
COLLATE
在索引中使用說明符來生成匹配索引。如果您在同一個表中混合數據,部分索引可能是完美的選擇。例如,具有國際字元串的表:
CREATE TABLE string ( string_id serial ,lang_id int NOT NULL ,string text NOT NULL );
而且您一次最感興趣的是一種語言:
SELECT * FROM string WHERE lang_id = 5 -- 5 being German / Germany here AND string > 'foo' COLLATE "de_DE" ORDER BY string COLLATE "de_DE";
然後創建部分索引,如:
CREATE INDEX string_string_lang_id_idx ON string (string COLLATE "de_DE") WHERE lang_id = 5;
您需要的每種語言都有一個。
實際上,對於這樣的表,繼承可能是一種更好的方法。然後,您可以在每個繼承的表上擁有一個純索引,該索引僅包含單個語言環境的字元串。當然,您需要熟悉繼承表的特殊規則。