mysql 帖子、评论和回复的数据库模式设计

d8tt03nd  于 2022-11-21  发布在  Mysql
关注(0)|答案(3)|浏览(684)

在我以前的项目中,我将帖子和评论分为两个表:
张贴

  • 标识符
  • 正文
  • 时间戳记
  • 用户标识

注解

  • 标识符
  • 讯息
  • 时间戳记
  • 用户标识
  • 后的

现在我需要设计对评论的回复。回复只有一个级别,所以用户只能回复评论,而不能回复。树结构只有一个级别深。我的第一个想法是对评论和回复使用同一个评论表。不过我添加了一个新列:
注解

  • 标识符
  • 讯息
  • 时间戳记
  • 用户标识
  • 后的
  • 父母推荐

回复已将parentcommentid设置为它们所属的父注解。父注解没有此ID(null)
检索给定帖子的评论很简单:
但是这次我需要另一个查询来找到评论回复。2这必须对每个评论都做:
这似乎不是一个好的解决方案,有没有办法让一个查询以正确的顺序返回完整的评论/回复列表?(由时间戳和嵌套决定)

kr98yfug

kr98yfug1#

您可以使用连接并在单个查询中获得结果,如下所示:

SELECT *, cc.message as replied_message 
    FROM `post` 
    JOIN comment as c 
      ON c.postid = post.id 
    JOIN comment as cc 
      ON cc.id = c.parentcommentid 
ORDER BY c.timestamp DESC, cc.timestamp DESC;

请注意,只有当一条评论只有一个回复时,它才能正常工作。此查询不支持对一条评论的多个回复

u1ehiz5o

u1ehiz5o2#

我 知道 这个 答复 是 多年 来 太 晚 了 , 但 希望 它 将 帮助 其他 人 面临 这个 问题 现在 。
我 想出 了 一 个 单一 的 表 和 一 个 单一 的 查询 , 返回 所有 的 结果 在 正确 的 顺序 , 我 在 我 自己 的 网站 上 使用 , 这 是 略有 不同 , 但 逻辑 可以 用来 适应 这个 问题 。
表格 名称 :注解

  • id/varchar ( 32 )
  • 用户 ID/整数 ( 10 )
  • 注解/文本
  • 排序/整数 ( 10 )
  • 第 二 次 排序/整数 ( 10 )
  • 来源/tinyint ( 4 )
  • 国家/tinyint ( 4 )
  • 创建/时间 戳
  • 已 编辑/时间 戳

在 ( id , ordering , ordering _ secondary , source ) 上 有 主键 , 因此 不会 插入 这 四 列 组合 得 重复 列 .
插入 注解 时 , 首先 检查 " 排序 " 并 将 新 注解 加 1 。

SELECT ordering FROM comments WHERE id="page id" AND source=0 ORDER BY ordering DESC LIMIT 1

中 的 每 一 个
例如 , " 源 " 列 将 为 " 0 " 表示 父 级 , " 1 " 表示 回复 。 因此 , 只需 插入 注解 , 并 为 特定 ID 上 的 每个 注解 增加 1 的 排序 值 。
插入 回复 注解 时 , 使用 与 父 注解 相同 的 " ordering " 值 , 但 增加 " ordering _ secondary " 列 。

SELECT ordering FROM comments WHERE id="page id" AND source=1 AND ordering="parent comment ordering" ORDER BY ordering DESC LIMIT 1

格式
因此 , 数据 如下 所 示 :

在 表 中 有 两 个 父 注解 和 对 第 二 个 父 注解 的 两 个 回复 。 没有 对 第 一 个 父 注解 的 回复 。
这种 方法 在 插入 时 的 开销 显然 要 稍微 大 一些 , 因为 您 必须 查找 " id " 上 最 后 一 个 注解 的 排序 值 , 但 查询 数据 很 简单 。

SELECT * FROM comments WHERE id=? ORDER BY ordering DESC, ordering_secondary ASC LIMIT 30

格式

r55awzrz

r55awzrz3#

如果您使用的数据库支持JSON或对象聚合,则可以从查询中获得更好的结果,其中每个顶级注解都是一行(并且不重复),并且回复嵌套在每行内的数组/JSON中。
这使您可以灵活地使用它,也可以更容易地确保排序和嵌套正确。
使用Postgres的示例:

SELECT
  p.id AS post_id,
  c.id AS comment_id,
  c.message,
  JSON_AGG(
    JSON_BUILD_OBJECT('comment', r.comment, 'timestamp', r.timestamp)
    ORDER BY r.timestamp
  ) AS child_comments
FROM
  post AS p
  INNER JOIN comment AS c
    ON c.post_id = p.id
  LEFT JOIN comment AS r
    ON r.parent_id = c.id
WHERE
  post.id = <some id>
  AND c.parent_id IS NULL
GROUP BY
  post.id,
  c.id,
  c.message
ORDER BY
  c.timestamp DESC
;

请注意,如上所述,此示例将只检索顶级及其第一级答复。它不会获取对答复的答复。您可以使用递归命令或其他子查询来执行此操作。

相关问题