定序限制與行為差異 - Amazon Aurora

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

定序限制與行為差異

Babelfish 使用 ICU 程式庫來支援定序。PostgreSQL 以特定版本的 ICU 建置,最多只能符合定序的一個版本。不同版本的變化不可避免,就像語言隨著時間演變,也會發生微小的變化。您下列清單中可以找到 Babelfish 定序的已知限制和行為變化:

  • 索引與定序類型相依性 – 依據 International Components for Unicode (ICU) 定序程式庫 (Babelfish 使用的程式庫) 的使用者定義類型索引,不會在程式庫版本變更時失效。

  • COLLATIONPROPERTY 函數 – 針對支援的 Babelfish BBF 定序實作定序屬性。如需詳細資訊,請參閱 Babelfish supported collations table

  • Unicode 排序規則差異 – SQL Server 的 SQL 定序將 Unicode 編碼的資料 (ncharnvarchar) 排序的方式不同於非 Unicode 編碼的資料 (charvarchar)。Babelfish 資料庫一律為 UTF-8 編碼,且不論資料類型為何,一律以一致的方式套用 Unicode 排序規則,因此 charvarchar 的排序順序與 ncharnvarchar 的相同。

  • 第二級相等定序與排序行為 – 預設 ICU Unicode 第二級相等 (CI_AS) 定序將標點符號和其他非英數字元排在數值字元前面,並將數值字元排在字母字元前面。但是,標點符號和其他特殊字元的順序不同。

  • Tertiary collations, workaround for ORDER BY – SQL 定序 (例如 SQL_Latin1_General_Pref_CP1_CI_AS) 支援 TERTIARY_WEIGHTS 函數,且能夠將 CI_AS 定序中視為同等的字串排序為大寫優先:ABCABcAbCAbcaBCaBcabC,最後是 abc。因此,DENSE_RANK OVER (ORDER BY column) 分析函數將這些字串評估為相同等級,但在分割區內以大寫優先來排序。

    在 Babelfish 中,您可以在指定第三級 CS_AS 定序的 ORDER BY 子句中,新增 COLLATE 子句來指定 @colCaseFirst=upper,以獲得類似的結果。不過,colCaseFirst 修飾詞僅適用於第三級相等的字串 (而不是第二級相等,例如 CI_AS 定序)。因此,您無法使用單一 ICU 定序來模擬第三級 SQL 定序。

    為了解決這種情況,建議您將使用 SQL_Latin1_General_Pref_CP1_CI_AS 定序的應用程式修改成優先使用 BBF_SQL_Latin1_General_CP1_CI_AS 定序。然後將 COLLATE BBF_SQL_Latin1_General_Pref_CP1_CS_AS 新增至此資料欄的任何 ORDER BY 子句。

  • 字元擴充 – 字元擴充將單一字元視為等同於主要層級的一連串字元。SQL Server 的預設 CI_AS 定序支援字元擴展。ICU 定序僅支援不區分重音定序的字元擴展。

    需要字元擴充時,請使用 AI 定序來做比較。不過,LIKE 運算子目前不支援這種定序。

  • char 與 varchar 編碼 – 當 SQL 定序用於 charvarchar 資料類型時,ASCII 127 之前的字元由該 SQL 定序的特定字碼頁決定排序順序。使用 SQL 定序時,宣告為 charvarchar 的字串與宣告為 ncharnvarchar 的字串,可能以不同方式排序。

    PostgreSQL 使用資料庫編碼將所有字串編碼,因此會將所有字元轉換為 UTF-8,並根據 Unicode 規則來排序。

    因為 SQL 定序使用 Unicode 規則來排序 nchar 和 nvarchar 資料類型,所以 Babelfish 使用 UTF-8 將伺服器上的所有字串編碼。Babelfish 使用 Unicode 規則來排序 nchar 和 nvarchar 字串的方式,同於排序 char 和 varchar。

  • 補增字元 – SQL Server 函數 NCHARUNICODELEN 支援 Unicode Basic Multilingual Plane (BMP) 以外字碼指標的字元。反之,非 SC 定序使用代理配對字元來處理增補字元。對於 Unicode 資料類型,SQL Server 可以使用 UCS-2 來表示最多 65,535 個字元,或者,如果使用增補字元,則表示完整的 Unicode 範圍 (1,114,114 個字元)。

  • 區分假名 (KS) 定序 –「區分假名」(KS) 定序會將 HiraganaKatakana 日文假名字元視為不同。ICU 支援日文定序標準 JIS X 4061。現在已棄用的 colhiraganaQ [on | off] 地區設定修飾詞可能有同於 KS 定序的功能。不過,Babelfish 目前不支援與 SQL Server 同名的 KS 定序。

  • 區分寬度 (WS) 定序 – 將單一位元組字元 (半形) 和以雙位元組字元 (全形) 表示的同一個字元視為不同時,定序就稱為區分寬度 (WS)。不過,Babelfish 目前不支援與 SQL Server 同名的 WS 定序。

  • 區分變化選擇器 (VSS) 定序 – 區分變化選擇器 (VSS) 定序會區分日文定序 Japanese_Bushu_Kakusu_140Japanese_XJIS_140 中的表意變化選擇器。變化序列由一個基本字元加上一個額外的變化選擇器組成。如果您未選取 _VSS 選項,則做比較時不會考慮變化選擇器。

    Babelfish 目前不支援 VSS 定序。

  • BIN 與 BIN2 定序 – BIN2 定序根據字碼指標順序來排序字元。UTF-8 的逐位元組二進制順序保留 Unicode 字碼指標順序,因此這也可能是表現最佳的定序。如果 Unicode 代碼指標順序適用於應用程式,請考慮使用 BIN2 定序。不過,使用 BIN2 定序可能會導致資料在用戶端以超出文化預期的順序顯示。隨著時間經過,Unicode 中也增加對小寫字元的新映射,因此 LOWER 函數在不同版本的 ICU 上可能有以不同方式運作。這是較常見定序版本控制問題的特殊情況,而不是 BIN2 定序所獨有。

    Babelfish 隨著 Babelfish 發佈而提供 BBF_Latin1_General_BIN2 定序,以依照 Unicode 代碼指標順序來排序。在 BIN 定序中,只有第一個字元排序為 wchar。剩餘的字元逐位元組來排序,實際上是依照符合其編碼的代碼指標順序。這種作法未遵循 Unicode 定序,Babelfish 並不支援。

  • 非確定性定序和 CHARINDEX 限制 – 對於早於第 2.1.0 版的 Babelfish 版本,您無法將 CHARINDEX 與非確定性定序搭配使用。預設情況下,Babelfish 使用不區分大小寫 (非確定性) 定序。對舊版 Babelfish 使用 CHARINDEX 會造成下列執行時間錯誤:

    nondeterministic collations are not supported for substring searches
    注意

    此限制和解決方法僅適用於 Babelfish 1.x 版 (Aurora PostgreSQL 13.x 版)。Babelfish 2.1.0 及更新版本沒有此問題。

    您可以透過以下其中一種方法解決此問題:

    • 將表達式明確轉換為區分大小寫的定序,並套用 LOUP 或 UPER 將這兩個參數進行大小寫折疊 (case-fold)。例如,SELECT charindex('x', a) FROM t1 會變成下列:

      SELECT charindex(LOWER('x'), LOWER(a COLLATE sql_latin1_general_cp1_cs_as)) FROM t1
    • 建立一個 SQL 函數 f_charindex,並將 CHARINDEX 呼叫替換為對以下函數的呼叫:

      CREATE function f_charindex(@s1 varchar(max), @s2 varchar(max)) RETURNS int AS BEGIN declare @i int = 1 WHILE len(@s2) >= len(@s1) BEGIN if LOWER(@s1) = LOWER(substring(@s2,1,len(@s1))) return @i set @i += 1 set @s2 = substring(@s2,2,999999999) END return 0 END go