用于评论和评论回复的mysql结构

Den*_*nis 11 mysql join

我一直在考虑这个问题很长一段时间,我需要一种方法来添加对数据库中的注释的回复,但我不知道如何继续.

这是我目前的评论表(并没有多说但是它的开头):

CREATE TABLE IF NOT EXISTS `comments` (
  `id` int(12) NOT NULL AUTO_INCREMENT,
  `comment` text,
  `user_id` int(12) DEFAULT NULL,
  `topic_id` int(12) NOT NULL,
  `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `user_id` (`user_id`),
  KEY `topic_id` (`topic_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=27 ;
Run Code Online (Sandbox Code Playgroud)

这是我当前的查询:

SELECT c.id, c.comment, c.user_id, u.username, u.photo
FROM (comments c)
JOIN users u ON c.user_id = u.id
WHERE c.topic_id = 9
Run Code Online (Sandbox Code Playgroud)

一种选择是创建一个名为"comment_replies"的新表,但我不确定如果我能够在一个查询中选择所有注释和注释回复,并且如果我添加一个名为"回复"的新列我就是不确定如何对它们进行排序以获得每个回复的每条评论.

我想知道如何处理这个问题.

编辑:

下面的答案是关于在1条评论和2条回复中添加parent_comment_id结果的这种数组:

array(2) {
  [0]=>
  object(stdClass)#17 (7) {
    ["id"]=>
    string(2) "26"
    ["comment"]=>
    string(36) "adding a comment from the admin page"
    ["user_id"]=>
    string(2) "16"
    ["ts"]=>
    string(10) "1249869350"
    ["username"]=>
    string(5) "Admin"
    ["photo"]=>
    string(13) "gravatar2.png"
    ["reply"]=>
    string(23) "There is no admin page!"
  }
  [1]=>
  object(stdClass)#18 (7) {
    ["id"]=>
    string(2) "26"
    ["comment"]=>
    string(36) "adding a comment from the admin page"
    ["user_id"]=>
    string(2) "16"
    ["ts"]=>
    string(10) "1249869350"
    ["username"]=>
    string(5) "Admin"
    ["photo"]=>
    string(13) "gravatar2.png"
    ["reply"]=>
    string(13) "Yes there is!"
  }
}
Run Code Online (Sandbox Code Playgroud)

我应该如何处理这个数组来处理它,是否可以将评论与回复分开?

fla*_*yto 5

如果您希望人们能够回复回复(例如,您可以在在线消息论坛中看到回复的层次结构),那么我会在评论表中添加可选的parent_comment_id字段.

你的桌子看起来像这样

`CREATE TABLE IF NOT EXISTS `comments` (
  `id` int(12) NOT NULL AUTO_INCREMENT,
  `parent_comment_id` int(12) NULL,
  `comment` text,
  `user_id` int(12) DEFAULT NULL,
  `topic_id` int(12) NOT NULL,
  `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `user_id` (`user_id`),
  KEY `topic_id` (`topic_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=27 ;`
Run Code Online (Sandbox Code Playgroud)

您显示所有评论和回复的查询将类似于:

SELECT c.id, c.comment, r.comment as reply, c.user_id, u.username, u.photo
FROM (comments c)
JOIN users u ON c.user_id = u.id
LEFT JOIN comments r ON c.id = r.parent_comment_id
WHERE c.topic_id = 9
Run Code Online (Sandbox Code Playgroud)

但请注意,使用此查询,您的回复不仅会显示在"回复"列中,还会显示在"注释"列中,作为附加行,每个行都有零个或多个回复.

要显示回复评论的用户的用户名,您需要两次加入users表(首先是发布原始评论的用户,再次是为回复的用户).尝试此查询以显示回复的用户的用户名:

SELECT c.id, c.comment, c.user_id, u.username, u.photo, r.comment as reply, r.user_id as reply_user_id, 
u2.username as reply_username, u2.photo as reply_photo
FROM (comment c)
JOIN users u ON c.user_id = u.id
LEFT JOIN comments r ON c.id = r.parent_comment_id
JOIN users u2 ON r.user_id = u2.id
WHERE c.topic_id = 9
Run Code Online (Sandbox Code Playgroud)


Den*_*nis 3

我决定在数据库中添加parent_id列,而不是留下加入回复,我只是一次选择所有评论,以便稍后使用服务器端代码对评论和回复进行排序,查询如下:

SELECT c.*, u.username, u.photo
FROM (comments c)
JOIN users u ON c.user_id = u.id
WHERE c.topic_id = 9
ORDER BY c.id ASC
Run Code Online (Sandbox Code Playgroud)

现在我将查询结果传递给下面的函数,以便每个回复都将作为数组添加到注释数组中,所以基本上它返回一个多维数组。

function sort_comments($ar)
{
    $comments = array();
    foreach($ar as $item)
    {
        if(is_null($item['parent_id'])) $comments[] = $item;
        else 
        {
            $parent_array = array_search_key($item['parent_id'],$comments,'id');
            if($parent_array !== false) $comments[$parent_array]['replies'][] = $item;
        }
    }
    return $comments;
}
Run Code Online (Sandbox Code Playgroud)

  • 什么是函数 `array_search_key` - 它不是 PHP 标准库函数 (3认同)