See the Elephant

1992生まれのプログラマが書くエンジニアブログ

phperKaigi 2019に行ってきた そーだいさんの失敗から学ぶRDBの正しい設計を聞いた

2日目

そーだいさんの発表「アンチパターンから学ぶRDBの正しい設計」を聞いてきた。

そーだいさんの本はこちら。

スライドはこちら

speakerdeck.com

基礎になる本はこちら。

このブログはメモ的に書いておく

#失敗から学ぶRDB

  • 愚者は経験に学び賢者は歴史に学ぶ
    • 他社の失敗を知ることで自分の失敗を防ぐ

フレームワーク依存症

  • アプリケーションを作るときはFW使うのが当たり前
  • FWの制約を受け入れる必要がある
    • 顕著なのはORM
    • modelからRDBMSを操作するときsqlを叩きたい
      • 言語によって差異がある
      • ormによってラップされることによって便利に使える
  • ormはモレのある抽象化
    • N+1問題
      • コードだけをみるとinner joinなのかsqlが実行されているのかわからない
      • get() という関数を見てもどういう実行処理が行われるかわからない
        • これが漏れ
  • Fw強い制約と規約によって高い生産性を与えてくれる

  • Active Recordパターン

    • ViewとModelが一対一
    • Viewがテーブル設計に影響を与える
    • 時に毒になる
      • バグってる時
      • 仕様変更で想定してない仕様になった時に顕著に出てくる
  • sqlアンチパターンをうむ
  • FWもORMも絶対悪ではない
    • 漏れを補えばいい
  • Repositoryパターンで回避する
    • service層: ビジネスモデル
    • data層: データ変換するだけ(データ元は気にしなくていい)
    • repository層: データ元を知っているが、共通のインタフェースを与える
  • FWもORMもメリットデメリットを含めて使う

知らないロック

  • RDBMS/トランザクションはデータを守るための仕組み
  • 排他ロック, 共有ロック
  • 表ロック, 行ロック
  • 意図しないロックはデットロックを生む
    • お互いに依存している処理を待つ現象
  • 共有ロックを生む
    • 変更すると困るのでロックを取る
      • insert...select構文
      • create table ... as select構文
      • 知らないうちにロックが取られている
      • ギャップロックとネクスキーロック
  • このRDBMSでは〇〇だから別のRDBMSでも一緒のはずだ、は危険
  • ロックはパフォーマンス問題に直結
  • 時にはクリティカルなバグを海サービス停止もありうる
  • 正しい知識を身に着ける

キャッシュ中毒

  • キャッシュの利用は劇的なパフォーマンス向上がある
  • キャッシュは中毒性がある
  • キャッシュはシステムの複雑度があがり, トラブルシュートが難しい
  • クエリキャッシュ
    • 計算結果をキャッシュしておく
  • マテリアライズドビュー
    • 計算結果を物理テーブルに残しておく
    • 本来は計算するものなのでキャッシュとみなす
  • アプリケーションキャッシュ
    • アプリケーションがハンドリングするキャッシュ
  • キャッシュの問題はクリティカルな問題につながる
    • memcachedのキャッシュが一気に消えた
    • 一気にRDBMSにrequestがきてアクセスがパンクする
  • 見えてはいけないデータ
    • myページのキャッシュを持っておくと別の人がログインした時に見えてはいけないデータが見える
    • 200返しているのでテストがめっちゃむずい
    • 事故が起きるのは防ぎにくい
  • キャッシュ戦略を最初に立てる
    • キャッシュを探しに行っても当たらない場合はボトルネック
    • キャッシュヒット率と更新頻度はサービス成長とともに変化
    • 後から変えないといけないパターンや時期が来る
  • キャッシュの多段化は危険
    • 必要だと感じたら設計を見直すべき
    • 多段キャッシュした時点で設計ミス
      • 設計を見直しましょう
  • 愚者は経験に学び賢者は歴史に学ぶ
  • データベースの寿命はアプリケーションよりも長い
    • アプリケーションからブログの機能が消えてもアプリケーションにはブログのデータが残る
    • データは追加できるけど、すでにあるデータは消すと戻せない
  • エンジニアは仕組みを変えることができる
    • RDBは本を数冊読むだけで正しい知識がつく

Q&A

本から学んだ知識と実態が大きく違うことがある
DBリファクタリングする時にどこから手をつければいいのか
  • アプリケーションから直す
    • テストをやりやすい
    • 設計を見直す
      • いつか永続化層の見直しが必要になる
      • そこから手をつければいい
    • デプロイができやすい -> rollbackしやすい
  • rdbmsは負荷がかかる時間や落とせない時間があるので後回ししやすい
  • rdbmsは長い時間がかかる
JSONを使うとORMとの相性がいい
  • JSONRDBMSと相性が悪い
  • RDBMSの制約が効かなくなる
  • アプリケーションも型についてきにすることが多くなる
  • select * ascでとれるものがすごく複雑になる

買って読むかぁ...