「失敗から学ぶRDBの正しい歩き方」いつの間にか辛いを避ける歩き方
アドカレ15日目
プロダクトコードの負債より、DBの負債の方が大変だと感じています。DBの負債を変える場合、プロダクトコードにあるDBの読み込み・更新まで全て変更する必要がありますからね。
そういった点でも、いつの間にか沼地に迷い込んでいたということが起きないような道標になる良本です。
MySQLはjoinでNLJしか対応していない
Nested Loop Joinの略で参照される行数分だけループが行われるというもの。
JOINの対象となるカラムにINDEXを貼ると速くなるのは参照去れる行数が減ることだったらしい。逆にFORCE INDEXで安定して早くなる理由も納得がいった。こういうのはやはり実装などをみておかないといけないなーと感じたところ。
Ruby on Railsなどは外部キーを作ると自動でインデックスも貼ってくれて、本当に意識せずに全部やってくれるなぁと感心する。
Viewテーブルかサマリーテーブルか
複雑なSelectクエリの発効が余儀なくされる場合の選択肢として、個人的にはViewを使うことが多いです。理由としてはやはり変更に強いこと。
サマリーテーブルはトリガーのタイミングなどを含め、実装が非常に複雑になる場合が多かったり、いざ即時のデータが欲しくなると時間がかかったりと痛い目を見たことが多いというのもあります。
Viewテーブルも参照時にクエリが走るなど辛くなってくる段階があるので、「そもそももっと使いやすい形にできないか」を考えてDB設計を考える必要がありますね。この辺はカーディナリティなどの話でも出てきますがデータの偏りなどを予想する必要が多いので「どのような特性のデータか」というところは十分に理解してからDBを設計する必要があるし、腕の見せ所だよなーとなるところ
クラウドやツールの大切さ
バックアップからログ、DBのモニタリングまで本当にクラウドの恩恵を受けていたのだなと感じるクラウド世代でした。
特にDBのチューニングなどは監視ツールを入れることで、スロークエリの順位なども見れるので立ち向かい方が変わってきます。特に、1ユーザーだけ特殊のデータの偏りをしていてインデックスが効いていないなど面白いことが見つかりますし、コンクションプーリングができていないなどの早期発見にもつながります。
本当に監視ツールは偉大。また、どこを監視するかについては監視入門などの書籍に譲ろうと思います。
また、クラウドの利点として「強制的にバージョンを上げさせられる」というものもありますね。19章の塩漬けのバージョンの対策にもなります。強制的にバージョンをあげるので、単なる利点とも言えませんが怠惰を重んじるエンジニアにとって、こういう強制性は重要になってきますね。
フレームワークと実行計画
ここで筆者のツイッターを見てみましょう。
— そーだい@初代ALF (@soudai1025) 2018年5月28日
そう。ORMの作るクエリは人類には厳しすぎるんです。Ruby on Railsの作るクエリなどをみていると「え、何このクエリ。え、でも実行計画はいい感じだな」となることがあります。これは正しく外部キー制約が貼られているおかげでもありますね。
ただ、フレームワークのORMに依存しすぎて、実際のクエリをみない人がそこそこいるのも悲しいことです。どのようなクエリが作られ、どのような実行計画になるのかは常に確認するようにしようね!!!
状態を管理する
アンチパターンの1つだがとても見る。ユーザーテーブルにある権限のカラム、受注テーブルにある受注状況のカラムなど様々な状態を管理するカラムを見てきたし戦ってきた。
特定の状態毎にテーブルを作るのが良いのは本書を読めばよくわかるが、なぜそれをしないのか・思いつかないのかを考えていく。状態ごとによって持つ情報が変わること知らない知識の不足もあるし、単純に実装の容易さもあるだろう。また、論理削除と同様に考えるというのもありそう。何より状態が増えるたびにテーブルが増えるということも問題となるのだと思う。
人間の記憶の特性として、7つ以上のものは記憶や理解が辛くなってくる。そのため、状態毎のテーブルやそれに関係するテーブルが自身の理解できる範囲内に収めようという思考が働くように感じる。命名などで群として捉え易くするなど、人間が情報処理しやすい命名や設計も重要になりそうだ。
他にも
ロックなどいろいろなことが書かれているので是非
MySQLのギャップロックなど、DBによる特殊な挙動など専門書を読むとより詳しく書かれているのでそちらを読むと良さそうです