Upgrade to Pro — share decks privately, control downloads, hide ads and more …

プロ野球をデータモデリングしてみたら沼だった件 / Baseball ERD Modeling to be obsessed

プロ野球をデータモデリングしてみたら沼だった件 / Baseball ERD Modeling to be obsessed

Baseball Play Study mini〜野球でデータモデリング(BPStudy#187)
https://bpstudy.connpass.com/event/277381/

YUMOTO Michitaka

March 29, 2023
Tweet

More Decks by YUMOTO Michitaka

Other Decks in Technology

Transcript

  1. プロ野球を”データモデリング”したら沼に
    ハマってしまった件
    gothedistance a.k.a ござパイセン
    https://twitter.com/gothedistance
    BPStudy#187 at 2023.03.29

    View Slide

  2. YUMOTO Michitaka
    Hello!
    2
    ● ゆもと みちたか(ござパイセンというHNで生きてます)
    ● 1979年生まれです。松坂世代。
    ● GoTheDistanceというブログを書いてます。たまに。
    ● 新卒SIer→雑貨製造業で内製→独立してもうすぐ7年。
    ● Flutter/React/T3 Stack等のフロントエンド好き
    ● やきうを愛する東京ヤクルトスワローズのファン!

    View Slide

  3. BPStudy History
    ● BPStudy#79(野球)
    ● BPStudy#91(野球)
    ● BPStudy#92
    ● BPStudy#100(野球)
    ● BPStudy#103(野球)
    ● BPStudy#108
    ● BPStudy#112(野球)
    3
    ● BPStudy#115(野球)
    ● BPStudy#122
    ● BPStudy#124(野球)
    ● BPStudy#127(野球)
    ● BPStudy#140(登板回避)
    ● BPStudy#142
    ● BPStudy#185(Flutter)
    ● BPStudy#187(NEW)

    View Slide

  4. お話させて頂くこと
    4
    ➔ プロ野球をデータモデリングしたら沼だった
    ➔ 2023年シーズンの抱負
    ➔ 謝辞

    View Slide

  5. RDBデータモデリング
    現実をデータベースの世界に落とし込め
    1
    5

    View Slide

  6. データモデリングはエンティティの抽出が9割
    6
    目に見えないソフトウエアは概念を明文化して共有するのだ
    ➔ データモデリングのコアは「エンティティ」の抽出。
    ➔ 自分たちが作ろうとしているソフトウエアで取り扱うデータに名前をつけ、実態として認識
    できるように命名付けた概念=エンティティ。
    名称 内容 例(ホテルの予約システム )
    ヒト そのシステムを利用する人達
    社員(役職・部門等)、取引先、得意先、ア
    ルバイト。
    モノ システムで取り扱う資産・サービス プラン・予約・お部屋・設備・カレンダー
    コト システムを通じて行われる行動・イベント
    予約受付・問い合わせ・オンライン決済・
    キャンセル・空き状況を確認する

    View Slide

  7. 正規化 is 何
    7
    ライフサイクルが違うものは別のテーブルに切り出せ
    ➔ 一番良くわからなかった概念が、正規化だった。今でもちょっとあやしい。
    ➔ 正規化における「重複を排除せよ」は
    「ライフサイクル」の違うエンティティは必ず分離しろ
    でよくない?よくなく なくなく なくなく ない?
    ➔ それを進めていけば、イミュータブル・データモデリングへと繋がるのでは?
    ➔ 予約のデータを作るのにプランが予約の中に入ってし
    まったら、新しい予約を作る時に必ず新しいプランが作ら
    れてしまう。
    ➔ 予約とプランは別々のライフサイクルを持っているので、
    エンティティ分けよう。
    ➔ こう考えれば勝手に第3正規形までいくだろ多分

    View Slide

  8. ペナントレースで必要な
    エンティティを出そう
    2
    8

    View Slide

  9. 9
    この1枚からすべてが始まる。さぁモデリングをしようじゃないか!

    View Slide

  10. ざっとこんだけのエンティティが必要だな
    10
    試合 開催日時、場所、経過時間、予告先発、勝利投手、敗戦投手、セーブ等
    チームと選手 チーム変わったりするよね。うん。それと選手は全員要るよね
    打順 ラインアップですね。選手は当然交代するので。
    ポジション 1〜9、及びDH。Enumでアプリ側で持っても良さげ。増減がないので。
    スコアボード イニング毎の得点、ヒット数等を掲載する必要がある。
    1球速報 1球ごとにカウント変わり得るので。球数も出す必要がある。
    交代履歴 投手及び野手の交代の履歴。
    試合毎の成績 打者成績(打率とHRはマスト)と投手成績
    開催日程 ペナントレースの開催日程に応じて成績表を出す必要があるため。

    View Slide

  11. 試合エンティティを考える
    11
    -
    - 開催日時
    - 開催球場
    - ホームチームID
    - ビジターチームID
    - ホーム予告先発
    - ビジター予告先発
    - ホーム得点数
    - ビジター得点数
    - 勝利投手
    - 敗戦投手
    - セーブ
    - 観客数
    - 試合時間
    試合エンティティ
    - ID
    - 名称
    球場
    - ID
    - チーム名
    - 所属リーグ
    チーム
    - ID
    - 登録名
    - ポジション
    - 背番号
    プレイヤー
    ➔ 正規化を崩すべきか悩む所
    ◆ 球場名はネーミングライツで同じ場所でも呼
    称が変わる為。チーム名も同様。
    ◆ シーズン年度と名称だけを持つエンティティ
    作って、シーズン年度でWHERE?
    ➔ チーム・プレイヤー・球場はマスタから参照すべき
    だ。固定値を埋めることは考えにくい。
    ➔ セーブは NULL許容カラムしかない?
    ➔ 審判も球審・塁審 x 3 が必要だ。1 : 1 の別エンティ
    ティ? カラム追加?
    ➔ リクエストの残り回数も管理が必要だとすると、どこ
    に保管すべきデータ?

    View Slide

  12. スコアボードエンティティを考える
    12
    - 試合ID
    - イニング数
    - チームID
    - 得点
    - 四球
    - 安打数
    - エラー
    イニング
    ➔ スコアボードはテーブルで表現できない気がしている。イニングの集合体がスコアボードな
    ので、SQLでデータ取得→アプリ側でスコアボードのUIに沿ったデータを作るしかないので
    は?
    ➔ 仮にスコアボードテーブルを作る場合、どういう設計にしていくのか???
    ➔ イニング毎に記録する数字が多いので、縦に持つしかない。
    ➔ ノーゲーム・雨天コールド・延長戦等、消化するイニング数が試合によって異
    なる。その点を踏まえても、イニングを積むしかなさそう。
    ➔ 裏の攻撃がなく試合が終わることが結構ある。
    9回表で試合終了する
    ケースには「X」がスコアボードにつくけど、まさか
    DB側にXを保存するわ
    けにもいかんだろ・・・

    View Slide

  13. カウントとランナー表示を考える
    13
    ➔ カウントは1球毎に異なる場合もあれば、4球投げても同じこともある。
    ➔ ストライクとボールカウントは0になり、アウトカウントも3つ目で0になる。
    ➔ 最大要素数が決まっているので単純に配列で持てば良さそう。
    ➔ 状況によってリセットされる性質があるので、
    SQLでカウント表示を表現するのは出来ない
    ように思うけど、まさか方法があるんだろうか・・・?
    ➔ ランナーもリセットされる。塁とランナー存在フラグを持つオブジェクトを作り、
    1塁2塁3塁の
    3つのフィールドを持たせるだけで良さそうだが、改良の余地はあるか???

    View Slide

  14. 成績表示を考える
    14
    ➔ 横持ちが簡単そうでいいけど、UPDATEの嵐になるデータ操作は正しいのか?
    - 試合ID
    - プレイヤーID
    - 球数
    - 奪三振
    - 与四球
    - 与死球
    - 失点
    - 自責点
    - アウトカウント
    投球履歴
    ➔ 横に持った場合、1球投げる毎に投球数や被安打を更新することにな
    る。すげーミュータブルなデータになってしまう。
    ➔ 1球投げる毎にレコードを追加して縦に持った場合、歯抜けなデータの
    持ち方になるけど、GroupByで頑張ればできそう。
    ➔ 横持ちした場合、被安打や打者等はただインクリメントするだけだけど、
    縦持ちした場合、三振とかヒットのような結果はどこで保存すべきなんだ
    ・・・?!

    View Slide

  15. 野手成績表示を考える
    15
    ➔ このUI作るの大変じゃないか・・・?
    ➔ 打数と打席数が一致しない。四死球は打数にカウントされない。
    ◆ 第1打席は三振、第2打席は四球等の履歴は、別テーブルで保持する必要があります。
    ➔ 代走・守備固めでの出場があるので、代走の場合は盗塁だけ、守備固めの場合は失策のみが計
    上されるケースがありえます。打席が与えられないケースもあるので、打席の履歴は別。
    ➔ 選手が起用される毎に 1レコード増やし、初期値は打率以外は全部 0。打率はこのテーブルの最後
    の1件を取り、プレイが完結したら UPDATEしていく以外、ちょっと思いつかなかった。

    View Slide

  16. 野球データモデリングは沼
    100テーブル前後の業務システムよりも設計が難しい(当社比)
    ペナントレースを表現できるER図とSQL書ければ上級者だろ・・・
    スポナビの野球担当エンジニアの方、3時間34分この話をしませんか・・?!
    16

    View Slide

  17. The die is cast.
    Let’s go for October!
    Thanks!
    17
    あかん、優勝してしまう
    ◉ @gothedistance
    [email protected]

    View Slide