【发布时间】:2012-03-01 03:37:40
【问题描述】:
我正在用头撞什么东西,我想知道是否有比我更熟练的人可以帮助我。
我的目标是创建一个将评论评分系统考虑在内的评论线程。
首先我会解释一下我现在在哪里。
假设我们有一篇文章的评论线程,如下例所示。括号中的数字是该评论的 ID。 ID 由数据库自动分配,并随着发布的每个附加评论按时间顺序递增。评论文本前的破折号数代表评论深度。
(01)"This is a top level comment."
(02)-"This is a second level comment. A reply to the top level comment above."
(06)-"This is also a second level comment / another reply to comment 01."
(07)--"This is a reply to comment 06."
(03)"This is a different top level comment."
(05)-"This is a reply to the comment above."
(08)--"This is a reply to that comment in turn."
(10)---"This is a deeper comment still."
(04)"This is one more top level comment."
(09)-"This is one more reply."
我的第一个问题是以一种可以按正确顺序返回的方式存储这些数据。如果您只是存储一个深度场并按深度排序,它将首先带回所有顶级 cmets,然后是第二级 cmets,等等。这是不对的,我们必须返回完整的 cmets 仍然完好无损。
实现此目的的一种方法是存储每条评论的完整父辈。
Comment ID | Parentage
01 | (Comment 01 has no parent because it is top level)
02 | 01- (Comment 02 was a reply to comment 01)
03 |
04 |
05 | 03-
06 | 01-
07 | 01-06- (Comment 07 has two ancestors 01 and then 06)
08 | 03-05-
09 | 04-
10 | 03-05-08-
添加另一个评论记录就像从您正在回复的评论中获取父辈一样简单,并附加其 ID 以形成新的父辈。例如,如果我要回复评论 10,我会采用它的父母身份 (03-05-08-) 并附加其 ID (10-)。数据库会自动将其识别为第 11 条评论,我们会得到:
Comment ID | Parentage
01 |
02 | 01-
03 |
04 |
05 | 03-
06 | 01-
07 | 01-06-
08 | 03-05-
09 | 04-
10 | 03-05-08-
11 | 03-05-08-10-
现在,当我们订购 cmets 进行展示时,我们订购的是 Parentage 和 Comment ID 的串联,这给了我们:
Order by CONCAT(Parentage, ID)
Comment ID | Parentage | CONCAT(Parentage, ID)
01 | | 01-
02 | 01- | 01-02-
06 | 01- | 01-06-
07 | 01-06- | 01-06-07-
03 | | 03-
05 | 03- | 03-05-
08 | 03-05- | 03-05-08-
10 | 03-05-08- | 03-05-08-10-
11 | 03-05-08-10- | 03-05-08-10-11-
04 | | 04-
09 | 04- | 04-09-
这会产生与第一次演示完全相同的列表。将我们后来添加的注释 11 插入正确的位置:
(01)"This is a top level comment."
(02)-"This is a reply to the top level comment."
(06)-"This is another reply that was posted later than the first."
(07)--"This is a reply to the second level comment directly above."
(03)"This is a different top level comment."
(05)-"This is a reply to the comment above."
(08)--"This is a reply to the comment above."
(10)---"This is a deeper comment still."
(11)----"THIS COMMENT WAS ADDED IN THE EARLIER EXAMPLE."
(04)"This is one more top level comment."
(09)-"This is one more reply."
可以通过检查 CONCAT 字符串的长度并将 len(CONCAT(Parentage, ID)) 乘以设定的像素数来完成缩进。太好了,我们有一个存储 cmets 的系统,可以识别他们的出身。
现在的问题:
并非所有 cmets 都是平等的。需要一个评论评分系统来区分好的 cmets。假设每条评论都有一个点赞按钮。虽然我们想保留父母身份,但如果一条评论在同一级别有两个直接回复,那么我们希望首先显示点赞最多的那个。我将在下面的[方括号]中添加一些投票。
(01)"This is a top level comment." [6 votes]
(02)-"This is a reply to the top level comment." [2 votes]
(06)-"This is another reply that was posted later than the first." [30 votes]
(07)--"This is a reply to the second level comment directly above." [5 votes]
(03)"This is a different top level comment." [50 votes]
(05)-"This is a reply to the comment above." [4 votes]
(08)--"This is a reply to the comment above." [0 votes]
(10)---"This is a deeper comment still." [0 votes]
(11)----"THIS COMMENT WAS ADDED IN THE EARLIER EXAMPLE." [0 votes]
(04)"This is one more top level comment." [2 votes]
(09)-"This is one more reply." [0 votes]
在这个例子中,cmets (01) 和 (03) 都是顶级的,但是 (03) 有 [50 votes] 而 (01) 只有 [6 votes]。 (01) 出现在上面只是因为它是较早发布的,因此被分配了一个较小的 ID。同样,(02) 和 (06) 都是对 (01) 的回复,但必须重新排序以使得票最多的 (06) 上升到顶部。
我完全和完全地试图实现这一目标。
我想任何排序/重新排序和索引最好在评论投票而不是页面加载时完成,这样页面加载时间可以尽可能快,但除此之外我完全不知道!
您可以在可能的途径上提出的任何想法或启示都会真正减轻负担!一如既往地感谢您的帮助。
----------------------------------------------- ----------------------------------
编辑:针对@Paddy 的解决方案,
当我在模拟数据上运行下面@Paddy 提供的表达式时,我得到的第一个错误是:
"The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP or FOR XML is also specified."
这可以通过将 SELECT 'top 100%' 添加到递归成员定义中来解决。完成后,我收到错误:
'CommentTree' has more columns than were specified in the column list.
这可以通过在 CommentTree 规范中添加“级别”列来解决。然后打印数据,但它首先返回所有顶级 cmets,然后返回类似于(但实际上不匹配)正确排序顺序的内容。
数据是这样返回的:
ParentId | CommentId | Comment | Vote | Level
NULL | 1 | Text here | 6 | 0
NULL | 3 | Text here | 50 | 0
NULL | 4 | Text here | 2 | 0
4 | 9 | Text here | 0 | 1
3 | 5 | Text here | 4 | 1
5 | 8 | Text here | 0 | 2
8 | 10 | Text here | 0 | 3
10 | 11 | Text here | 0 | 4
1 | 2 | Text here | 2 | 1
1 | 6 | Text here | 30 | 1
6 | 7 | Text here | 5 | 2
我做错了什么还是@Paddy 错过了什么?请接受我的道歉,递归函数对我来说很新。
【问题讨论】:
-
@Tudor 这是谷歌几乎不可能的主要原因!我不知道“多级评论结构的概念”比线程更好的词,有什么想法吗?
-
@Atheist for Paytheist - 如何将数据转换到前端?获得确切的顺序可能会很棘手,但我认为你拥有所有数据来为你的展示建立一个树。
-
你不只是想要
ORDER BY Parentage, Vote DESC, ID,还是我错过了什么?
标签: mysql sql sorting hierarchical-data comments