ビンゴマスタ側はまぁこうだろう。

# ビンゴマスタ
bingos
  title : varchar

# ビンゴマスタの各マスの中身
bingo_cells
  bingo_id
  position : int (1..25)
  label : varchar

で、ユーザが回答したものをどう書くか。

1. 1マス1レコード

bingo_results
  user_id
  bingo_id
  position : int (1..25)
  checked : boolean
  • 1-1: 必ず 9 or 25 レコード作る
    • 無駄レコードが多いのでなるべく避けたそう
  • 1-2: 達成したマスだけレコード作る
    • こっちなら checked カラムも要らないね。行がある=チェックされている

2. カラムで持つ

bingo_results
  user_id
  bingo_id
  checked_1 : boolean
  checked_2 : boolean
  ...
  checked_25 : boolean

25 カラム以上は増えないのでまぁ悪くはなさそう。集計も簡単そう。
この場合マスタ側も position をカラムで持たず、varchar で 25 カラム持ちそう。

3. 配列で持つ

bingo_results
  user_id
  bingo_id
  checks_json : jsonb ([true, true, false, ...])

アプリケーション側で扱いやすいなら非常に良さそう。

4. bitfield

bingo_results
  user_id
  bingo_id
  checks : bigint # 各 position をそれぞれ 1, 2, 4, 8, ..., 16,777,216

25 マスなら 32bit に収まるので bigint にする必要もなさそう。
ラインが揃っているかを mask で表現できるのは面白そう。
アプリケーションで扱うのは多少面倒なので、いい ORM があるかどうかに依存しそう。

ビンゴのユーザレコードの持ち方は?

複数選択期限なし
  • 1マス1レコード32%7票
  • カラムで持つ0%0票
  • 配列で持つ41%9票
  • bitfield23%5票
  • その他14%3票
投票者 22人 / 計 24票投票するにはログインしてください

通報する

通報の理由を選択してください

通報はパーク管理者・モデレーターに届きます。(はてなも随時確認いたします)

はてなに直接通報したい場合はお問い合わせからご連絡ください

コメント一覧

  • かなり悩む〜。自分なら配列を選びそう。

    1. 1解答1レコードである方が望ましそう
      • 要件が増えることが想像できるなら、各マスの情報を持てる構造を選ぶが
    2. カラムは多少扱いづらい
      • メタプロしていいなら扱いやすくできるのでデメリットも無いんじゃないか
    3. 本命。だけど SQL アンチパターン的にはジェイウォーク
    4. DB を直接眺めたときに jsonb より可読性に劣る
      • なんかテクニカルでカッコイイ気がするので選びたくなる気持ちがある
    投票:
    • 配列で持つ
    5

    登録・ログインをすると、スレッドに投票できます

    1

    通報する

    通報の理由を選択してください

    通報はパーク管理者・モデレーターに届きます。(はてなも随時確認いたします)

    はてなに直接通報したい場合はお問い合わせからご連絡ください

    • うっ「なんかテクニカルでカッコイイ気が」して4を選んでしまったw

      投票:
      • bitfield
      2

      登録・ログインをすると、スレッドに投票できます

      通報する

      通報の理由を選択してください

      通報はパーク管理者・モデレーターに届きます。(はてなも随時確認いたします)

      はてなに直接通報したい場合はお問い合わせからご連絡ください

  • bingo_cells にビンゴのマスのマスタデータ置いたんだから当然解答レコード側でも bingo_cell_id を使うべきだったね。(「その他」ってどんな構造が考えられるかなーって考えてて見落としていたことに気づいた)

    3x3、5x5 しか存在しないって要件に踊らされている。

    投票:
    • 配列で持つ
    1

    登録・ログインをすると、スレッドに投票できます

    通報する

    通報の理由を選択してください

    通報はパーク管理者・モデレーターに届きます。(はてなも随時確認いたします)

    はてなに直接通報したい場合はお問い合わせからご連絡ください

  • bitfieldか配列にして、面白い畳み方ができないかな〜と考えたりしました。素朴に実装すると左上から右上に、そして次の行へ・・・といった感じの畳み方になりそうだけれど、Z曲線とかヒルベルト曲線とか螺旋とか、平面を充填する方法はいろいろある。

    0

    登録・ログインをすると、スレッドに投票できます

    通報する

    通報の理由を選択してください

    通報はパーク管理者・モデレーターに届きます。(はてなも随時確認いたします)

    はてなに直接通報したい場合はお問い合わせからご連絡ください

  • そもそもビンゴカードのマスタと抽選された番号のレコードがあれば、どのマスが開いてるかなんていうのはJOINして持ってくるものであって、レコードなんて作るもんじゃない派
    とはいえビューを作るという手段はあるだろうし、そうなったら見た目的には1マス1レコードにはなるのでそっちにも一票

    投票:
    • 1マス1レコード
    • その他
    3

    登録・ログインをすると、スレッドに投票できます

    1

    通報する

    通報の理由を選択してください

    通報はパーク管理者・モデレーターに届きます。(はてなも随時確認いたします)

    はてなに直接通報したい場合はお問い合わせからご連絡ください

    • はてなパークスのスタンプみたいなビンゴ機能じゃなく正しくビンゴの設計だ!

      投票:
      • 配列で持つ
      1

      登録・ログインをすると、スレッドに投票できます

      通報する

      通報の理由を選択してください

      通報はパーク管理者・モデレーターに届きます。(はてなも随時確認いたします)

      はてなに直接通報したい場合はお問い合わせからご連絡ください

  • 横持ち派が誰も居なかったのちょっと意外だった。拡張性がないのを嫌うからかなー。

    投票:
    • 配列で持つ
    1

    登録・ログインをすると、スレッドに投票できます

    通報する

    通報の理由を選択してください

    通報はパーク管理者・モデレーターに届きます。(はてなも随時確認いたします)

    はてなに直接通報したい場合はお問い合わせからご連絡ください

  • ちょっと質問の趣旨から外れるかもしれませんが、結果を持つのではなく、配られたカード(数字のリストを1カラムで)呼ばれた数字のリスト(1行1つ)を永続化する、という手もあります(イベントソーシング的な)。って書いてたらすでに似たようなコメントありましたね。JOIN でもいいですが、アプリ側で毎回計算するでもいいかもしれないです(個人的にはこちらが好みです)。

    投票:
    • その他
    3

    登録・ログインをすると、スレッドに投票できます

    通報する

    通報の理由を選択してください

    通報はパーク管理者・モデレーターに届きます。(はてなも随時確認いたします)

    はてなに直接通報したい場合はお問い合わせからご連絡ください

コメントして​会話に参加しよう