我正在尝试创建一个评论系统。
数据库设计的东西,我想评论(帖子和文章):
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;
问题
每条评论都应与帖子或文章相关联。
我的尝试
选项1
我将article_id和post_id的可能性放在同一个表中,它们都可以留空。
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_id。
但是如果一个字段永远不是NULL,那么将这两个字段保留为NULL是个好主意吗?
选项2
创建两个单独的表。一个用于发表评论,一个用于文章评论。
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;
像这样的人,谁应该是NOT NULL是NULL
但是,我不知道这是否会成为一个性能问题,我很确定这会导致我的PHP内容中出现大量重复。
有更好的方法吗?
我没有这方面的经验,非常感谢你的帮助!
答案 0 :(得分:2)
这里有一些注意事项。
对象与关系映射
PHP提供OO风格的编程,允许您创建一个抽象的超类文章和帖子,然后通常可以链接到哪些评论。不幸的是,像这样的OO结构并不能很好地映射到关系数据库,所以你必须妥协。
用于访问数据的用例
您需要如何以及在何处访问评论数据。这可以推动您构建的方式,并可能使数据非规范化并创建索引。
强制执行数据完整性约束的位置
能够让数据库在可能的情况下强制执行干净的数据是很好的,但实际上这并不总是可行的(或者你必须像上面的第二个选项那样跳过箍)来实现它。就个人而言,这是我不愿意让数据库为我管理它的情况之一,而是确保在您的应用程序中适当地管理(和处理错误)。
最终,我没有遇到过这个问题的正确答案。在您建议的两个选项中,选项1将是我自己的偏好。但是,您应该考虑的另一种方法是将您的帖子和文章表合并为一个内容'具有content_type属性或类似属性的表(允许您使用PHP中的抽象超类和具体子类对它们进行建模)。那么你的评论表只是引用了这一点。