所以我認爲我的問題可以歸結爲兩個問題:鄰接表模型的兩個表
如何構建在PHP一筆畫樹結構,當樹存儲在MySQL(兩個表之間)使用鄰接列表模型的方法,同時記住性能?
什麼是可維護的方法來顯示所需格式的樹而無需重複遍歷代碼並使用if/else和switch語句亂拋垃圾?
以下是詳細信息:
我使用Zend框架。
我正在進行問卷調查。它存儲在兩個單獨的表之間的MySQL數據庫中:questions和question_groups。每個表擴展適當的Zend_Db_Table_ *類。層次結構使用鄰接列表模型方法表示。
我意識到我遇到的問題可能是由於我正在將樹結構填充到RDBMS中,所以我打開替代方案。不過,我也在存儲問卷調查回覆者和他們的回覆,因此替代方法需要支持。
問卷需要顯示在各種HTML格式:
- 作爲進入與問題(和一些基團)的反應(用Zend_Form的)
- 作爲有序列表(嵌套的)形式作爲按問題或按組查看回復的鏈接。
- 作爲一個有序列表(嵌套),每個問題都附有回覆。
問題是葉節點,question_groups可以包含其他question_groups和/或問題。綜合起來,有超過100行要處理和顯示。
目前,我有一個視圖助手,它使用遞歸來檢索question_group的子項(在兩個表之間執行UNION的查詢:QuestionGroup :: getChildren($ id))。另外,當顯示問卷回答的調查問卷時,需要額外的兩個查詢來檢索回答者以及他們對每個問題的回答。
雖然頁面加載時間不是很長,但這種方法感覺不對。遞歸加上多個數據庫查詢幾乎每個節點都不會讓我感到非常溫暖和模糊。
我試過recursion-less以及從UNION返回的完整樹數組的遞歸方法來構建一個遍歷和顯示的分層數組。但是,由於組和問題存儲在不同的表中,因此存在重複的節點標識,因此似乎會出現問題。也許我錯過了那裏的東西......
目前,以上面列出的格式顯示樹的邏輯相當混亂。我不想在遍地都重複遍歷邏輯。但是,遍佈各地的條件不會產生最易於維護的代碼。我已經閱讀了訪問者,裝飾器和一些PHP SPL迭代器,但我仍然不清楚這將如何與擴展Zend_Db_Table,Zend_Db_Table_Rowset和Zend_Db_Table_Row的類一起工作。特別是因爲我還沒有解決以前從數據庫構建層次結構的問題。很容易添加新的顯示格式(或修改現有的格式)。
謝謝比爾。我爲這兩個表添加了一個root_id列,並實現了您建議的方法(http://pastie.org/762955)。雖然我不能看到大局。該方法如何遍歷Rowset工作中處理樹的行遍佈兩個表?我假設fetchTreeByRootId()需要使用UNION。或者會創建一個視圖是一個更好的解決方案?雖然我喜歡能夠利用現有的類... – Lauren 2010-01-01 02:16:28
比爾,謝謝澄清。它的作品非常漂亮。我仍在致力於將葉子(問題)整合到組合中。一旦完成,我會發布我的最終解決方案。希望能夠讓可能遇到相同情況的其他人受益。 – Lauren 2010-01-05 12:33:12
我很高興它爲你工作。順便說一句,我改變了'initTree()'成爲'public'函數,因爲它必須由Table類調用。你可能已經找到了同樣的東西。 – 2010-01-05 15:38:14