Slide 1

Slide 1 text

シンプルを極める。 アンチパターンなDB設計の本質 1

Slide 2

Slide 2 text

CTO/Co-Founder 梅林 泰孝 @ystk_u - 2013年 Google に新卒⼊社、検索の品質チームに参画 - 2014年 サイバーエージェントに転職後、AirTrack の開 発責任者として開発‧プロダクト戦略にも携わり、国内 最⼤規模の位置情報プラットフォームに成⻑させる - 2018年 SmartNews の TechLead としてシリコンバレー に移住し、⽶国エンジニアチームを⽴ち上げ、 MAU 2000万超の Push 通知基盤をマネジメント - 2021.10 Facilo を共同創業 - 2024.2 シリーズ A 12億資⾦調達 - 2025.2 帰国 - 2025.11 従業員64⼈(内エンジニア19⼈) 2

Slide 3

Slide 3 text

associationとcache 親会社 ⼦会社 従業員 機能の on/off や default の振る舞いが設定可能で 親の設定を⼦供が上書きできる形で利⽤されている 3 機能の出し分けなんかだと毎 session で必要な情報だったりするので 親の親までアクセスするのを cache を利⽤して不必要な DB アクセスを絞る

Slide 4

Slide 4 text

associationとcache 4 pseudo code

Slide 5

Slide 5 text

associationとcache ALB App Sticky Session この cache は FileCache を使⽤ 脱Redis FileCache 5 File なので User が round robin された違うサーバーに request するともちろんcache hit しなくなるかも。(同一親会社や子会社の hit率は高そうだけど) → ALB のSticky Session を使うことで同じサーバーに基本的に向くようにする ?「でもそれって、偏りがでるんじゃ」「 cache hit 率そもそも低すぎ....」 → 10万 DAU でも余裕で 2vCPU 1台でさばけている。 そんなに立派なリクエスト数捌いてる?、縦になるべく大きくして Redis 依存減らすほうがメ リット大きくない?( Redis ってマネージドってほどマネージドじゃないよね .... リシャー ディ....)、そして local file は早い...

Slide 6

Slide 6 text

ModelとDB設計 - DB 外部キーはいれない - トランザクションあんまり貼らない 6 - dependent: :destroy でだいたい⼗分。外部キーあると、実⾏順序とか気にしないといけない 認知コスト増える。書き込み速度落ちる(すこしでも気にする理由後述) ぼっち record できたとしても参照失ってることも多いので、実害が出にくい。 トランザクションいるほど⼤切な依存ですか?これも認知コストが⾼くなる。 お⾦とか扱うとか critical な依存や、ぶっ壊れる可能性があり、ユーザーインパクトが多い ときのみ利⽤くらいでいんじゃない。

Slide 7

Slide 7 text

ModelとDB設計 - DB にunique 制約を⼊れて、model にはunique 制約をいれない 7 - 複数のサーバーだったり、マルチプロセスだったりマルチスレッドだったりで、そもそも model の制約は厳密ではない。DB で守っていたら、無駄な select の発⾏も抑えられるし、い らないと思う。form 等のエラーメッセージが⼤切ならなにか⼯夫をいれる。 DB の unique 制約も uuid とかだったらまず被らないので index だけにしたほうが書き込み早 くていいと思う(すこしでも気にする理由後述)

Slide 8

Slide 8 text

ModelとDB設計 - 検索対象にならない項⽬は json field のような スキーマレスな column を使う( store にする) 8 - store のいいところは json みたいなスキーマレスなも のでも、何がはいっているかを型として明⽰できるこ とにある。queryable でないデータって全部 json に 突っ込んでもいいと思っている。不可逆な変更ではな い。query したくなったら add column してパッチ当 てたらどうだろ。( json も index つけれたりするけど ね) かと⾔ってスキーマレスだから DynamoDB !とい うのもすこし違うと思う。latency もそうだけど、 パッチ当てづらい、schemaの versioning 管理しにく い。iteration が回しにくい。

Slide 9

Slide 9 text

パッチ⽤のAd-hoc Runner schemaless なjson field とパッチの持続可能な運⽤はセットで考える 9 - rails g で作れるようにして、⽣成物の header に generate コマンドを書くことで ⽂化として根付かせる。同じ template で作ることで実⾏の管理をしやすくする。 migration に混ぜると rollback 耐性がなかったりするのでいれない。⽇付 versioning で gitignore した history file で各々管理する座組を作るくらいでわりと⼗分運⽤できる

Slide 10

Slide 10 text

マルチテナント, マルチプロダクトのDBのインフラ戦略 Product A Product B Product C Single DB Cluster( Primary + Replica ) ( database 名で product ごとに分割) Primary Replica Replica 10 運⽤コストを極限まで下げる (現実的な⾒積もりを常にする) 複数のクラスターをサービスごとに最適化するのはコスト。 共有で CPU パワーつけたほうがインフラのエコシステムも享 受もしやすい。10年前より、ハイパフォーマンスで縦にもか なり⼤きくなるので、single primary の書き込みがボトル ネックには意外とならない。なるときは分割すればいいし、 そのときは結構組織サイズも⼤きくなっているくらい売上実 際出ているはずである。それくらいの作業は重くないでしょ う....

Slide 11

Slide 11 text

マルチテナント, マルチプロダクトのDBのインフラ戦略 11 更新系は参照系の5%程度 プロダクトの性質によるが、あと10プロダ クトは同じ Primary に載せられるんじゃな い....

Slide 12

Slide 12 text

疎結合な⾮同期処理(SQS) SQS Worker - SQS はフルマネージド(安定してる) - SolidQueue を使わないことで DB の書き込み リソースを節約 - Rails の ActiveJob や Shoryuken のフォー マットに乗らない 再実⾏性をあげ、他 micro service から呼びや すくする。cli でちょろっと json message 送 るだけでも実⾏可能 脱密結合 12

Slide 13

Slide 13 text

検索は Rails でやらない( OpenSearch ) Rails で頑張りすぎない。 OpenSearch への indexing, querying, analyzing は interface を汎化させることで multi product で活躍する⼤きなエコシステムになる App SQS Worker (indexing) 13

Slide 14

Slide 14 text

おしまい Follow me @ystk_u 14