评论系统的 MYSQL 模式

标签 mysql database database-design schema

我在使用下表设置创建的应用程序上有一个基本的评论系统:

CREATE TABLE `meet_comment` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `meet_id` int(11) NOT NULL,
 `user_id` int(11) NOT NULL,
 `date_created` datetime NOT NULL,
 `comment` mediumtext NOT NULL,
 PRIMARY KEY (`id`),
 KEY `meet_id` (`meet_id`),
 KEY `user_id` (`user_id`),
 CONSTRAINT `meet_comment_ibfk_1` FOREIGN KEY (`meet_id`) REFERENCES `meet` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
 CONSTRAINT `meet_comment_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
meet_id是对用户正在评论的对象的引用。这很好用,尽管目前如果用户编辑评论我只是更新 comment field 。

如果评论被编辑,我希望能够查看评论历史记录,最好的方法是什么?我猜我需要另一个包含评论和引用的表 meet_comment.id ?也许像:

CREATE TABLE `meet_comment` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `meet_id` int(11) NOT NULL,
 `user_id` int(11) NOT NULL,
 PRIMARY KEY (`id`),
 KEY `meet_id` (`meet_id`),
 KEY `user_id` (`user_id`),
 CONSTRAINT `meet_comment_ibfk_1` FOREIGN KEY (`meet_id`) REFERENCES `meet` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
 CONSTRAINT `meet_comment_ibfk_2` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

CREATE TABLE `meet_comment_content` (
 `revision` int(3) NOT NULL,
 `meet_comment_id` int(11) NOT NULL,
 `date_created` datetime NOT NULL,
 `comment` mediumtext NOT NULL,
  UNIQUE KEY `revision_2` (`revision`,`meet_comment_id`),
 KEY `revision` (`revision`),
 KEY `meet_comment_id` (`meet_comment_id`),
 CONSTRAINT `meet_comment_content` FOREIGN KEY (`meet_comment_id`) REFERENCES `meet_comment` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

如果是这样,查询表的最佳方法是什么,我猜我可以通过连接来获取所需的数据?

最佳答案

修改历史导致拉锯战——

  • 简单与否
  • 规模效率,与否
  • 查询的复杂性,与否
  • 磁盘空间或膨胀

  • 考虑以下“一般”原则:

    有两个表:
  • Current -- 当前版本的评论
  • History --所有版本的评论
  • Current使主要查询更简单、更高效。

    创建或编辑评论意味着 INSERTUPDATECurrent ,加上(总是)一个 INSERT进入 History .
    History将具有与 Current 略有不同的架构,因为需要有一个修订号,可能还有其他日期/标志/等。

    这不解决磁盘空间;我怀疑你可以坚持一段时间,然后才需要担心这样的事情。一种技术是“压缩”主要 TEXT列并将其放入 BLOB . (注意:另一个模式差异。并增加了代码的复杂性。)典型的文本缩小了 3:1。

    旁注:int(3) -- (3)什么也没说。安 INT总是 4 个字节。建议使用 SMALLINT UNSIGNED , 占用 2 个字节,范围为 0..64K。

    我会放弃FOREIGN KEYs ,尤其是 CASCADE ;在这两个表中可能会有一些引用文献被纠缠在一起。无论如何,您需要仔细编写代码来处理各种任务,从而消除对 FK 的需求。

    每个表都应该有一个 PRIMARY KEY .对于数据的“聚类”,我推荐 (comment_id, revision) ,而不是相反。

    并且,考虑是否meet_id成为PK的一部分。

    关于评论系统的 MYSQL 模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61592813/

    相关文章:

    mysql - 其他函数,如 FIND_IN_SET,它返回逗号分隔列表中可用的字符串数量

    mysql - SQL:选择列值从上一行更改的行

    mysql - HAVING 子句影响结果

    sql - Visual Studio 的数据库设计器?

    sql-server - 数据库中用于生成主键的表?

    mysql - 如何获取mysql中两个表的列名?

    php - composer --create 命令在 laravel 4.2 中无法正常工作

    mysql - sql动态日期比较

    sql - 使用多个成本表计算用户的余额

    sql - 我怎样才能编写一个程序来获得级别 i 到 j 或像这样的树?