为点赞/点赞建模——每种类型一张桌子,还是一张大桌子?
Posted
技术标签:
【中文标题】为点赞/点赞建模——每种类型一张桌子,还是一张大桌子?【英文标题】:Modeling Upvotes / Likes - one table per type, or one big table? 【发布时间】:2013-12-30 02:28:59 【问题描述】:我正在建模一个系统,该系统将在各种实体类型(Reports
、Reviews
和 Collections
)中获得“赞成票”。
这是仅有的三个可以投票的实体,但未来可能还会有更多。
目前,db 架构有ReportUpvotes
、ReviewUpvotes
和CollectionUpvotes
。
我想知道将所有这些表放在一个 Upvotes
表中是否会更好,并带有 Type
的枚举。
在评估此类决定时我应该考虑什么?
【问题讨论】:
您可能还感兴趣:Implementing comments and Likes in database. Data Model of SO 可能是您问题的一个很好的参考。 【参考方案1】:在一张表中存储相同类型的实体(Upvotes)的想法对我来说非常有意义。然而,它可以以不同的方式实现。蝙蝠的权利我可以告诉3种方式。
问题中提出的第一个(除非我误解了)会导致多态关联,这种做法通常被认为是不好的。如果我错了,请纠正我,但您似乎想要CREATE TABLE Upvotes (..., type enum ('Report','Review',...), entity_id int)
之类的东西,其中entity_id
是指基于type
列的值的Report
、Review
等表之一。如果没有触发器,您将无法强制执行此类约束。
其次是专属弧线。更好的方法(可以强制执行参照完整性),但仍然很丑陋。如果你这样走,你会有类似的东西
CREATE TABLE Upvotes(..., report_id INT , review_id INT, ....,
CONSTRAINT FK_REPORT FOREIGN KEY (report_id) REFERENCES Report(report_id),
CONSTRAINT FK_REPORT FOREIGN KEY (review_id) REFERENCES Review(review_id)
);
首先,您需要确保(report_id、review_id 等)中只有一个对于任何行都不为空。其次,添加可以投票的新实体类型意味着将新列添加到Upvotes
。
第三种方式是“共同父母”方式。您正在创建一个新表,例如 UpvotableEntity
(坏名,仅用于说明)。然后使其成为现有 ReportUpvotes、ReviewUpvotes 和 CollectionUpvotes 的父表。最后,Upvotes
表存储upvotable_entity_id
。
【讨论】:
是的,第一种方法是我正在考虑的 - 用于查询与 ENUM 对应的任何表的单个“EntityId”字段。共同的父方法 - 您是否介意进一步解释这一点,或者甚至是演示该概念的链接都会有所帮助。 另外,我想补充一点,从实用性的角度来看,让一切标准化和强制执行本身不应该是目标;考虑每个解决方案的时间和复杂性。 太棒了,我刚订购了那本书。感谢您的帮助。 通用父方法 (child.Parentid) 会不会将子与父之间的关系限制为一对一而不是一对多?还是我误会了?【参考方案2】:就像在软件开发中一样,需求应该强烈地影响你应该做什么。
您是否需要能够将所有点赞/赞一起显示或显示在一个地方?
您是否设想添加更多类型的点赞?
对这两个回答“是”会让我倾向于一张桌子。
除此之外,就像在软件开发中一样,如果表在结构和用途上非常相似,则可以将它们“重构”为单个表。出于这个原因,我倾向于使用一张桌子。
【讨论】:
以上是关于为点赞/点赞建模——每种类型一张桌子,还是一张大桌子?的主要内容,如果未能解决你的问题,请参考以下文章