我有两个名为(向上|向下)投票的表,你可以同时进行upvote和downvote,因此它不是一个有bool的表。人们建议我应该使用一个名为votes的表,并有一个名为type的字段。
我为什么要这样做?我认为编写唯一的表名更容易然后编写Vote然后使用额外的where语句(type & upOrDownTypeBit) <>0
。
注意:(向上|向下)投票表为PK id, FK userId
答案 0 :(得分:5)
对于数据建模,了解事物的含义通常很重要。
同一个人对同一件事的投票和投票是否与一个人对某事物的投票完全相同?
在任何情况下,为了便于管理,将其置于单个表中当然是可能的(通过适当的性能索引)。在该基表的顶部,您可以添加UpVote和DownVote视图。或者你可以采用另一种方式,为方便起见,有两个带有单个投票视图的基表。
通常,拥有两个表现在意味着两组参照完整性,两个要维护的半完全相同的表模式,以及一个不太统一的数据视图。这也意味着您可能需要有两个存档和/或分区计划来处理历史记录等。
这并不意味着它是错误的,但如果实体非常相似,那么在单个表中对它们进行建模通常很有意义。
有时实体可能看起来很相似,但实际上它们确实不是,它们应该在单独的表中建模。这里会想到报价,采购订单和发票。很多人喜欢把两件或两件以上的东西塞进同一张桌子里,这真是一个坏主意。
答案 1 :(得分:4)
为什么不把它变成INT呢?我非常怀疑由于填充等原因,BIT数据占用的空间与INT一样多。使用INT,您可以:
-1: downvote
0: neutral vote (might not be used)
1: upvote
NULL: no vote
你的投票表可能是:
create table votes (
post INT,
user INT,
vote INT
);
投票表应该有post和user的外键约束以及(post,user)的索引,但我不知道MySQL中的语法。
答案 2 :(得分:3)
通过将其合并到单个表中,您可以做的一件有用的事情是通过在表格中为upvote指定+1并在delta列中为downvote指定-1来快速找到整体净投票。
然后你可以去
SELECT SUM(delta) FROM votes WHERE id = ?
答案 3 :(得分:3)
DRY。拥有两个表的缺点是任何处理投票的代码都可能需要重复。这可能包括复制数据库中的任何约束和其他逻辑。有一个关系数据库设计原则断言你应该避免在多个表中重复相同的数据:The Principle of Orthogonal Design。
答案 4 :(得分:2)
一个人可以同时拥有UPvote和DOWNvote吗?如果没有,那么两个表没有意义。此外,您必须编写两个查询来删除投票;每张桌子一个。还值得吗?
答案 5 :(得分:0)
如果性能完全是一个问题,那么从单个表中列出而不是两个表上的连接或联合会更快。
也许我误解了你在做什么,但是你有关于被投票对象的其他外键吗?或者是用户被投票。
无论哪种方式,对单个表上的聚合会更容易和更高效,例如,如果您想要Sum()upvotes或downvotes。你应该在投票领域做1和-1。
答案 6 :(得分:0)
在阅读数据时,您的方法将提供一些易用性。在写入数据时,单个表将提供易用性。使用两个表,您必须在决定要写入哪个表之前检查该值。使用单个表,您可以在不知道或不关心变量内容的情况下写入表。我认为这是一种更为正常的做事方式,特别是当扩展到这个单一的例子之后。
为了允许向上和向下投票,你可以为每个投票设置一个布尔列。
答案 7 :(得分:0)
在您的应用程序环境中做任何最有意义的事情。请记住哪些系统会消耗数据,并确保您实施的内容对这些系统有意义。如果有一天你发现需要,还要考虑更改表的成本(如果有多个应用程序使用数据,这将会增加)。
但最重要的是,这是你的数据,代表它使你的事情变得最简单。
答案 8 :(得分:0)
实际上,这取决于您的数据量以及您对数据的处理方式。如果您没有特殊原因要使用两个表,请使用一个表。由于一个表可以提供具有两个表的所有功能,并且在某些情况下更简单,更容易:将向上投票改为向下投票;总结所有选票等。