Sql-Server

避免在 SQL Server 的聯接中使用複雜的字元串?

  • November 25, 2017

我將在 SQL Server 中為客戶端創建幾個表。這個問題特別感興趣的是FactStoreSale要創建的表,其中第一個表將包括所有商店的銷售額,DimProduct並包括例如StoreKeyDateKey、和銷售數據。TimeKey``ProductKey

DimProduct表將使用關於產品的補充數據,即ProductNameProductGroupProductCategory。該表將是一個緩慢變化的維度,並根據每個商店的價格等儲存產品歷史記錄。該表將包括列FromDate,並ToDate分別描述輸入數據的時間和替換數據的時間(預設值為 2999 年,ToDate直到插入產品的新更新)。

我相信這很常見。但是,ProductKeys來自底層數據庫的 是非常複雜的字元串,例如140-xx4449CH-4.44,9.

我看到的替代方法是Checksum在 SQL Server 中使用將復雜的字元串轉換為整數,並將它們儲存在單獨的列中ProductKeyInt ,並在執行 JOINS 時使用這些列。但是校驗和不保證唯一的整數值,這可能會導致問題。當我在虛擬 PC 和我自己的 PC 上嘗試校驗和時,對相同的值執行校驗和會返回不同的結果,這也是一個問題。我相信這兩個一起排除了校驗和,除非它可以以某種方式被操縱以使其更加獨特?

另一種選擇是使用更複雜的函式來確保將字元串值轉換為整數,例如我的問題here中提供的那個。然而,諸如此類的解決方案也存在問題,例如值100-xx31003將獲得相同的結果。從某種意義上說,如果不是精通 SQL 的人需要嘗試查找使用該函式的 Query 的任何問題,那麼這也很複雜,可能很難理解正在發生的事情。

我的第三個選擇似乎是使用該DimProduct表並首先從 SQL 代理更新該表,並在該表上使用索引鍵並將該索引用作FactStoreSale表中的 ProductKeyInt(其中 ProductKeyInt 將是某種子查詢,例如FactStoreSale獲取與ToDateProductKey對應的DimProduct中最大的值。

有人有意見嗎?有沒有更簡單的方法?我不想將字元串作為 JOIN 鍵,因為例如增加了 CPU 時間

  1. 您不需要將該ProductKey列用作. 您可以創建一個代理鍵,它是一個複合鍵,它由一列和 SCD 的每一行遞增,以及每一個唯一的列組成。兩者都是(很可能,除非您永遠不會擁有很多獨特的產品,在這種情況下,我可能會選擇為您提供 65k 值的產品)。DimProduct``DimProductID``IDENTITY``ProductID``ProductKey``INT``SMALLINT``ProductID

這種方法使您既能夠引用產品的任何特定版本(使用IDENTITY列,或者兩者都可能更好地使用索引),並且能夠僅使用非聚合來聚合特定產品的所有版本-IDENTITY列。

在任何一種情況下,您通常都不需要在ProductKey列/值上加入。 2. 當您確實需要過濾或加入時ProductKey,假設大寫和小寫字母之間沒有功能差異,您應該強制所有內容為大寫使用二進制排序規則(任何以_BIN2, not_BIN結尾的排序規則最有可能Latin1_General_100_BIN2)。大多數人不考慮將排序規則用於包含字母數字程式碼的字元串列,其中沒有任何目的,以任何方式具有大小寫(或假名或寬度或重音不敏感)並且沒有目的評估複雜的語言規則,例如哪些字元序列等同於其他語言中的其他字元。非二進制排序規則有很多適用的複雜規則,而且這些規則需要時間。使用二進制排序規則會很多更快,因為它只是比較字節,這就是為什麼你需要強制大寫以防有人以小寫字母輸入字母字元。

因此,為此,請確保Latin1_General_100_BIN2在創建表時設置要使用的列的排序規則。如果表已經創建,使用ALTER TABLE ... ALTER COLUMN設置 Collat​​ion 以便預設使用。

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