【问题标题】:Most efficient database design for this data此数据最有效的数据库设计
【发布时间】:2012-09-17 13:33:39
【问题描述】:

我会说我的数据库知识是合理的,我为此使用 MySQL (InnoDb),并且也完成了一些 Postgres 工作。总之……

  • 我有大量“是”或“否”问题。
  • 很多人都可以参与同一个投票。
  • 用户可以选择任一选项,这将记录在数据库中。
  • 用户可以稍后改变主意并交换需要更新存储数据的选择。

我目前存储这些数据的计划:

  • 轮询、用户 ID、决策、时间戳

显然用户数据在另一个表中。

要添加他们的选择,我必须查询他们之前是否投票并插入,否则,更新。 如果我想查看投票结果,每次有人想查看投票时,我都需要遍历所有决策(尽管是索引部分)。

我的问题是

  1. 有没有更有效的方法来存储/查询这个?
  2. 我是否有关于 POLLID 或 POLLID 和 USERID 的索引(可能只是一个唯一约束)?还是其他?
  3. 附加问题:为什么我不能像在 Postgres 中那样在我的表上选择 HASH 和 BTREE 索引?

【问题讨论】:

  • 为什么要遍历所有决策才能看到投票结果?是什么阻止了您在每次投票时使用更新民意调查信息的表格?它节省了遍历所有内容以获取数据所需的资源。
  • 请注意 N.B. 的建议,虽然它可以工作 - 它可能导致非正常化,因为您的投票可能无法反映民意调查信息。最好用 SQL 来计算这些信息,它已经足够强大了。
  • 其实这样做并不是最好的。投射/更新投票 - 存储在其他地方的递增/递减计数器。每次有人连接时都可以节省您的迭代和求和。如果实施得当(而且我真的看不出它是如何被糟糕地实施的,因为它是微不足道的),它会按预期工作。
  • 我想到了这个,但是因为Zeritor给出的原因而忽略了它。另外,除非你有我的设计和一个柜台,否则你将如何跟踪谁投票给了什么?这意味着 id 有冗余数据(不会是正常形式)加上我无法获得投票日期......对吗?
  • 所以问题是关于性能,但物化视图却不受欢迎?一旦用户投票或更改投票,谁说您不能更新保存按用户排序的投票的表,然后更新保存投票统计信息的表?这是您想要性能时使用的标准做法。但如果你是 SQL 传道者,那为什么还要追求性能呢?

标签: mysql sql database voting


【解决方案1】:

这个设计听起来不错,有几个想法:

民意调查表:民意调查 ID、问题。

选项表:选项 id、文本。

将投票链接到选项的表格:poll id->choice ids。

用户表:用户详细信息、用户 ID。

投票表:(用户 ID、投票 ID)、选项 ID、时间戳。 (括号是唯一的一对)

为单个用户插入/更新可以正常工作,因为您只需检查用户 ID 和投票 ID 是否存在条目。

与使用 COUNT 进行迭代相比,您可以更轻松地查看结果。

e.g.: SELECT COUNT(*) FROM votes WHERE pollid = id AND decision = choiceid

这将告诉您有多少人在“pollid”民意调查中为“choiceid”投票。

后期编辑:

这是一种在不存在时插入并在存在时更新的方式:

IF EXISTS (SELECT * FROM TableName WHERE UserId='Uid' AND PollId = 'pollid')
    UPDATE TableName SET (set values here) WHERE UserId='Uid' AND PollId = 'pollid'
ELSE   
    INSERT INTO TableName VALUES (insert values here)

【讨论】:

  • 谢谢,看起来是个不错的答案。我说迭代是因为我不知道计数函数的内部工作原理。最后一个q有灯吗?
  • 对不起,我对索引不太了解,也从未使用过 postgres。
  • 可以编写INSERT/UPDATE 语句,使它们在不可能的情况下不更新任何行,但它们不会失败。因此,可以根据它们是否在INSERT 上成功进行检查,但语句的“更新行数”为 0...如果仅使用选择,则不需要轮询/选择交叉引用表一项民意调查(不确定是否相关)。而且技术上在投票表中同时存储choice_idpoll_id 是非规范化的,但正确规范化它会使查询变得有些复杂。
  • @X-Zero,真的是非规范化吗?这对我来说似乎没问题,但我可能是错的。你能否进一步解释一下,我很想知道。我看不到任何其他存储所有选票的方式。
  • 这是因为民意调查和选择之间的关系已经存储在其他地方,所以它是不必要的/可能损坏的信息(民意调查的错误选择)。正确的做法是存储(user_idchoice_id),然后浏览关系以检查用户是否没有投票支持特定的民意调查。但是,以这种方式选择性地反规范化可能没问题,特别是如果仅将选项作为主变量提供,并且从关系表中解析轮询(意味着UPDATEs 需要更多时间,但查询更容易)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-30
  • 1970-01-01
  • 1970-01-01
  • 2016-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多