達人に学ぶDB設計徹底指南書を読んで

初めに

前回はスッキリわかるSQL入門を読んで - john-hc20230703の日記にてSQLについて学んでいきました。
今回は達人に学ぶDB設計徹底指南書を読み、設計について集中的に学習を行ったので、それについての感想になります。

DB設計について事前に持っていた知識や、感じていたことは

  • コードを書いていて、DB設計に引っ張られて煩雑なコードにせざる得ないケースが多々ある
  • 正規化は第三正規形までを基本的に行う
  • 各正規化の理由はよく分からぬまま必要なことだからという認識
  • RAIDも言葉は知っているが、それぞれの特徴は知らなかった
  • パフォーマンス改善にインデックスを付ければいいと聞いてはいたが、どんなケースで効果が高いか知らなかった
  • 悪い/良くない設計(バッドノウハウ、グレーノウハウ)があることは知っていたが、どんなものか、何が悪いかまで知らなかった

といったもので、なんとなしにDBを使っていた人は割りとこんな感じだったりするのかなと思っています。

なんとなくの理解で済まして部分が、この本を読むことで「そういうことだったのか〜!」と腹落ちしたり、設計について気をつけねばならないことを知ることができました。
また、一貫して良い面と悪い面、トレードオフを強調されていて、判断基準が養われたように思います。

良かったこと

  • 見出しレベルの知識しかなかったものについて、内容を学ぶことができた
  • 全体を通して、技術/手法の使用(正規化やインデックスなどなど)に対してのメリット/デメリットを学べた
  • ER図を見てデータの繋がりがわかるようになった
  • 最終手段である非正規化までに考えるべき多くのパフォーマンス改善の方法を学べた

などです。
1個目に上げたものに全部が内包されているような気もしますが。笑

学んだこと

データ設計の重要性

データ設計がシステムの品質を最も大きく左右する。

という言葉が本書内にあるのですが、自分が開発に携わる中で感じていたことに対してまさにといったものでした。
テーブルの設計がこうなっていればよりシンプルだったのでは…?ということが多くあったので。。

性能のボトルネックになるのはストレージのI/Oであるケースが多い

データベースのファイルを分散させること、また読み出し/書き出しを最も頻繁に行うファイルについては、最も高性能なハードウェアをあてがうことが大切。
論理設計だけでなく、物理層まで幅広い知識が必要。

サイジングは難しい。小さいよりは大きい方が絶対良い!

大きい分には後から、「ここにこんなにお金かけなくても良かったんじゃない?」と小言を聞くだけで済むだろうが、小さすぎた場合にはシステム障害に繋がる可能性が高くなる。
大は小を兼ねる考えで、しっかり安全率を掛けよう!

RAIDについて

パッと読んで、RAID6とRAID10、どっちも最低必要になるディスク数が同じなら最低コスト同じじゃないの?と思ったのですが、RAID10はミラーリングするのでディスク使用効率から考えるとより大きな容量を必要とする分、高コストになるという理解で良いのかな?
耐障害性(2本まで壊れても大丈夫か、1本までか)や読み出し性能(RAID10が優勢)で要件に合わせて選ぶことになるというのが自分としての整理。

正規化、正規形について

第1~3の正規形については、冒頭で書いたように基本的に行う必要があるという漠然とした知識を持っていたが、本書を読むことでそれぞれの正規形がなぜ必要であるのかを知ることができた。
また、より高次の正規形については存在もよく知らぬものでした。
高次の正規形にすることで、更新作業の冗長性排除、整合性を保ちやすくなるなどいい点もあるが、欲しいデータを取得するにあたって多数の結合が必要になることで高負荷な処理になるなどのデメリットもある。

性能改善を行うに当たって、パフォーマンスチューニングでどうしようもない場合の最終手段として、非正規化を行う場合がある。
正規化は機械的に出来るが、非正規化はその業務に精通し、トレードオフを見極めて行う必要がある。

様々なパフォーマンスチューニングの方法

インデックス

どのようなデータに付与するのが効果的かデメリットはなにか、またパフォーマンスチューニングでよく耳にする理由を知ることができた。
インデックスをつける規模のデータ量を扱う機会がなかったのもあるが、せっかくインデックスをつけても使用されないケースがあることも知らなかった。 とはいえ、強力な武器であることは確かなので、検討する際にまず上がってくる手法だと感じた。 よく使われるB-treeインデックス以外のビットマップインデックス、ハッシュインデックスについての特徴も学ぶことができる。

統計情報

SQLが実行された際、データへの効率的なアクセスパスを決める際に使用されるメタデータ
これが古いと適切なアクセスパスが得られない(更新されていないカーナビのようなもの)ので、大幅な更新があれば、統計情報も再収集する必要がある。
なるべく早く更新するのが好ましいが、実情は非常に重い処理なのでサービス利用者の少ない夜間に行う事が多い。 また、統計情報を凍結するという手段が有効なケースもあるということ。

様々なバッドノウハウ

ある程度データベースに触れてはいるので、「そんなことやらんやろ」と思うものもあるのですが、そうなってしまうに至る経緯まで紹介されているので、納得できる。
本書では、水平分割、垂直分割や集約についてもバッドノウハウの章に入っている。
これらは結構やりがちなケースに思うので気をつけねばならないと感じた。
特に水平分割は、多くのDBMSが持つパーティションという機能で効果を満たせるので、避けよう。 水平分割の場合だけでなく、代替手段やそれ以前の対策の方法まで書かれているのが助かります。

様々なグレーノウハウ(本書内の造語)

こちらもバッドノウハウ同様、代替手段やそれ以前の対策の方法まで紹介されています。
列持ちテーブルはやりがちだなと感じつつ、またそれに対して行持ちにすることで欠点が大分少なくなるということや、列持ちテーブルから行持ちへ変換する方法まで書かれていて有用に感じました。
また、仮想的にテーブルを作るビューや、更新を起点にSQLを発砲するトリガーは、知らぬところで多段に重なっていかないよう、用法用量をよく守って使わないと、気づけば恐ろしいことになりそうだと。。

リレーショナルデータベースが苦手な木構造の取り扱い方法

いくつかのモデルが、そのメリット/デメリットと特徴について紹介されています。
図や、ノードやリーフの取得方法を解説するSQLもありイメージが付きやすいです。

この本は2012年のものですが、入れ子区間モデルの将来性に期待するのような文章がありました。
しかし今、入れ子区間モデルについて検索してもあまり盛り上がってる雰囲気がないので実用に耐えないということでしょうか?
有力になっているのであれば、かなり使い勝手が良さそうだなと感じたのですが。。

最後に

本書はいわゆる入門書ではないので、一度で理解するのは難しく感じました。
この記事はあくまで感想を書いていますが、裏で学習した内容を自分用にまとめたものは、かなり長くなっています。
まとめられる程度に理解するにあたって、三周読んでやっとといった形でしたが、とても読んで良かったと思う内容でした!

ここまで読んでいただき、ありがとうございました!