我正在为一个网站(PHP/MySQL)创建一个评论区,用户可以在这里发表评论或者回复已经发布的内容。我了解到这有点棘手,因为像MySQL这样的RDBMS并不是真正为存储分层数据而创建的。我已经找到了4种解决问题的方法(邻接列表、路径枚举、嵌套集和闭包表)其中我选择了嵌套集(修改的预购树遍历)。我已经成功地完成了对根评论及其回复的提取和排序但我似乎找不到一种方法来按点(其他专栏)对评论进行排序父链接>子链接。
想象一张这样的桌子:
+-------------------------------+
| id | comment | lft | rgt | pts|
+-------------------------------+
+-------------------------------+
| 1 | abc | 1 | 8 | 3 |
+-------------------------------+
| 2 | 123 | 2 | 7 | 1 |
+-------------------------------+
| 3 | xyz | 3 | 4 | 5 |
+-------------------------------+
| 4 | www | 5 | 6 | 4 |
+-------------------------------+
| 5 | com | 9 | 10 | 9 |
+-------------------------------+
如果我通过"lft ASC"订购我得到了标准的时间顺序(从最老到最新):
(1) abc
--(2) 123
----(3) xyz
----(4) www
(5) com
如果通过"rgt DESC"我得到了opsite,即新的第一(最新到最旧):
(5) com
(1) abc
--(2) 123
----(4) www
----(3) wxy
所有这些都很有魅力。问题是我似乎找不到按点排序的方法。最终我想得到这样的订单:
(5) com (9 pts)
(1) abc (3 pts)
--(2) 123 (1 pts)
----(3) xyz (5 pts)
----(4) www (4 pts)
有什么方法可以让嵌套集模型像这样运行吗。如果可能的话,最好的方法是使用正确的查询,但如果这样的查询没有exist使用PHP对它们进行排序也是可以接受的(如果它使用了合理的资源弹药)。如果使用嵌套集模型这是不可能的,我想知道使用哪个模型来生成上面提到的所有注释排序方式。
我相信这可以归结为获取深度,然后按深度排序,然后点。
SELECT
c.*,
(COUNT(p.id) - 1) AS depth
FROM
comments AS c
LEFT JOIN comments AS p ON c.lft BETWEEN p.lft AND p.rgt
GROUP BY c.id
ORDER BY depth, c.pts DESC
将产生:
id comment lft rgt pts depth
5 com 9 10 9 0
1 abc 1 8 3 0
2 123 2 7 1 1
3 xyz 3 4 5 2
4 www 5 6 4 2