为什么我应该使用一个表而不是两个?

3
我有两个表,分别叫做UpVote和DownVote。你可以进行点赞和踩操作,因此它不是一个带有bool值的表。有人建议我使用一个名为votes的表,并添加一个名为type的字段。
为什么要这样做呢?我认为写唯一的表名比写Vote再加上额外的where语句 (type & upOrDownTypeBit) <>0 更容易些。
注意:(Up|Down)Vote表是PK id, FK userId

我会这样做:PK ID,FK 用户,BIT 投票(其中 1 表示赞成,0 表示反对)。 - BrunoLM
@BrunoLM:你可以两者兼顾,这就是问题所在。 - user34537
在我看来,你不应该在两个表中这样做,因为这只是无用的,并且会在不同的地方积累相同类型的数据,我不认为它有任何用处。 - BrunoLM
我认为OP的意思是,你可以同时拥有赞和踩,但用户不能同时点赞和点踩。这是一个模棱两可的陈述,引起了很多混淆。 - Joe Phillips
实际上,您可以进行点赞和点踩(也许更清楚)。当然,我不能在同一命令中执行此操作,但用户可以说他喜欢和不喜欢某个评论。听起来很奇怪,逻辑上也是如此,但在网站上有意义,而且正是因为这个表格,我才遇到了这个问题。 - user34537
9个回答

5

在数据建模方面,了解事物的含义通常很重要。

一个人对同一件事情进行赞成和反对投票是否等同于该人对某件事情不投票?

无论如何,通过适当的索引以提高性能,将其放在单个表中以便管理是完全可行的。在基本表之上,您可以添加UpVote和DownVote视图。或者您也可以采用另一种方法,即使用两个基本表,并为方便起见使用单个Votes视图。

通常,现在有两个表意味着有两组引用完整性、必须维护的半相同表模式以及数据的不太统一的视图。这也意味着您可能需要两个存档和/或分区计划来处理历史记录等。

这并不意味着它是错误的,但如果实体非常相似,则将它们建模为单个表通常是有意义的。

有时实体可能看起来相似,但实际上它们确实不同,应该将它们建模为单独的表。报价、采购订单和发票就是这样的例子。许多人喜欢将其中两个或更多的内容塞入同一个表中,这真的是一个坏主意。


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)上的索引,但我不知道MySQL中的语法是什么。


3

将这些内容合并到单个表格中的一个有用之处是可以通过为表格中的上投票分配+1和为下投票分配-1来快速找到总体净投票。

然后您可以执行:

SELECT SUM(delta) FROM votes WHERE id = ?


3

一个人可以同时有点赞和踩吗?如果不行,那么两个表格就没有意义了。此外,你需要编写两个查询语句来删除投票;每个表格都需要一条。这样做还值得吗?


我不太明白为什么这个答案能被接受,因为楼主明确说一个人可以同时进行赞和踩,但我猜那就是生活啊。我同意这个答案说使用两张表是不太理想的,但我还是有些困惑。 - MJB
1
说实话,我不确定有人(包括我自己)完全理解了这个问题。它有点含糊不清。如果这些回答在某种程度上解答了操作员的问题,那么,我也不知道该说什么了。 - Joe Phillips
1
不是说我会怪你或者你在意,只是这事看起来有点奇怪。 - MJB
d03boyL 是这句话“此外,您必须编写两个查询来删除投票;每个表一个。这还值得吗?”让我明白了。我发现自己开始编写更复杂的查询,并意识到这正是你所警告的。我立即将其改为一个表。 - user34537

3

DRY。拥有两个表的缺点是任何处理投票的代码可能都需要重复。这可能包括在数据库中复制任何约束和其他逻辑。有一个关系型数据库设计原则,它断言您应该避免在多个表中重复相同的数据:正交设计原则


0
如果性能是一个问题,那么从单个表中列出会比在两个表上进行连接或联合更快。
也许我误解了你的意思,但是你是否有关于被投票对象的其他外键?还是用户正在被投票?
无论哪种方式,都可以更轻松、更高效地在单个表上进行聚合,例如如果您想要对赞成票或反对票进行求和(Sum())。您应该在投票字段中执行1和-1。

0

当读取数据时,您的方法将提供一定的易用性。单个表在写入数据时提供易用性。使用两个表时,您必须在决定要写入哪个表之前检查值。对于单个表,您甚至不知道或关心变量的内容就可以写入表中。我认为这是一种更正常的做事方式,尤其是当超出此单个示例时。

为了允许上下投票,您可以为每个选项添加一个布尔列。


0

在应用上下文中做出最有意义的事情。记住哪些系统将使用数据,并确保您实现的内容对这些系统是有意义的。还要考虑更改表格的成本,如果有一天您发现需要更改,这种成本往往会增加(如果有多个应用程序使用该数据,则会更高)。

但归根结底,这是您的数据,请以最简单的方式表示。


0
其实,这取决于您的数据量以及您要对数据进行什么操作。如果您没有特殊原因使用两个表,请使用一个表。因为一个表可以提供您在两个表中拥有的所有功能,并且在某些情况下更简单、更容易:将赞成变为反对;求和所有投票等。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接