2012-08-30 32 views
2

我有一個對象(恰好是C#),其中大約有20個屬性是可空的布爾值。可能會有數百萬個這樣的對象持久存在SQL數據庫中(目前SQL Server 2008 R2,但將來可能需要支持MySQL)。實例本身相對較大,因爲它們包含一段文本以及一些其他不相關的屬性。在SQL中存儲多個可空布爾值的策略

對於給定的對象實例,大多數屬性大多數時間將是null

當用戶搜索這些對象的實例時,他們將選擇可能爲空的布爾屬性的1-3,並搜索其中至少有一個屬性爲非空(OR搜索)的實例。

我的第一個想法是將該對象持久化爲一個帶有可爲空的BIT列的單個表,表示可空的布爾屬性。但是,此策略需要每個BIT列一個索引,以避免在搜索時執行表掃描。此外,每個索引不會特別選擇,因爲每個索引只有三個可能的值。

有沒有更好的方法來解決這個問題?

+0

您可以考慮使用位向量但它會存儲空值的挑戰。 – Kash

+0

我幾乎想說創建另一個表來存儲非空值,因爲大多數屬性在大多數情況下都是空的。這應該減少你的索引大小。 – Kermit

回答

1

出於性能方面的原因,我建議您將表格拆分成兩個表格。

使用用於索引的位字段創建主鍵。讓另一張表具有附加數據(如段落)。使用WHERE條件的第一個條件,加入第二個條件以獲取所需的數據。喜歡的東西:

select p.* 
from BitFields bf join 
    Paragraph p 
    on bf.bfid = p.bfid 
where <conditions on the bit fields> 

與一羣二元/三元領域,我不認爲指數將有助於得多,所以查詢引擎將被訴諸全表掃描。如果你在一個表中放入位域,你可以將表存儲在內存中,並獲得良好的性能。

另一種方法是將字段存儲爲名稱值對。如果你真的有很多這樣的字段(比如數百或者數千),並且在給定的行中只有少數(比如說十幾個),那麼實體屬性值(EAV)結構可能會更好。這是一個包含三個重要列的表格:

  1. 實體ID(我稱之爲bfid以上)。
  2. 屬性ID(特殊屬性)
  3. 值(true或false)
+0

準確地+1我的邏輯。 – Kermit

+0

是的,這種類型的設置被用於很多明星數據庫模式,特別是當你有一組已知的組合。理論上,您可以預先列舉選項,然後使用多對一設置。不幸的是,由於給定的總體可能性是3^20,這不是完全可行的。不瞭解SQL Server,但某些版本的DB2可以對索引本身執行ANDing/ORing操作,這意味着您可能會在每列上創建單列索引。 –