[英]Hierarchical Data Structure Design (Nested Sets)
我正在設計一個分層數據庫結構的設計,該結構模擬包含產品的目錄(這與此問題類似)。 數據庫平台是SQL Server 2005,目錄非常大(750,000個產品,4個級別的8,500個目錄部分),但相對靜態(每天重新加載一次),所以我們只關心READ性能。
目錄層次結構的一般結構是: -
我們使用嵌套集模式來存儲層次結構級別,並將存在於該級別的產品存儲在單獨的鏈接表中。 因此,簡化的數據庫結構將是
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.