2

さまざまな種類の宝くじ (結果 + チケット) を保存するシステムを設計しています。現在、米国の Mega Millions とシンガポールの Pool Toto に焦点を当てています。どちらも似たような形式です。

Mega Millions: 1 から 56 までの 5 つの異なる数字と 1 から 46 までの 1 つの数字 Toto: 1 から 45 までの 6 つの数字

ユーザー チケットと対応する結果を格納するための洗練されたデータベース設計を考え出す必要があります。私はそれについて2つの方法を考えました。

  1. 6 つの数字を 6 つの列に格納するだけです。また
  2. ball-number と ticket_id を持つ別のテーブル (多対多) を作成します。

結果のボール番号も保存する必要があります。

TOTOの場合、当選番号が4つ以上一致すると当選となります。メガ ミリオンズについても同様のプロセスがあります。

長所と短所、またはより良い解決策を探していますか? 私は多くの調査と書類作成を行いましたが、どの方法でそれを行うべきかまだ混乱しています.

4

4 に答える 4

2

2 つのテーブル

tickets
    ball_number
    ticket_id

player
    player_id
    ticket_id

// optional
results
    ball_number
    lottery_id

2 つのテーブルでは、次のようなクエリを使用できます。

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 つの宝くじだけに関係するためです。

1 つのテーブル

各数値の列を含む 1 つのテーブルを使用すると、クエリがさらに複雑になる場合があります。特に、私が信じているように、数字はソートされており、1 つ (または 2 つ) の数字を除くすべての数字を当てると賞品があります。上記のクエリほど簡単ではないものと比較1, 2, 3, ...する必要があるかもしれません。2, 3, 4, ...

1列

文字列内のすべてのエントリを 1 つの列に格納することは、すべての正規化の慣行に違反し、ほとんどのクエリで列を分割する必要があり、データベースによって実行されるすべての最適化が取り除かれます。また、数値を保存すると、テキストを保存するよりも必要なディスク容量が少なくて済みます。

于 2013-05-20T08:57:33.643 に答える
1

これは 1 日 1 回の作業なので、編集、保守、視覚化が容易な方法でデータを保存すると思います。あなたの多対多のアプローチはうまくいくでしょう。主に、特定の 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 にインデックスがあり、チケットのデータが多すぎないため、現時点ではおそらく問題ありません。

于 2013-05-20T17:13:14.840 に答える