我有一個用PHP編寫的網站。它目前使用MySQL來滿足所有的數據庫需求(我可以使用其他數據庫技術)。我應該如何存儲非樹分層數據(即任何通用圖)?
系統的內容是相互關聯的。這些關係可以表示爲一個圖,其中頂點是內容片段,邊是關係。我需要能夠遍歷該圖。我特別需要能夠:
- 得到孩子數在給定的深度(例如許多grandchildrean如何確實有一個項目)
- 獲取累積孩子數在給定的深度(例如有多少孩子和孫子們做的項目有)
- 獲取最大深度爲給定根(例如,什麼是該項目的最長路徑)
- 在給定的深度把孩子們(如誰是這個項目的孫子)
- 讓父母在特定的深度(例如,誰是這個項目的祖父母)
- 查看哪些狀態(如「隱藏」或「鎖定」)已從父母繼承。
因爲它是一個動態的系統上的圖形,而不是一棵樹或傳統的等級,也有我認爲排除通常的基於SQL的技巧(例如鄰接表和路徑枚舉)的一些複雜性。
主余光中:
內容可以有不止一個孩子。
內容可以有多個父母。
對於每個用戶,項目的關係圖可能看起來不同。例如,某些內容可能對一個人隱藏,而對另一個人隱藏。
項目可以在圖樹上多次出現,並且可以以不同的路徑長度出現(例如,項目50可以是直接孩子,同時也是第三代孩子)。
圖可以包含數十萬個項目。
一些額外的余光中:
不同類型的內容可以與(如,民意調查可能與一個論壇帖子,或用戶可能與社區)
有幾種不同類型的關係(如,父/子關係,產權關係,同伴關係)
根據關係的類型,許可和限制可能會或可能不會從父母傳遞給孩子(例如,如果父母是隱藏的,孩子會被隱藏好,但如果對等項目被隱藏的狀態不是一起傳送)
我天真(慢)「解決方案」
目前我正在採用SQL的天真方法。我有這些列一個「關係」表:
item1ID (int)
item1TypeID (int)
item2ID (int)
item2TypeID (int)
relationshipTypeID (int)
在PHP,我動態生成的查詢充滿內心的聯接來查找最大深度,然後一旦被想通了,我生成一個查詢它遍歷層次結構並檢索我需要的任何信息。這已經太慢了,即使有適當的索引。
我的第二個簡單的方法是將存儲過程的遍歷和深度查找。我不知道這是否會帶來顯着的速度提升。我也在考慮採用某種緩存機制,這樣我就可以避免像往常一樣查找最大深度,但這似乎只是避免了真正的問題。
我的問題
必須有一個更好的辦法。它是什麼?我知道StackOverflow已經有很多關於SQL中分層信息問題的問題和答案,但這不是很層次 - 它是一個完整的圖表。
由於我有強大的模型,我可以混合使用另一種數據庫技術來處理事情的關係,而不會破壞現有的代碼庫。我一直在研究NoSQL解決方案,但我幾乎不知道它們。我也聽說過「Graph Databases」(如Neo4J),它基於我所看到的名稱和幻燈片,聽起來就像我需要的。但是,我不知道哪些實際上足夠強大,可以堅持到底,哪些可以很好地利用PHP。
幫助我StackOverflow,你是我唯一的希望。