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 只是笼统地引用了它。
我正在尝试创建一个评论系统。
关于数据库设计的东西,我要评论(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 只是笼统地引用了它。