massa142's blog

くり返す このポリリズム

「失敗から学ぶRDBの正しい歩き方」を読んだ

失敗から学ぶRDBの正しい歩き方 (Software Design plus)

失敗から学ぶRDBの正しい歩き方 (Software Design plus)

動機

  • データベース設計のリファクタリングをしていてRDBに関する本が読みたくなった
  • ロックについては毎回調べてもすぐ忘れるので、ちゃんと頭の整理をしたい

感想

アンチパターンとして言語化されることで、頭のなかで漠然とよくないよねと思っていることを明確にすることができた。各章のはじめにはそのアンチパターンを簡単な現場ストーリーをもとに紹介しているんだけど、むかし運用していたプロダクトを思い出させられてすごく懐かしくなった。

またRDBSQLの書籍だとPostgreSQLだけを扱ってるのが少なくないけど、MySQLPostgreSQLの挙動の違いがあるところはちゃんと説明してくれていてわりやすかったです。そーだいさんの人柄がでてる優しい文章で読みやすく、各章深掘りはせず詳しいことを知りたい場合は参考文献に逃しているので、基本をおさえる・振り返るために最適な一冊だなと思います。

読書メモ

第2章 失われた真実

  • 履歴データはRDB内にどれくらいの期間もっておくべきか難しい
    • ある時期よりも前のものは削除するかS3に退避させるのがいいんだろうなー

第3章 やり過ぎたJOIN

  • JOINのアルゴリズム
    • Nested Loop Join (NLJ)
    • Hash Join
    • Sort Merge Join
    • MySQLではNLPしかサポートしていない
  • JOINは必要最低限
  • INDEXを適切に活用する
  • JOINするテーブルは小さくしてからJOINする
  • 複雑なクエリになった場合はViewを活用する

第4章 効かないINDEX

  • INDEXが使われる条件
    • 検索結果がテーブル全体の20%未満
    • 検索対象のテーブルが十分に大きい
  • PostgreSQLには式INDEXという機能がある
  • あいまい検索でINDEXを利用するケースは前方一致のみ

第5章 フラグの闇

  • 「とりあえず削除フラグ」アンチパターン
  • テーブルに状態を持たせず事実のみを保存する
    • 「削除済み」のためのテーブルを定義する

第6章 ソートの依存

  • WHERE句狙いのINDEX
  • ORDER BY句狙いのINDEX
  • OFFSETで指定したデータ範囲が大きくなるとINDEXは効かなくなる
  • 実行されないとわからないORDER BYの問題

第7章 隠された状態

第8章 JSONの甘い罠

  • APIの戻り値を格納するのに便利
  • ユーザーが任意で登録する値でスキームレスなものとかも

第9章 強過ぎる制約

  • 外部キー制約が生み出すデッドロック
    • MySQLだと、外部キー制約の子テーブルを更新すると、親テーブルの共有ロックを自動的に取る
  • 強い制約はアプリケーション側の責務として持たせる

第10章 転んだ後のバックアップ

  • バックアップの手法
    • 論理バックアップ
    • 物理バックアップ
    • PITR(Point In Time Recovery)

第11章 見られないエラーログ

第12章 監視されないデータベース

第13章 知らないロック

  • ロックの種類

    • 排他ロックと共有ロック
    • 表ロックと行ロック
  • PostgreSQLはSELECTでも「AccessShareRock」という一番小さなロックを取得

  • MySQLの特徴的なロック
    • 対象が存在しなくてもロックを取るギャップロック
    • 対象よりも1つ先の行までを取るネクスキーロック

第14章 ロックの功罪

  • トランザクション分離レベル
    • read uncommitted: ダーティーリード発生
    • read committed: ファジーリード発生
    • repeatable read: ファントムリード発生
    • serializable: 完全な直列処理
  • MySQLのデフォルト: repeatable read
    • 後勝ちのロストアップデートが起こりうる
      • SELECT ... FOR UPDATE で排他ロックを取得すればOK
  • PostgreSQLのデフォルト: read committed

第15章 簡単過ぎる不整合

  • 非正規は用法用量を守ってお使いください

第16章 キャッシュ中毒

  • キャッシュは麻薬

第17章 複雑なクエリ

  • スパゲッティクエリは分解して、アプリケーション側で加工する
  • SQLが書きにくいなというときは、テーブル設計に問題が隠れている

第18章 ノーチェンジ・コンフィグ

  • Database as a service
    • コンフィグの管理を自分たちで行わない

第19章 塩漬けのバージョン

  • バージョンアップする文化を作る

第20章 フレームワーク依存症

  • ORMが発行するSQLRDBMSに最適化されたものではない