$30 off During Our Annual Pro Sale. View Details »

限界ORM!BOOTHとギフトとライブラリ【PIXIV MEETUP 2023 LT】

RND
September 29, 2023

限界ORM!BOOTHとギフトとライブラリ【PIXIV MEETUP 2023 LT】

かつてBOOTHのライブラリは、自分が購入した商品を並べるシンプルな世界でした。そんな世界に<購入せず、所有ができる>ギフトという概念が生まれ、シンプルだった世界は終焉を迎えます。BOOTHのギフト機能実装の際にハマったActiveRecordの落とし穴とその解決策の話です。

RND

September 29, 2023
Tweet

Other Decks in Technology

Transcript

  1. pixiv Inc.
    限界ORM!
    BOOTHとギフトとライブラリ
    RND

    View Slide

  2. Profile
    RND
    エンジニア
    クリエイター事業部 BOOTH部所属
    絵と漫画を描く が趣味
    RND(らんど)と読みます

    View Slide

  3. 前提知識
    検索する時に自動でクエリを組み立ててくれる心づよい友達
    ORM (= Object Relation Mapping)
    RDB レコードとオブジェクトとを変換する技術
    ActiveRecord: Rails ORMフレームワーク

    View Slide

  4. 今回 話

    View Slide

  5. BOOTH ギフト機能 なし
    クリエイターとファンを繋ぐ
    C2C 販売プラットフォーム
    Railsで書かれている
    今年10周年
    BOOTH

    View Slide

  6. 2022年12月

    View Slide

  7. DL商品を購入する
    ギフト用URLが発行される
    URLにアクセスすると
    他 人が
    DL商品を受け取ることが
    できる

    View Slide

  8. こ 機能

    View Slide

  9. 実装が大変だった

    View Slide

  10. これまで BOOTH
    所有者 = 購入者
    注文 LineItem
    注文と商品 関連テーブル
    商品
    購入者
    (所有者)

    所有


    これが...
    注文完了かつ、LineItemがあれ 所有してる

    View Slide

  11. ギフト 場合
    所有者 ≠ 購入者
    注文 LineItem
    注文と商品 関連テーブル
    商品
    購入者 *
    所有(ギフトじゃない時)


    ギフト
    受取ユーザー
    所有(ギフト 時)

    View Slide

  12. ということ
    所有=購入で運用されてきたサービス
    所有と購入を分離、影響箇所 ...
    注文
    LineItem
    注文と商品 関連テーブル
    商品
    購入者
    発送
    売り上げ管理
    カート
    pixivFACTORYと
    連携
    送り状(伝票)
    生成
    レコメンド
    アルゴリズム
    無限にある

    View Slide

  13. ということ
    所有=購入で運用されてきたサービス
    所有と購入を分離、影響箇所 ...
    注文
    LineItem
    注文と商品 関連テーブル
    商品
    購入者
    発送
    売り上げ管理
    カート
    pixivFACTORYと
    連携
    送り状(伝票)
    生成
    レコメンド
    アルゴリズム
    無限にある
    it’s 無理

    View Slide

  14. やった
    意外となんとかなる
    必要な 気合い
    やったらできた
    grepして出てきた箇所をnotionに書き出して影響 有無を判断

    View Slide

  15. 本題

    View Slide

  16. ライブラリ なし

    View Slide

  17. ライブラリ
    ギフトによって
    所有 経路が2種類になった
    所有している商品が入手順に並ぶページ

    View Slide

  18. ギフトで受け取った商品も
    自分で買った商品も
    ライブラリに入手順で並べる

    View Slide

  19. 2種類 経路でJOINされたテー
    ブルを結合
    でもRails(ActiveRecord)にない
    unionを実装したgem?
    もしく 生SQLを書くか、orメソッドなどで頑張る
    UNIONが必要そう

    View Slide

  20. 分けたらええやん
    「無理そう」な設計が出たら要件を見直す
    別ページに分けて解決、ユーザーも困らない。
    ギフトで受け取った商品
    別ページに遷移して表示

    View Slide

  21. まだある

    View Slide

  22. ギフト、何回でも受け取れる
    こんなケース
    こ 前言ってた
    アバター、
    プレゼントで送ります
    好きそうなアバター
    あったんでギフトで
    送ります
    ダブってしまったけど
    受け取らない も
    申し訳ないなぁ...

    View Slide

  23. 受け取れます

    View Slide

  24. 何回でも

    View Slide

  25. ということ

    View Slide

  26. ライブラリ
    複数回受け取った商品
    最新 1件だけ表示される
    所有している商品が入手順に並ぶページ
    new!

    View Slide

  27. 複数回受け取った場合
    GROUP BY `商品`
    1件にまとめて表示
    ORDER BY `ギフト.受け取り日時` DESC
    最近受け取ったも が先にくるように並べる

    View Slide

  28. こうか??

    View Slide

  29. ダメ
    ORDER BY GROUP BY より後に実行される

    View Slide

  30. 欲しいクエリ これ
    ActiveRecordで記述する手段 ない、一部生SQLになる

    View Slide

  31. 別 案: サブクエリ
    件数がめちゃくちゃ増えてくるとパフォーマンスが悪くなる
    ActiveRecord from を使うとサブクエリが使える

    View Slide

  32. もっと良さそうな案
    変えようぜ、テーブル設計
    所有を表現するテーブルを用意
    アプリケーションで整合性を保つ
    移行する 大変だが
    シンプルで変更につよそう

    View Slide

  33. すまんがリリースまで時間ないわ
    実装する に時間がかかる
    今回 サブクエリ案で年内にリリース。
    ユーザーに素早く価値を提供することが大事

    View Slide

  34. まとめ:教訓
    ActiveRecord、なんかすぐ限界になりがち
    限界が見えたら
    1. まず要件と仕様を見直す。 コードを書かずに解決しよう
    2. テーブル設計を見直す。 プロダクトをシンプルに保とう
    3. ActiveRecord芸を頑張ったり、生SQLもありかも
    (ユニットテストがしっかり書かれててCIでテストがちゃんと動いてるなら生SQLで別にいいんじゃないか(小声))

    View Slide

  35. 早くこれにしたい で、エンジニアを募集中
    ご清聴
    ありがとうございました

    View Slide