建模Upvotes / Likes - 每种类型一张桌子,还是一张大桌子?

时间:2013-12-08 15:56:55

标签: database-design schema normalization

我正在建立一个具有" upvotes"跨越各种实体类型 - ReportsReviewsCollections

这些是唯一可以被投票的三个实体,尽管未来可能会有更多。

目前,数据库架构有ReportUpvotesReviewUpvotesCollectionUpvotes

我想知道将所有这些表合并到一个Upvotes表中是否更好,其中包含Type的枚举。

在评估此类决定时,我应该考虑什么?

2 个答案:

答案 0 :(得分:7)

在一个表中存储相同类型的实体(Upvotes)的想法对我来说非常有意义。但是,它可以以不同的方式实现。蝙蝠的权利我可以讲三种方式。

问题中提出的第一个(除非我误解了它)导致多态关联,这种做法通常被认为是坏的。如果我错了,请纠正我,但似乎你想要CREATE TABLE Upvotes (..., type enum ('Report','Review',...), entity_id int)之类的内容,其中entity_id指的是基于ReportReview等表格之一type列的值。没有触发器,你无法强制实施这种约束。

其次是专属弧。更好的方法(可以强制执行参照完整性),但仍然非常难看。如果你这样做,你会有类似

的东西
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等)不为null。其次,添加可以上调的新实体类型意味着向Upvotes添加新列。

第三种方式是“共同父母”方法。您正在创建一个新表,例如UpvotableEntity(错误的名称,仅用于说明)。然后将其作为现有ReportUpvotes,ReviewUpvotes和CollectionUpvotes的父表。最后,Upvotes表存储upvotable_entity_id

答案 1 :(得分:3)

就像在软件开发中一样,要求应该强烈影响你应该做的事情。

您是否需要能够一起或在一个地方显示所有赞成/喜欢?

您是否设想添加更多类型的投票?

对这两个中的任何一个回答“是”都会让我倾向于一张桌子。

除此之外,就像在软件开发中一样,如果表在结构和目的上非常相似,它们可以“重构”到单个表中。也是出于这个原因,我倾向于拥有一张桌子。