2个不同实体的评论系统

Comment system for 2 different entities

我正在尝试创建一个评论系统。

关于数据库设计的东西,我要评论(post篇):

TABLE `posts` (
 `post_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
 `post_text` text NOT NULL,
 `user_id` int(11) unsigned NOT NULL,
 PRIMARY KEY (`post_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;


TABLE `articles` (
 `article_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
 `article_text` text NOT NULL,
 `user_id` int(11) unsigned NOT NULL,
 PRIMARY KEY (`article_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;


问题
每条评论都应链接到 post 或文章。

我的尝试

选项一
我把 article_id 和 post_id 的可能性放到同一个 table 中,它们都可以留空。

TABLE `comments` (
 `comment_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
 `comment_text` text NOT NULL,
 `user_id` int(11) unsigned NOT NULL,
 `post_id` int(11) NULL,
 `article_id` int(11) NULL,
 PRIMARY KEY (`article_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

像这样,当文章被评论时会有 article_id,如果 post 被评论时会有 post_id。
但是,如果一个字段应该始终为 NOT NULL,那么将两个字段都保留为 NULL 是个好主意吗?

选项二
创建两个单独的 table。一篇用于 post 评论,一篇用于文章评论。

TABLE `article_comments` (
     `comment_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
     `comment_text` text NOT NULL,
     `user_id` int(11) unsigned NOT NULL,
     `article_id` int(11) NOT NULL,
     PRIMARY KEY (`article_id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;


TABLE `post_comments` (
         `comment_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
         `comment_text` text NOT NULL,
         `user_id` int(11) unsigned NOT NULL,
         `post_id` int(11) NOT NULL,
         PRIMARY KEY (`article_id`)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

像这样nobody,谁应该是NOT NULL就是NULL。
但是,我不知道这是否会成为性能问题,而且我很确定这会导致我的 PHP 内容出现大量重复。

有更好的方法吗?

我没有这方面的经验,非常感谢您的帮助!

这里有一些注意事项。

对象与关系映射

PHP 提供 OO 风格的编程,它允许您创建文章和 post 的抽象超级 class,然后通常可以将评论链接到它。不幸的是,像这样的 OO 结构不能很好地映射到关系数据库,所以你必须做出妥协。

访问数据的用例

您需要如何以及在何处访问评论数据。这可以驱动您构建数据的方式,并可能使您的数据去规范化并创建索引。

在何处实施数据完整性约束

能够让数据库在可能的情况下强制执行干净的数据是件好事,但在现实中这并不总是可能的(或者您必须像上面的第二个选项一样跳过箍)才能实现它。就个人而言,这是我不会费心让数据库为我管理它的情况之一,而是确保它在您的应用程序中得到适当的管理(和错误处理)。

最终,我没有找到一个正确的答案来解决这个问题。在您上面建议的两个选项中,选项 1 是我自己的偏好。但是,您应该考虑的另一种方法是将您的帖子和文章 table 合并为一个 'Content' table 和 content_type 属性 或类似的(这允许您用抽象的 superclass 和 PHP 中的具体的 sub-classes 对它们进行建模)。那么您的评论 table 只是笼统地引用了它。