簡體   English   中英

分層數據結構設計(嵌套集)

[英]Hierarchical Data Structure Design (Nested Sets)

我正在設計一個分層數據庫結構的設計,該結構模擬包含產品的目錄(這與此問題類似)。 數據庫平台是SQL Server 2005,目錄非常大(750,000個產品,4個級別的8,500個目錄部分),但相對靜態(每天重新加載一次),所以我們只關心READ性能。

目錄層次結構的一般結構是: -

  • 1級部分
    • 2級部分
      • 3級部分
        • 4級部分(產品鏈接到這里)

我們使用嵌套集模式來存儲層次結構級別,並將存在於該級別的產品存儲在單獨的鏈接表中。 因此,簡化的數據庫結構將是

CREATE TABLE CatalogueSection
(
    SectionID INTEGER,
    ParentID INTEGER,
    LeftExtent INTEGER,
    RightExtent INTEGER
)

CREATE TABLE CatalogueProduct
(
    ProductID INTEGER,
    SectionID INTEGER
)

我們確實有一個額外的復雜性,因為我們有大約1000個獨立的客戶群,這些客戶群可能會也可能不會看到目錄中的所有產品。 因此,我們需要為每個客戶組維護一個單獨的“副本”目錄層次結構,這樣當他們瀏覽目錄時,他們只能看到他們的產品,而且他們也看不到任何空的部分。

為了便於實現這一點,我們在下面的部分“維護”了一個層次結構的每個級別的產品數量表。 因此,即使產品僅直接鏈接到層次結構的最低級別,它們也會在樹中一直計算。 這個表的結構是

CREATE TABLE CatalogueSectionCount
(
    SectionID INTEGER,
    CustomerGroupID INTEGER,
    SubSectionCount INTEGER,
    ProductCount INTEGER
)

因此,對於問題 ,層次結構的頂層級別的性能非常差。 顯示所選目錄部分(以及所有子部分)中“前10名”產品的一般查詢正在1分鍾內完成。 在層次結構的較低部分,它更快但仍然不夠好。

我已經在所有關鍵表上放置了索引(包括適用的覆蓋索引),通過查詢分析器,索引調整向導等運行它,但仍然無法使其執行得足夠快。

我想知道設計是否存在根本缺陷,還是因為我們有這么大的數據集? 我們有一個合理的開發服務器(3.8GHZ Xeon,4GB RAM),但它只是不工作:)

謝謝你的幫助

詹姆士

使用閉包表。 如果基本結構是具有字段ID和ParentID的父子結構,則閉包表的結構是ID和DescendantID。 換句話說,閉包表是祖先 - 后代表,其中每個可能的祖先與所有后代相關聯。 如果需要,您可以包含LevelsBetween字段。 閉包表實現通常包括自引用記錄,即ID 1是子級ID 1的祖先,LevelsBetween為零。

示例:父/子
ParentID - ID
1 - 2
1 - 3
3 - 4
3 - 5
4 - 6

祖先/后代
ID - DescendantID - LevelsBetween
1 - 1 - 0
1 - 2 - 1
1 - 3 - 1
1 - 4 - 2
1 - 6 - 3
2 - 2 - 0
3 - 3 - 0
3 - 4 - 1
3 - 5 - 1
3 - 6 - 2
4 - 4 - 0
4 - 6 - 1
5 - 5 - 0

該表旨在消除遞歸連接。 您將遞歸連接的負載推送到每天加載一次數據時執行的ETL循環。 這使它遠離查詢。

此外,它允許變量級層次結構。 你不會被困在4。

最后,它允許您在非葉節點中插入產品。 許多目錄在層次結構的較高級別創建“雜項”存儲桶,以創建將產品附加到的葉節點。 您不需要這樣做,因為閉包中包含中間節點。

就索引而言,我會在ID / DescendantID上做一個聚簇索引。

現在為您的查詢性能。 這需要一大塊但不是全部。 你提到了“十大”。 這意味着對您未提及的一組事實進行排名。 我們需要細節來幫助調整這些。 另外,這只能獲得葉級部分,而不是產品。 至少,您應該在CatalogueProduct上有一個索引,它按SectionID / ProductID排序。 我會根據您提供的基數強制Section to Product連接成為循環連接。 關於目錄部分的報告將轉到閉包表以獲取后代(使用聚簇索引搜索)。 然后,該子列表將用於通過循環索引查找使用索引從CatalogueProduct獲取產品。 然后,使用這些產品,您將獲得進行排名所需的事實。

您可以使用角色和treeId來解決客戶群問題,但您必須向我們提供查詢。

可能在每天加載后計算ProductCount和SubSectionCount嗎?
如果數據每天只改變一次肯定值得計算這些數字,那么即使需要一些非規范化。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM