用于存储彩票信息的数据库设计

时间:2013-05-20 03:37:47

标签: mysql sql ruby-on-rails database-design

我正在设计一个系统,我应该存储不同类型的彩票(结果+门票)。 目前专注于美国Mega Millions和新加坡Pool Toto。它们都有类似的格式。

Mega Millions:从1到56的五个不同的数字和从1到46的一个数字。 Toto:从1到45的6个数字

我需要提供一个优雅的数据库设计来存储用户票证和相应的结果。 我想到了两种方法。

  1. 只需在6列中存储6个六位数字。 OR
  2. 创建另一个表(多对多),其中包含ball-number和ticket_id
  3. 我也需要存储结果的球数。

    对于TOTO,如果您的号码与4个或更多中奖号码相匹配,则您赢得奖品。 对于数百万美元,也有类似的过程。

    我正在寻找利弊或可能更好的解决方案? 我做了大量的研究和论文工作,但我仍然感到困惑的是它采用哪种方式。

4 个答案:

答案 0 :(得分:2)

两张表

tickets
    ball_number
    ticket_id

player
    player_id
    ticket_id

// optional
results
    ball_number
    lottery_id

使用两个表格,您可以使用以下查询:

select ticket_id, count(ball_number) hits
from tickets 
where ball_number in (wn1, wn2, ...) // wn - winning number
group by ticket_id
having hits = x

当然,您可以从彩票结果表中获取中奖号码(或将它们存储在特殊票号下的balls_table中)。

同样准备统计数据会更容易。与

select count(ticket_id)
from tickets 
group by ball_number

您可以轻松查看哪些号码主要被选中。

您可能还会使用某些字段(如彩票号码)来缩小查询范围,因为大多数字段只涉及一次抽奖。

一个表

对每个数字使用一个包含列的表可能会使查询更加复杂。特别是,据我所知,这些数字是有序的,而且除了一个(或两个)数字外,还有奖品。您可能需要将1, 2, 3, ...2, 3, 4, ...进行比较,这不像上面的查询那么简单。

一栏

将一个字符串中的所有条目存储在一列中违反了所有规范化做法,强制您拆分大多数查询的列并取消数据库执行的所有优化。存储数字也需要比存储文本更少的磁盘空间。

答案 1 :(得分:0)

我只是使用约定将它们连接起来并将它们存储在一列中。

像'10〜20~30~40~50~!60'之类的东西 〜分开数字 !表示特殊号码(强力球等)

如果你真的需要将它放在列中,请使用sql table values函数拆分结果。

答案 2 :(得分:0)

由于这是一天一次的事情,我想我会以易于编辑,维护和可视化的方式存储数据。你的许多方法都可行。主要是,我希望找到选择特定ball_number的用户很容易。

users
  id
  name

drawings
  id
  type # Mega Millions or Singapore (maybe subclass Drawing) 
  drawing_on

wining_picks
  drawing_id
  ball_number

ticket
  drawing_id
  user_id
  correct_count

picks  
  id
  ticket_id
  ball_number

获取数字后,找到所有在图纸中选择特定数字的user_id

按日期获取图纸

drawing = Drawing.find_by_drawing_on(drawing_date)

通过ball_number和绘图获取用户。

picked_1 = User.picked(1,drawing)
picked_2 = User.picked(2,drawing)
picked_3 = User.picked(3,drawing)

这是用户

的范围
class User < ActiveRecord::Base

  def self.picked(ball_number, drawing)
    joins(:tickets => :picks).where(:picks => {:ball_number => ball_number}, :tickets => {:drawing_id => drawing.id})
  end

end

然后执行快速数组交叉以获得正确获得3,4,5,6个选择的user_ids。你会遍历中奖号码以获得排列。

例如,如果中奖号码是3,8,21,24,27,44

some_3_correct_winner_ids = picked_3 & picked_8 & picked_21  # Array intersection

对于每位获胜者 - 使用正确的计数更新门票。

我可能会单独存储获胜者,但是使用了correct_count的索引,而且票证中没有太多数据,这可能现在已经可以了。

答案 3 :(得分:0)

首先,我要说我是Oracle人员,而不是MySQL人员。

其次,我通常会说要进行标准化的设计,但我很想在这里想到一个非常规的替代方案,我会在这里发表评论。

你如何对所有数字选择使用一列进行非规范化处理?

ticket_id      integer
nums           bit(56)
special_number integer

这将是一个非常紧凑的表示,你可以使用逐位操作来找到获胜者或潜在的赢家。

不知道这是否可行......请注意。