您应该将 'Likes' table 拆分为多个 table 吗?

Should you split a 'Likes' table into multiple tables?

假设我有一个类似于 Instagram 的社交网络应用程序。对于我的数据库模式,我会做这样的事情:

CREATE TABLE `likes` (
  `like_id` int PRIMARY KEY AUTO_INCREMENT,
  `user_id` int,
  `type` ENUM ('POST', 'COMMENT'),
  `target_id` int
);

其中 target_id 是指向特定 post 或特定注释的外键。将 post 和评论赞合并为一个 table 并通过类型 ENUM 区分它们是不是一个糟糕的设计?创建两个 tables: commentLikes 和 postLikes 没有区别会更好吗?

请记住,我确实预见到将来可能会向应用程序添加更多他们可能喜欢的功能,例如文章或食谱等

你的方法很好。不幸的是,您想要做的在 SQL 中并不简单。理想情况下,您希望在 target_id 和它引用的 table 之间建立外键关系。用你的结构,这是不可能的。

但是,您的方法确实具有简洁的优势——无论是在 table 定义还是在基础 table 布局中。代价是无法声明外键关系。

编辑:

如果有一个简单的替代方案,我会推荐它。您可以为每个外键关系创建一个单独的列,但这不仅占用了 space,而且还增加了添加新关系的难度。您可以为外键生成一个列,但这相当麻烦,并且应该为外键关系保留这些列。

没有最优解,你的版本没问题。其他解决方案也很好,具体取决于您需要解决方案做什么。

虽然我喜欢你所拥有的内容的简洁性,但我建议将评论赞、帖子赞等 table 彼此分开。这样,查看您的数据库的人就可以看到评论 table 并找到喜欢的评论 table,并且可以轻松理解正在发生的事情。

加入 table 时,在查询中加入评论 table 和喜欢的评论更容易。

我想说,您可以同样轻松地从单个点赞 table 和单独点赞 table 中获取数据。例如,如果你想找到最喜欢的评论,使用简洁的 table 你会这样做:

select c.id
from comments c
inner join likes l on c.id = l.target_id and 'comment' = l.type
where l.added between x and y

如果 commentlikes 是分开的,你会写:

select c.id
from comments c
inner join commentlikes l on c.id = l.target_id

单独 table 允许您定义外键关系。外键允许引用完整性并有一些性能开销。您必须确定与参照完整性的妥协(或添加额外代码以补偿数据库中的 RI)相比,开销是否足够大。

如果 table 是分开的,您还可以以可读的方式更改评论、帖子等之间的点赞行为。例如,如果您希望对评论而不是对帖子的喜欢是不同类型的(例如心、祝贺、不喜欢等),单独的 table 可以提供这种灵活性。你也可以用一个 table 做同样的事情。如果 table 是分开的,它会更具可读性。

如果您在评论和帖子上获得大量点赞,点赞 table 会比点赞 table 分开时变大得更快。

您可以从一个简洁的 table 开始,然后在适当的时候拆分它,或者您可以从不同的 table 开始,然后再组合起来。