2013-05-25 33 views
3

在以下情況:是否存在將冗餘數據存儲在數據庫中以提高速度的情況?

user has many bags 
bag has many items 

users 
-id 

bags 
-id 
-user_id 

items 
-id 
-bag_id 

有2種方式來獲得訪問用戶的項目。

1)可以將實例方法添加到用戶,該用戶遍歷每個用戶的行李,並將行李的物品收集到數組中以返回。在Ruby on Rails的,是這樣的:

#in user.rb 
def items 
    items = [] 
    bags.includes(:items).each { |bag| items += bag.items } 
end 

2)直接添加user_id屬性的項目表,並添加一個額外的關係,使user has many items。然後做user.items

的第二方法是更快的,但涉及到存儲冗餘數據。有沒有情況下實施它是有道理的?

回答

4

是的,有某些情況下,如果它確實是有意義的介紹一些控制冗餘的性能的原因。一般來說,這隻能在數據庫無法滿足其性能要求時才能完成。這就是所謂的「denormalisation」,你必須考慮什麼是它:

  • 可以使執行更加複雜的
  • 往往犧牲了靈活性
  • 可加速檢索,但放慢更新(因爲你現在有更新多個位置)

因此,在性能不理想,關係的更新率低和查詢率高的情況下需要考慮。

還有一些非規範化的數據庫設計,如星型模式,用於數據庫倉儲。

+1

請注意,如果你非規範化,必須使用觸發器,以確保非規範化的數據停留在同步,否則就會有數據完整性問題。 – HLGEM

0

對於組合來自兩個SQL表的記錄,數據庫實施有效的JOIN方法,該方法可以是used from Ruby on Rails。幾乎所有的應用程序都足夠快。也就是說,對於某些高性能商店,您可能希望按照您的建議存儲冗餘數據,但這是以保護數據在寫入時保持同步爲代價的。

1

除非有些事情你還沒有告訴我們,像這樣

create table bagged_items (
    user_id integer not null, 
    bag_id integer not null, 
    item_id integer not null, 
    primary key (user_id, bag_id, item_id) 
); 

表中至少5NF。這都是關鍵。那裏沒有多餘的數據。

你所做的不是標準化;規範化是基於識別某些種類的依賴關係,並通過投影來減少其影響。你所做的也不是反規範化,非規範化是對規範化的撤銷。

您只是簡單地將主鍵拆分成小塊。爲了證明這一點,我不假裝知道你遵循了什麼原則。它看起來有點像「沒有表可能有多個外鍵」的正常形式。 (但是,當然,有沒有這樣的事情。)

1

是。特別是報告數據庫,數據集市和數據倉庫通常使用明顯偏離一些規範化規則的設計原則。結果是一個數據庫有一些冗餘,但不僅查詢速度更快,而且更容易。

當數據庫和數據庫用戶之間存在分析GUI時,輕鬆查詢尤爲重要。如果在數據庫設計中遵循某些設計原則,這些分析工具就會容易掌握。標準化在這方面不是特別有用。

非規範化設計不一定意味着不規範的設計。尤其是,如果您打算構建報告數據庫,數據集市或數據倉庫,則值得關注星型模式和雪花模式設計。星形或雪花模式保持最新的過程(有時稱爲ETL(提取 - 轉換 - 加載))必須仔細編寫,以防止受控冗餘導致自相矛盾的數據。

在面向事務處理的數據庫中,標準化是普遍較好,但很多專家並不試圖把它超越BC範式。

相關問題