Collation

是否有任何 DBMS 具有區分大小寫和不區分重音的排序規則?

  • July 26, 2016

請注意,此問題與供應商/版本無關

在我看來,作為一名說英語的人(打字員、作家),期望單詞大小寫正確但不一定有正確的口音走向正確的方向是合理的:

當我在香榭麗舍大街餐廳與酒店領班克洛伊(Chloe)聊天時,在等待加孔(garcon)拿我的炒墨西哥胡椒醬時……

你明白了。

所以今天我想我想要一個搜尋條件來使用區分大小寫但不區分重音的排序規則,但找不到。這是否有充分的理由,或者我的只是一個罕見的案例?


這是我正在查看的一些文件的範例(儘管認為與供應商/版本無關):

SQL Server 排序規則名稱 (SQL Server 2008 R2)

TL; 博士

沒有“與供應商無關”的排序規則視圖,甚至也沒有“與版本無關”,因為它們的實現——包括哪些方面可以變得不敏感以及它們的命名約定——是特定於供應商的,並且會隨著時間而變化.

這是我發現的摘要,詳細資訊在該行下方較長的部分中:

RDBMS        Naming-             Combinations    Case-Sensitive and
            convention          of options?     Accent-Insensitive support?
-------      ------------        -------------   -----
SQL Server   _CS, _AI, etc       Yes             Latin1_General_100_CS_AI

DB2          _E{x}, _S{y}, etc   Yes             CLDR181_EO_S1

PostgreSQL   locale: en_US       N/A             unaccent(), not via Collation

MySQL        _cs, maybe _ai      No              No: _cs implies _as & _ci implies _ai
                                                Yes? Create your own Collation :-)

Oracle       only _CI & _AI      No              No: _AI always implies _CI

SAP ASE      arbitrary: turdict  N/A             No: "AI" always implies "CI"

Informix     locale.codepage     N/A             No: no "AI" via Collations

正如您在圖表中看到的,七個 RDBMS 中的兩個確實通過排序規則原生支持“區分大小寫不區分重音”操作,儘管它們具有不同的命名約定(以及其他幾個功能差異)。

一個 RDBMS——PostgreSQL——本身並不支持這種組合,但您仍然可以通過使用unaccent()附加功能去除重音符號來實現它。

最後四個 RDBMS,其中兩個具有類似的選項命名約定,既不原生支持這種組合,也似乎沒有一種方法可以在不編寫自己的函式來刪除重音符號/變音符號的情況下完成此操作。MySQL 允許創建您自己的排序規則,但這需要您將其添加到原始碼控制並將其合併到您的測試和部署過程中,以便它可以應用於所有環境中的所有伺服器(但仍然是一個非常酷和靈活的選項) . SAP ASE 提到 SAP可以提供額外的 Unicode 排序順序,但沒有提到他們可能願意提供什麼。

關於:

這是否有充分的理由,或者我的只是一個罕見的案例?

我可以說,在對這個答案進行研究時,我遇到了很多人想要 MySQL 不區分大小寫和區分重音的實例,但很少有人(如果有的話)要求你想要的組合。


我想要一個搜尋條件來使用區分大小寫但不區分重音的排序規則,但找不到。

這個問題與供應商/版本無關

您的搜尋沒有成功,因為根據排序規範查找 RDBMS 沒有任何意義。這不是排序規則的工作方式。儘管您希望將此視為與供應商無關,但現實情況是排序規則(至少是我們與之互動的部分)非常特定於供應商,並且並不總是適合您正在搜尋的方案.

字元串比較和排序非常複雜,並且有不同的方式來執行這些規則。一種方法是使用考慮到一個或多個規則的映射。因此,區分大小寫和重音的 Sensitive 和 Insensitive 的四種組合將等同於四個單獨的映射。例如,您在SQL Server Collat​​ion Name的 MSDN 頁面上看到了這一點。如果向下滾動,您將看到圖表的左列是Sort Order ID。每個 Collat​​ion 都有不同的 ID:SQL_Latin1_General_Cp1_CI_AS= 52 而SQL_Latin1_General_Cp1_CS_AS= 51,即使唯一的區別在於區分大小寫。

或者,它可以是基於規則的,例如 Unicode 通過 Unicode Collat​​ion Algorithm (UCA) 提供的功能。在這種方法中,預設情況下,每個字元都被賦予一個或多個權重。然後,每種文化/語言環境都可以選擇覆蓋任何這些權重、刪除規則或添加規則。該算法會考慮任何特定於語言環境的規則,然後可能會根據選擇的任何選項(敏感性,在進行區分大小寫的排序時哪個大小寫優先等)來操縱這些權重。這就是為什麼進行 Unicode 排序比非 Unicode 排序慢一點的原因之一。

要了解實際有多少選項(即實際複雜性),請查看 ICU(Unicode 的國際組件)項目中的這個展示:

ICU零食展示

有 8 個單獨的選項要指定,其中一些在您正在考慮的排序規則名稱規範的多個元素中表示(例如CS,、、、CIASAI。考慮到有多少變化,使用每個組合都有自己的 ID 的映射文件方法會產生數千個文件。每當這些特定語言發生更改或發現錯誤時,其中許多文件都需要更新。這可能就是為什麼在 SQL Server 2012 中只有 75 種類型的排序規則(即名稱以 開頭的排序規則SQL_)。因此沒有 的組合_CS_AI

以及為什麼您無法為基於 UCA 的排序規則找到該組合?好吧,SQL Server 2012 中有 3810 個排序規則不以 開頭SQL_,因此總共有 3885 個排序規則。該列表似乎太長,無法在網頁上完全列舉。但這並不能完全解釋為什麼您找不到其他供應商的這種組合。

除了已經提到的(即要實現的組合太多,以及要列出的實現太多)之外,您仍然需要與特定於供應商的實現作鬥爭。含義:並非所有供應商都允許定制所有這些選項,並且首先沒有排序規則的標準命名約定。此外,並非所有供應商都將排序選項視為排序規則的一部分:PostgreSQL 排序規則是所選語言環境的預設排序,您需要使用它ILIKE來獲得不區分大小寫的比較。有關特定於供應商的資訊,請參見下文。

SQL 伺服器(微軟)

您在這兩個 MSDN 文件頁面上看到的內容與@MartinSmith 在對該問題的評論中提供的查詢之間的區別(下面稍作修改):

SELECT *
FROM   sys.fn_helpcollations()
WHERE  [name] LIKE '%[_]CS[_]AI%';

是這兩個 MSDN 頁面專門指的是非常不推薦使用的 SQL Server 排序規則,而作為該查詢結果顯示的排序規則(其中 888 個從 SQL Server 2012,SP3 開始)是 Windows 排序規則。

從 SQL Server 2000 開始,舊的 SQL Server 排序規則(在 SQL Server 能夠利用 Windows 排序規則之前創建)已被棄用,並且不會使用新規則或功能進行更新。例如,從 SQL Server 2012 開始,添加了一組排序規則,支持正確處理補充字元的內置函式(即 UCS-2 中最初定義的“基本”65,536 個字元之外的剩餘 UTF-16 字元)。這些較新的排序規則以_SC(如在補充字元)結尾。

最好不要使用 SQL Server 排序規則 - 名稱以 . 開頭的排序規則SQL_。因此,您確實可以訪問大量支持您正在尋找的選項組合的排序規則(即區分大小寫和不區分重音)。只要可用,最好也使用一端,_SC只要它具有您想要的所有其他選項。

雖然 SQL Server 確實使用_CS_AI命名約定,但沒有列出所有 3810(自 SQL Server 2012 起)Windows 排序規則。只有Windows 排序規則名稱頁面列出了所有語言環境和版本,以及命名約定的工作方式,但僅此而已。

SQL Server 還支持切換寬度和假名敏感度。

MySQL(被甲骨文收購)

MySQL 5.7 版文件聲明它確實支持_ai_as_ci_cs後綴(並且_bin為了完整性),但也聲明:

對於未指定區分重音的非二進制排序規則名稱,它由區分大小寫決定。也就是說,如果排序規則名稱不包含_aior _as_ci則顧名思義_ai_cs顧名思義_as

例如,latin1_general_ci不區分大小寫(隱式不區分重音),區分大小寫(隱式區分latin1_general_cs重音)

這當然意味著可以有一個latin1_general_cs_ai排序規則。但是,我有權訪問的 MySQL 5.5.50 伺服器沒有任何具有多個後綴的排序規則,我看到的唯一後綴是:、、總共 198 個排序規則。我使用SHOW COLLATION命令列出它們。_cs``_ci``_bin

因此,雖然聽起來 MySQL 使用了類似的命名約定(至少就這兩個選項而言),但我找不到與您正在尋找的內容匹配的排序規則。但是,有可能去掉重音符號(和其他變音符號)並使用_cs排序規則來獲得你想要的東西(類似於你在 PostgreSQL 中的做法——見下文)。但我不確定這個選項,目前沒有時間進一步研究。

或者,您可以創建自己的排序規則來完全按照您的意願行事。與其他 RDBMS 不同,MySQL 似乎使添加自己的排序規則變得相當簡單,在這種情況下,您可以完全控制每個字元的權重。有關詳細資訊,請參閱向 8 位字元集添加簡單排序規則向 Unicode 字元集添加 UCA 排序規則

有關 MySQL 如何處理不同類型的排序規則的更多資訊,請參閱他們的排序規則實現類型頁面。

PostgreSQL

PostgreSQL 中的排序規則似乎遠沒有那麼靈活。您僅指定文化/語言環境:en_US、、de_DE等。有關詳細資訊,請參閱他們的文件頁面以獲取排序規則支持。因此,預設情況下,您會獲得特定於文化的覆蓋,但排序規則對所有內容都敏感(順便說一下,與“二進制”排序規則不同)。

您可以使用ILIKE(第 9.7.1 節)來獲得不區分大小寫的功能,但它們沒有類似的區分重音的運算符。但是,我發現它們確實具有非重音功能,可用於去除重音和其他變音符號。請注意,此功能是附加提供的模組,因此不一定存在於任何要使用的特定 PostgreSQL 伺服器中。最近連結的文件指出:

從原始碼分發建構時,這些組件不會自動建構,除非您建構“世界”目標

……

如果您使用的是 PostgreSQL 的預打包版本,這些模組通常作為單獨的子包提供,例如postgresql 貢獻。

如果您沒有並且想要它,請參閱該文件以獲取有關如何獲取該功能的說明。

更多資訊也可以在以下 Stack Overflow 答案中找到:

PostgreSQL 是否支持“不區分重音”排序規則?

DB2 (IBM)

與 Microsoft SQL Server 類似,DB2 有兩種排序規則:

  • “SYSTEM”排序規則,使用以下格式指定:SYSTEM_{codepage}_[optional-territory]. 這些不是很靈活,並且似乎不支持對大小寫、重音或任何內容進行定制敏感性。您可以在此處找到支持的排序規則列表:支持的區域程式碼和程式碼頁
  • 基於 Unicode 排序算法 (UCA) 的排序規則。這些確實支持相當多的剪裁。有關如何配置行為、命名約定和有效語言環境列表的詳細資訊,請參閱他們的基於 Unicode 排序算法的排序規則頁面。請注意,在表 1 中,第三行(“案例級別”)中的範例以:

將 Case Level 屬性設置為 on 並將 Strength 屬性設置為 primary level 將忽略重音但不會忽略大小寫。

這正是你要找的。但是,它的語法是: CLDR181_EO_S1. 這就是為什麼您的搜尋沒有找到與 DB2 相關的任何內容的原因。

甲骨文

Oracle 10g 增加了對重音不敏感比較和排序的支持。然而:

  • 他們只能選擇表示“不敏感”的操作:_CI_AI
  • 您一次只能指定其中一個選項
  • 不區分大小寫選項 – _CI– 仍然區分重音
  • 不區分重音選項 – _AI– “也始終不區分大小寫。” (引自他們的文件,連結如下)

有關更多詳細資訊和範例,請參閱他們的語言排序和字元串搜尋文件頁面。

SAP ASE(以前的 Sybase ASE,又名 Sybase)

ASE 支持每個語言環境/字元集的以下一種或多種敏感度組合:

  • 區分大小寫,區分重音
  • 不區分大小寫,區分重音
  • 不區分大小寫,區分重音,優先排序
  • 不區分大小寫,不區分重音

您可以在他們的選擇預設排序順序頁面上查看語言環境、字元集和可用排序順序之間的關係。您可以在其Collat​​ion Names and IDs頁面上查看完整的排序規則列表。

它們的排序規則命名約定是任意的,因為它們都是 4 - 8 個字元,並嘗試擷取語言環境名稱或程式碼頁以及某種排序意義。例如:

altnoacc== “CP 850 Alternative – 無重音”

rusdict== “俄語詞典排序”

dynix== “漢語拼音排序”

他們的Selecting the Default Unicode Sort Order頁面上有一條註釋說明:

您可以使用目錄中的外部文件添加排序順序$/collate/Unicode。名稱和排序規則 ID 儲存在syscharsets. 無需輸入外部 Unicode 排序順序的名稱,syscharsets即可設置預設的 Unicode 排序順序。

外部 Unicode 排序順序由 SAP 提供。不要嘗試創建外部 Unicode 排序順序。

尚不清楚 SAP 是否會提供外部排序順序以允許區分大小寫不區分重音。也許有一天我會給他們發電子郵件,詢問是否可以要求。

為了獲得所需的敏感度組合,您應該能夠創建一個標量使用者定義函式來去除重音符號和其他變音符號。

Informix(被 IBM 收購)

Informix 似乎大多只支持 Collat​​ion 的預設排序和比較行為。因此排序規則只是語言環境和字元集。區分大小寫是在數據庫級別處理的,預設情況下它們是區分大小寫的。您可以通過在語句中指定 NLSCASE INSENSITIVE將數據庫(不是表、列、查詢甚至謂詞)設置為不區分大小寫。CREATE DATABASE

雖然每個客戶端連接都可以覆蓋數據庫排序規則(區域設置和字元集),但似乎沒有辦法覆蓋區分大小寫的設置。並且,該NLSCASE選項的名稱中有“NLS”是有原因的:它只影響NCHARNVARCHAR數據;CHAR並且VARCHAR始終區分大小寫。

沒有解決重音敏感性問題,也沒有內置功能可以去除重音/變音符號。

Informix 排序規則命名約定是:

<lang>_<country>.<code set>

在哪裡:

  • <lang>= 2 個字母或 3 個字母的語言程式碼

  • <country>= 2 個字母的國家或地區程式碼

  • <code set>= 以下列 3 種等效方式之一指定的程式碼頁:

    • name: 8859-1
    • IBM CCSID 號的十進制值: 819
    • IBM CCSID 號的十六進制值: 0333

因此,以下三個語言環境規範都指的是完全相同的語言環境:

  • fr_fr.8859-1
  • fr_fr.819
  • fr_fr.0333

欲了解更多資訊,請參閱:

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