All Articles

失敗から学ぶ RDB の正しいあるき方を読んだ

RDB をうまく使っていくために読んだ。
本書にも書いてあるとおり、悪い設計はデータが増えてきてから問題が顕著になることが多いと思う。
そうなったときにデータの再設計、migrate をするのは中々骨が折れるし、できればやりたくない。
ダウンタイムの計画や顧客のデータを触って事故ったときのリスクが高すぎるように思えるため。

設計のアンチパターンを知ることで、現状うまくいきそうな設計でもゆくゆくこんなトラブルになりそうなことが想像できるようになる。
設計が確固としたものであればその上に乗るデータは長く安心して運用できるようになると考えられるので手札を増やしとくのはいいことだろう。
先人たちの何が正しくて、何が正しくなかったという経験則は非常に役に立つ。
根拠のある知見で今後の設計をよりよくしていきたい。

所感など

  • MySQL8.0.16 からは CHECK 制約が使える

    • Postgres は 9系でも対応している(どのバージョンからかは不明)
  • Postgres と MySQL の違いは調べときたいけど、トランザクション分離レベルが少し扱い異なるくらい理解しとけばいいのかな。根拠のないベンチマークでどっちが早いとか書いてある記事を鵜呑みにしてもしょうがないので。

    • uberの例は気になるので理解しておきたい
  • MySQL の join は NLJ (Nested Loop Join) のみ。よくjoinが遅いって言われるのはこのせいか。

    • 他のアルゴリズムとしては、Hash Join, Sort Merge Join がある
  • クエリの中で計算したり(式を使う)するとインデックス効かないこと多い
  • やっぱ delete_flag は使うと制約が使いづらくなるから設計で避けたいな

    • 全般に言えるけど、テーブルの中で状態を持たないようにする。状態が変わったら新しい概念として取り出すべき
  • ソートが辛いときは Redis の Sorted Set 使うのはあり。特にOFFSET が深くなってくるとスキャンする行が増えて負荷が高い
  • 定期的にバックアップをリストアする予行演習をしよう

    • バックアップから戻せる時間がいつからか把握しとく
    • 最新の機能使えばだいたい直前の状態まで戻せる気がする
  • ロックについてもいつも忘れてる

    • ダーティリード
    • コミット前のデータ見える
    • ファジーリード
    • Tx 中に他の更新が走った場合、そのデータが見える
    • ファントムリード
    • 他のTxからの追加・削除が見える
  • MySQL でも Postgres でも Repeatable Read であればファントムリード発生しない
  • 排他ロックかけるなら For Update 使おう
  • DB もバージョンアップしていこう

    • MySQL 8 !