Sql-Server

稀疏主鍵的適當表設計

  • August 11, 2017

在我的系統中,我有基於儲存在我的數據庫中的規則創建的臨時實體,並且這些實體沒有持久化。

現在,我需要儲存關於這些實體的資訊,因為它們是根據規則創建的並且沒有儲存,所以它們沒有 ID。

我想出了一個公式來根據用於生成它們的規則為這些臨時實體生成一個 ID id = rule id + "-" + entity index in the rule:. 此公式生成表單的唯一字元串164-3, 123-0, 432-2, etc...

我的問題是當我的鍵沒有關係或順序時,我應該如何建構我的表(關於主鍵和聚集索引)? 請記住,我只會(99.9% 的時間)使用上面提到的 id 查詢表。

經過大量閱讀後我想到的選項,但不知道哪個更好:

  1. 具有聚集索引的 varchar 列上的主鍵。-根據各種消息來源,由於碎片化和密鑰的廣泛性,這會很糟糕。此外,它們的格式對於排序也很奇怪。

  2. 沒有聚集索引(堆表)的 varchar 列上的主鍵。- 由於索引和碎片問題,根據各種來源也是一個壞主意。

  3. 具有聚集索引的標識 int 列,以及具有唯一索引的 varchar 列作為主鍵。- 在這裡看不到代理鍵的好處,因為它主要有助於範圍查詢和排序,我永遠不會根據這個鍵查詢表,因為它在任何時候都是未知的。

4)2列複合鍵:規則id +規則索引列。現在我沒有字元串,但我有兩列將被複製到 FK 和非聚集索引。另外我不確定在這種情況下我會使用什麼索引。

有人可以在這裡發光嗎?任何幫助表示讚賞。

  • 編輯

這是我在閱讀評論和理由後認為我將使用的內容:

clustered identity int Id as PK
non-clustered unique index on (rule id, index)

理由:

1 - 我經常rule id只查詢表,這就是為什麼它是最左邊的索引列;

2 - 該Id列可用於第一次查詢後的後續操作rule id(ID將儲存在客戶端);

3 - 我永遠不會index只查詢;

4 - 唯一索引保證插入的一致性,儘管它仍然比單個 int 慢;

我在考慮聚集 pk (rule_id, index)

去做。這真的不是什麼難事。(rule_id, index) 唯一標識一行,因此這應該是您的集群 PK,除非有一些令人信服的理由使用不同的設計。因為

我經常只通過規則 id 查詢表

rule_id 應該是索引中的前導列。這支持通過 rule_id 進行高效查找,並確保為同一 rule_id 插入多行的局部性。

為您的數據庫設計。數據庫端對應用端是否有意義並不重要。該理論遵循 Star Schema 設計,並包含 Durable Keys 等概念。但是,您當然可以根據需要混合搭配。:)

$$ VERSION: 1.1 $$

  • 可能是社區編輯
  • 重組格式更容易理解
  • 提供設計範例

規則:

  • 堆不會被恐懼,而是被設計掌握。

  • 應避免使用自然鍵。因為數據庫鍵對應用程序/使用者端沒有任何意義。

  • 任何基於 GUID 或字元串的主鍵/唯一鍵充其量都被認為是短期的。

    1. 它們只會導致資源浪費,浪費時間重新發明可以事先解決的問題。
    2. 此外,它們可能是偷偷摸摸的、卑鄙的自然密鑰,會削弱安全性並破壞關係數據庫的目的。
  • 您必須在可行的、可擴展的設計範圍內定義您目前的並發和按比例收集規則和索引的範圍。

設計狀態: 為了實現這個目標,我們知道我們有許多出現和消失的 entity_index 實體。我們假設在這個設計中它們與 Rule_ID 有某種關係,甚至可能有一個現在或以後可以利用的分類比較。它們在技術上是否按“數字”順序是無關緊要的,因為這是數據庫。

此外,我們在概念上知道三個概念:規則、Entity_Indexes 和使設計更更改的映射機制。特別是優化器。不能說這種設計應該首先為數據庫服務。

概念範例:

CREATE TABLE Rules_DIM
(
   Rule_ID         INT
 , Rule_Name       VARCHAR(255)
 , <Details>
)
GO
/*
EntityIndex Key is not related to GUID that identifies this key
It helps identifiy like RuleID's and their EntityIndexes
It can and SHOULD be limited in number to an INT
 Since this is the database key
 Unless you have determined Rule_ID can be mapped to more than
 5 billion Entity_Indexes CONCURRENTLY
*/
CREATE TABLE EntityIndex_DIM
(
   EntityIndex_ID  INT -- database_key.
   EntityIndex_GUID    VARCHAR(<some_length>)
    /*Can be an actual GUID or what maps to the APP*/
 , <Details>
)
/*Our Mapping Table*/
CREATE TABLE Rule_Mapping
(
   RuleID
 , EntityIndex_ID
 , Create_Date
 , <some other Mapping column that is not related to the EntityIndex_DIM table
)

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