# 8/11(水) メンターさんペアプロ メモ [toc] ## 生データを保存する理由 - 古いデータをとってこないので大変→アプリで使わないなら不要かも - 正規化できないデータ - 時期などは関係なしに、後で欲しいとおもったデータのスキーマを変えた時(どういうテーブルにどういうデータ型のカラムを作るか)に、 - 一発で綺麗に出せない? - - 一回とっておきたい - 生データ関係なく問題があるポイントがある - サインアップしてないユーザーに、issueがアサインされている - assigned_issueとPRにでーたがふえていって、userはない問題 - assigneeは指定できるけど、reviwerは指定してリクエストで取れない問題 - issueとPRのでーたをためていって、userがサインアップ - userのサインアップを起点にリクエストを飛ばしたくない - userのサインアップユーザーのサインアップした時にissueやPRを撮りにapiにリクエストしたくない。リクエストをこちらで制御できないのが嫌。 umemotosan - 問題2:PRはreviewer指定して取りに行けない - 1. サインアップした段階でuserが - PR何件取りに行く? - PRがcloseされたら、or レビュワーでなくなたtらアプリ上は消える - PRのレコードを削除するタイミング - ポーリング:APIに逐一状態を聴きに行かないと最新の状態が分からない - とってきたものが更新されてるか見に行かないといけない(ポーリングしないといけない) - サインアップしたら取りに行く方法 - 1回目のレコード作成のタイミングはユーザーサインアップした時 - 結局2回目以降はポーリング(バッチ処理)がやることになる - 結局定期的にみに行かないといけない - メンターさんの手法 - APIから取ってきたものをissueとPRテーブルに保存しておく - userサインアップした時だと余計なリクエストがとぶ - createした時とuddateした時でわかれてしまうと考えることが増える - 生データの話にもどる - どっちの作戦でもデータを地区地位とりにいかないといけない - https://user-images.githubusercontent.com/58052292/183830551-a471ed40-4648-490d-94d4-cc1d1d935563.png - このテーブルで足りないカラム - 私の方法を実現するのはとても複雑。むずかしい ## メンターさんの手法イメージ https://discord.com/channels/715806612824260640/888287515994386462/1006907408502759515 ### メンターさんメモ 梅コース: まじめにやらない。1回で取れる最大を取ってくる。リリース以降に取ってこられるものだけに限定する。 竹コース: 1000 件手動で取ってきて、スクリプトで API を叩いて 1000 件ぐらい詰めるコードを書く (初回のデータ投入とかシードみたいな感じ) 松コース: 最初の 1 件目から全件取得する ```ruby 10.times do |n| get_issues(offset: 100 * n) get_pull_requests(offset: 100 * n) # persist issues # persist pull requests end api_issues = GitHubApiClient.get_issues # JSON api_issues.each do |api_issue| raw_issue = RawIssue.create!(json: api_issue) issue = Issue.create!( number: 1234, raw_issue:, point: raw_issue['labels'][0].name, users: raw_issue['assignees'].map { |user| user['login_name']] } ) end api_pull_requests = GitHubApiClient.get_pull_requests # JSON api_pull_requests.each do |api_pull_request| raw_pull_request = Rawpull_request.create!(json: api_pull_request) pull_request = pull_request.create!( number: 1234, raw_pull_request:, point: raw_pull_request['labels'][0].name, users: raw_pull_request['assignees'].map { |user| user['login_name']] } ) end ``` ``` # スケジューラー管理のテーブル軍 - issues <- scheduler -> API - 1 (update), users: [hoge, fuga, piyo], point - 2 (update), users: [], point - 3 (create), users: [], point - pull requests <- scheduler -> API - 1 (update), users: [hoge, fuga, piyo], title, number - 2 (update), users: [], title, number - 3 (create), users: [], title, number # ユーザー起点?のなにか - users - 1 - 2 - 3 - users <-> issues - 1 - 2 - 3 - users <-> pull requests - 1 - 2 - 3 # 真面目にやりすぎな例 - api issues - api users - api issues <-> api users ``` ### 自分のメモ - スケジューラが管理するテーブル - issuesとPRテーブルへのデータ作成や更新は常にherokuスケジューラが行う - データをいじるのは常にスケジューラだけ - この人がアサインされてますというデータを持っていないといけない。そうしないとusersテーブルと紐つけられない - JSONデータは複数人配列で入ってる - が、DBでは配列をデータとして入れることができない - しかしこの配列の部分を正規化すると.... - user起点 - users - 中間テーブル -------- - しかしこの配列の部分を正規化やりすぎると... ![](https://i.imgur.com/Pq98rwh.png) ----- ![](https://i.imgur.com/92JqzuE.png) - なので配列でレコードを入れておく - 生データが必要な理由:あくまで保険 - なにかあった時のために撮りやすくする保険 - あってもなくてもいいとおもう - でも用意するコストはそんなに変わらない - データ量の懸念(多い) / このJSONをいつ消すか? を考えないといけない ## データ保存の流れ api→Rawissue→AssignedIssue ## 関連付けは必要か? - RawIssueからAssignedIssue - つける理由 - どのjsonから作成しているか明示するため - お互い絶対1個ずつしか存在しないはずなので、関係ないデータがまぎれこまないため - ユニーク制約をつければ1:1の保証ができる ## issueのAPIリクエストを、レビューリクエストされたPRを取得するためのAPIリクエストと揃えた方が良い理由 - cafedomancerさんの手法だとこんな感じのコードでDB保存することになる ![](https://i.imgur.com/5L0LEeq.png) - PRも↑のコードを使う。同じ方が見通しが立ちやすい。 - サインアップした時にuserを指定してとってくることがない。 ## リクエストの件数は何件が妥当か - issueとPRでリクエストのクエリは変わらない - ❌PRはopenなものだけ取りに行く→2回目以降の更新のタイミングがあるのでopenステ=タスは意味をなさなくなる - 何件が妥当か - 松竹梅3つの道 - 梅:リリースの直後に100 - 竹:リリース直後に一回だけ1000件撮りに行ってDB保存して取っておく - 松竹梅コース - issuesエンドポイントにPRが混ざってる問題 - 取ってきた時にissueとPRがどれくらいの割合で帰ってくるか分からない。単純に2倍ではない。 - 「取ってきたけど足りない」というのが問題 - データの詰め直しが必要かも - 最初はrakeタスクでデータをつめる処理が必要かも - issueは、sort=updated を使えばよさそう ## テーブルのデータが、create と update と delete されるタイミング - user - 1度ログインしてるけど、別PCでログインした時にupdateがされる - deleteは退会 - issueとPRの4つのテーブル - これは簡単 - deleteのタイミング - create と update はAPI叩いたタイミング - deleteはない(生データがない場合) - 生データのdeleteのタイミング - 懸念=データ量が多い - 最初は100件でも稼働していくとどんどん増えていく - 量もどんどん増えていくし、JSONデータ自体も重そう(これはやってみないと分からない!テストデータつ方t裏して検証) - 多くて消す必要がある場合は、削除のタイミングを考える必要がある - その場合、 - 外部キーを設定したissue/PRテーブルのデータをどうするか考えないといけない - 1. NULLを入れる - 2. 親と一緒に子も消す - issuesの - 中間テーブル2つがやっかい - createされるタイミングが2つある - userとissue/PR の作成のタイミングが違うので、createが厄介 - updateはこのテーブルはされることはない - deleteは、assigneeからuserが入らなくなった時、紐づいてない