達人に学ぶ DB 設計 徹底指南書を読み終えての感想

達人に学ぶ DB 設計 徹底指南書 を読了したので、感想や分かった事について整理していきたいと思います。

良かったところ

この技術書の一番良かったと感じるポイントは何と言ってもその分かりやすさです。
タイトルに「達人」や「徹底指南書」と書いてあるので、取っ付きにくい難しい文章で書かれているのではないかとビビっていましたが、いざ読んでみるとそんな事は無く、例えや言い回しが秀逸で非常に分かりやすいです。

その他自分が感じた良かった点です。

  • 以前の章の内容が出てきても解説が挿入されており、都度ページを捲って戻る必要がない
  • DB 設計におけるアンチパターンの事例が紹介されており、やってはいけないDB設計が分かる
  • 同じテーブルを使い回す事が多い為、テーブルの構造を毎回理解しなくて良い
  • 重要な事については何度も説明されている

悪かったところ

練習問題によってはハンズオンで取り組み内容もありますが、基本的にこの技術書は読むだけです。個人的には手を動かしながらの方が分かりやすいので、ただただ読む作業が辛くはありました。

学んだこと

第1章 データベースを制する者はシステムを制す

データベースには複数のモデルが存在します。
主流なモデルは本書で取り扱われている RDB です。

モデル データ管理方法
リレーショナルデータベース(RDB) 二次元表で管理
オブジェクト指向データベース(OODB) オブジェクトとして管理
XML データベース(XMLDB) XML として管理
キー・バリュー型ストア(KVS) Key と Value の組み合わせで管理
階層型データベース 階層構造で管理


システム開発は以下の順で進めるが、段階的に進める方法と循環的に進める手法がある。

  1. 要件定義
  2. 設計
  3. 実装
  4. テスト
モデル フロー 用途
ウォーターフローモデル 一方向 大規模システム
プロトタイピングモデル 循環的 小規模システム


データベースの構造はスキーマで表され、 3 つのレベルに分けられたスキーマ3 層スキーマと呼ばれる。

スキーマ 特徴
外部スキーマ(外部モデル) ユーザーから見たデータベース
概念スキーマ(論理データモデル) 開発者から見たデータベース
内部スキーマ(物理データモデル) DBMS から見たデータベース

第2章 論理設計と物理設計

概念スキーマを定義する設計を論理設計と呼びます。
論理設計のステップは以下の流れです。

  1. エンティティの抽出
  2. エンティティの定義
  3. 正規化
  4. ER 図の作成


内部スキーマを定義する設計を物理設計と呼びます。
物理設計のステップの以下の流れです。

  1. テーブルの定義
  2. インデックス定義
  3. ハードウェアのサイジング
  4. ストレージの冗長構成決定
  5. ファイルの物理配置決定

第3章 論理設計と正規化

キー

テーブルには基本的にキーと呼ばれる1行のレコードを一意に識別できる鍵が存在します。

キー 意味
主キー 一意のレコードを識別するキー
複合キー 複数の列を組み合わせて作るキー
候補キー 主キーとして利用できる候補のキー
スーパーキー 主キーに非キー列を付加したキー
外部キー テーブルに対して一種の制約を課すキー

外部キーの制約で代表的なものは次の 3 つです。

制約 効果
NOT NULL データに NULL を格納する事を禁止する
UNIQUE 列で重複する値を禁止する
CEHCK データに格納する値の範囲を制限する

正規形

正規形とはデータの冗長性を排除し、一貫性と効率性を保持するためのデータ形式です。 正規形のレベルは第 5 までありますが、実際の業務では第 3 正規形まで考える事がほとんどみたいです。

正規形 定義
第 1 正規形 1 つのセルの中には 1 つの値(スカラ値)しか含まない
第 2 正規形 部分関数従属を解消する
第 3 正規形 推移的関数従属を解消する
ボイスーコッド正規形 非キーからキーへの関数従属を解消する
第 4 正規形 関連エンティティに含まれる関連は 1 つだけにする
第 5 正規形 関連エンティティと関連を 1 対 1 に対応させる

第4章 ER 図

ER 図はテーブル同士の関係性を図に表したものです。
代表的な記法としては IE 表記法と IDEF1X があります。

第 5 章 論理設計とパフォーマンス

実は正規化を行うと SQL の処理が遅くなるという副作用があります(更新速度は上がる)。 理由は正規化は基本的にテーブルを分割して行いますが、そうなると必要なデータを取り出す時にテーブル同士を結合する必要があります。
この結合が非常にコストが高い操作であり、結合するテーブル数やレコード数が増えれば増えるほど処理時間が遅くなります。

では正規化は行わない方がいいのでは無いかという話になってきますが、本書では可能な限り高次にする事が大原則と書かれています。

データ整合性とパフォーマンスはトレードオフの関係にあり、正規形を非正規形より高パフォーマンスにする事は不可能です。

整合性をどこまで落としてパフォーマンスをどこまで上げるか、要件を同時に満たせる平衡点を探し出す能力が求められます。

第 6 章 データベースとパフォーマンス

インデックスは技術書の索引のようなもので、特定のデータのポインタを意味します。

最も頻繁に使われるインデックスは B-tree インデックスです。 名前の通り、木構造でデータを保持します。 最下層のリーフと呼ばれるノードだけが実データに対するノードを持っています。

B-tree インデックスの特徴は以下の通りです。

均一性
B-tree の構造は平衡木でルートからリーフまでの距離が一定で、どんなキー値を使っても、常にリーフまでの距離が一定であるため、処理速度が一定になります。

持続性
テーブルのデータ量が増えても、検索や更新にかかる時間はほとんど増えません。

処理汎用性
他のインデックスと違い、挿入、更新、削除、検索の処理時間が大体同じです。例えばビットマップインデックスは検索性能は B-treeインデックス を上回りますが、更新に膨大な時間が掛かります。

非等値性
等号(=)による検索のみならず、不等号(<、>、<=、>=)や BETWEEN の範囲検索に対しても高速化を可能にします。ただし B-treeインデックス は特定データのポインタを持つため、否定条件(<>、!=)は、特定データ以外のデータとなり、絞り込みが効かず、意味がありません。

親ソート性
B-tree インデックスは構築時にキー値をソートして保持するため、B-tree インデックスが存在する列を ORDER BY で指定すると、ソート処理をスキップできます。


インデックスは無闇に作ればいいという訳ではありません。
インデックスを作る指針は以下の通りです。

  • 大規模なテーブルに対して作成する
    • データ量が少ない場合はフルスキャンの方が速いです
  • カーディナリティの高い列に作成する
    • データ量の時と同じように恩恵がありません
  • SQL 文で WHERE 句、又は結合条件に使用されている
    • そもそもその列が使われないと作る必要がありません

第7章 論理設計のバッドノウハウ

バッドノウハウの事例から見えた設計時のポイントは次の通りです。

  • 配列型を使用しない。第 1 正規形を守る
  • 列は意味的に分割できる限り、なるべく分割する(人名:田中大地 → 姓:田中 名:大地)
  • 同一の列が 2 つの意味を持つダブルミーニングを避ける
  • 水平分割ではなくパーティションを使う
  • 垂直分割ではなくデータマート、又はサマリテーブルを作成する

第8章 論理設計のグレーノウハウ

グレーノウハウの事例から見えた設計時のポイントは次の通りです。

  • いかなるテーブルであっても主キーを作成する
  • 多段ビューは原則として 1 段にとどめる
  • 既存のデータベースを改修する際は、データベース設計前にデータクレンジングを行う

第9章 一歩進んだ論理設計

RDB木構造のデータを扱うのが苦手で、この弱点を克服するために複数のモデルが存在します。 木構造のデータとはトップのデータ(ルートノード)から下にデータが分岐して吊り下がっているようなデータ構造の事です。

モデル 特徴
隣接リスト ノードのレコードに親ノードのポインタを格納する
入れ子集合 ノードを円と見なして、ノード間の階層関係を円の内包関係で表す
入れ子区間 入れ子集合モデルの座標が整数なのに対して実数を用いる
経路列挙 ノードをディレクトリと見なし、各ノードまでの経路をパスで表す

難しかったこと

  • 第 2,3 正規形の役割がごっちゃになり都度それぞれの役割を確認していました。

    • 第 2 正規形: 部分関数従属を解消する
    • 部分関数従属は主キーの一部の列に対して従属性がある事
    • 第 3 正規形: 推移的関数従属を解消する
    • 推移的関数従属は{会社コード, 社員 id} → {部署コード} → {部署名} のように2段階の従属性がある事
  • 木構造RDB を扱う手法について、今ままでの章の DB 設計とは大きく異なる事からかなり難しく感じました。特にモデルが多いため、全てを理解するのは難しかったです。