这是我目前为数据库设计的简化版本,用于“Stack Overflow”式投票系统。
问题是:如果用户得到了他们为回复得到的总票数得分,那么这个得分应该是“即时”得出的,还是应该在用户表中有一个字段来指代他们的得分。如果案件是后者,推荐的方法是什么让它保持最新?
Users Table
-id
-name
-email
Question Table
-id
-text
-poster (user id)
Responses Table
-id
-text
-question (question id)
-poster (user id)
Votes Table
-id
-response (response id)
-voter (user id)
答案 0 :(得分:2)
我建议至少在开始时根据需要计算投票总数。在开始使用时,需求可能会很低,并且可以在以后更改为在Responses表中存储为字段。当/如果发生这种情况,请使用触发器更新它。此外,设置一个视图来报告响应和总计,所以当/如果进行了更改,您有一个中心位置来进行界面更新,而不是在代码中搜索查询。
如果需求在开发期间或初始发布后发生变化,则具有更灵活的附加好处。注意功能蠕变。
您还可以删除Votes表中的id字段。如果每个投票对于回复和选民都是唯一的,那么将这些字段键设置到表格就足够了。
答案 1 :(得分:2)
您可能希望让架构允许对问题进行投票(这意味着需要另一个投票表)。我认为在Users
表中使用投票金额(信誉)是个好主意,因为查询表中的单行比在每次查询两个表的总和更有效想要显示用户的声誉。您可以从触发器或业务逻辑更新此更新。您还需要考虑如何表示上/下投票。您可以使用两个投票表中的位值(表示向上或向下)或绝对数字(1 / -1)来执行此操作。每次在两个投票表中插入,删除或更新条目时,您都必须调整Users
表中的总数。通过触发器更新总数可能会更加“万无一失”,但您也可以认为它应该存在于您的业务逻辑层中,并且人们不应该直接在表中玩游戏。但只要你做出明智的决定,我个人认为这不重要。
答案 2 :(得分:2)
对数据库模型进行去规范化,这样一些关键场景可以获得更好的性能是合理的,只要您以谨慎和慎重的方式进行。
之后你已经对实际的数据量进行了基准测试,并确定即时计票会导致性能问题,请立即进行并缓存投票次数。
保持缓存值最新的最强大的方法可能是实现一个数据库触发器,每当一行插入Votes
时递增缓存值,并在删除行时递减。 / p>
(注意:拥有SELECT COUNT(*)...
触发器可能会引入细微的并发问题。)