『達人に学ぶDB設計 徹底指南書』を読みました。
皆様こんにちは、Amiaです。
私はここ何週間かでタイトルにもある通り『達人に学ぶDB設計 徹底指南書』を読んでいました。
そのため今回は上記の書籍について読んだ感想等をまとめいきたいと思います。
よろしければ最後までご覧になっていただければと思います。
⚫︎良かった点
- 論理設計だけでなく物理設計についても記載されている。
- バッドノウハウ、グレーノウハウの例が豊富に記載されていて、著者の実体験にも基づいておりイメージしやすい。
⚫︎学んだこと
「第1章 データベースを制する者はシステムを制す」
「第2章 論理設計と物理設計」
- 論理設計:概念スキーマを定義する設計のこと。
- システムの世界での「論理」:「物理層の制約にとらわれない」という意味。
- システム開発におけるデータベース設計は下記の手順で行われる。
- 論理設計の四つのタスク
- ①エンティティの抽出
- システムのためにどのようなデータが必要になるかを抽出する。
- このタスクの一部は「要件定義」と重なっている。
- システムのためにどのようなデータが必要になるかを抽出する。
- ②エンティティの定義
- 各エンティティがどのようなデータを保持するかを決める。
- 各エンティティがどのようなデータを保持するかを決める。
- ③正規化
- エンティティについて、システムでの利用がスムーズに行えるように整理する。
- エンティティについて、システムでの利用がスムーズに行えるように整理する。
- ④ER図の作成
- エンティティ同士の関係を表現する図を作成する。
- エンティティ同士の関係を表現する図を作成する。
- ①エンティティの抽出
- 物理設計の五つのタスク
- ①テーブル定義
- ②インデックス定義
- ③ハードウェアのサイジング
- システムで利用するデータサイズを見積り、それに十分な容量の記憶装置を選定する。
- システムが十分な性能を発揮できるだけのスペックのCPUやメモリを持ったサーバーを選定する。
- システムで利用するデータサイズを見積り、それに十分な容量の記憶装置を選定する。
- ④ストレージの冗長構成決定
- ⑤ファイルの物理配置決定
- ①テーブル定義
- データベースにおいては、データの整合性とパフォーマンスの間に強いトレードオフが存在する。
- 三つのバックアップ方式
- バックアップ方式にもトレードオフがある。
- リストア及びリカバリの手順
「第3章 論理設計と正規化 ~ なぜテーブルは分割する必要があるのか?」
- 正規化
- 正規化とは更新時の不都合/不整合を排除するために行う。
- 正規化は従属性を見抜くことで可能になる。
- 正規形はいつでも非正規形に戻せる。
- 正規化は常にするべきか?
- 第3正規形までは原則として行う。
- 関連エンティティが存在する場合は関連とエンティティが1対1に対応するように注意する。
- 第3正規形までは原則として行う。
- 正規化とは更新時の不都合/不整合を排除するために行う。
- 正規形:データベースで保持するデータの冗長性を排除し、一貫性と効率性を保持するためのデータ形式。
- 第1正規形
- 1つのセルの中には1つの値しか含まない状態にする。
- 1つのセルの中には1つの値しか含まない状態にする。
- 第2正規形
- テーブル内で部分関数従属を解消し、完全関数従属のみのテーブルを作る。
- テーブル内で部分関数従属を解消し、完全関数従属のみのテーブルを作る。
- 第3正規形
- テーブル内での推移的関数従属を解消する。
- テーブル内での推移的関数従属を解消する。
- ボイス-コッド正規形
- 非キーからキーへの関数従属をなくす。
- 非キーからキーへの関数従属をなくす。
- 第4正規形
- 独立な多値従属性が複数存在するテーブルを分割することで作られる。
- 独立な多値従属性が複数存在するテーブルを分割することで作られる。
- 第5正規形
- 関連がある場合は、それに対応する関連エティティを作る。
- 関連がある場合は、それに対応する関連エティティを作る。
「第4章 ER図 ~ 複数のテーブルの関係を表現する」
- IDEF1X
- 角の尖った四角で表記したエンティティ
- 独立エンティティ:他のテーブルのデータに依存することなく、データを保持することのできるエンティティ。
- 独立エンティティ:他のテーブルのデータに依存することなく、データを保持することのできるエンティティ。
- 角の丸い四角で表記したエンティティ
- 従属エンティティ:他のテーブルにデータが存在しなければ、データを保持することのできないエンティティ。
- 従属エンティティ:他のテーブルにデータが存在しなければ、データを保持することのできないエンティティ。
- エンティティ間の関連:カーディナリティの「多」が黒丸(⚫︎)で表現される。
- 角の尖った四角で表記したエンティティ
「第5章 論理設計とパフォーマンス ~ 正規化の欠点と非正規化」
- 正規化と検索SQLのパフォーマンスは強いトレードオフの関係にある。
- 非正規化は最後の手段。
- 正規化の次数は高ければ高いほど良い。
- 冗長性排除によって引き起こされる性能問題
- サマリデータの冗長性排除
- サマリデータを冗長に保持すると正規形に違反するが、検索を高速化できる。
- サマリデータを冗長に保持すると正規形に違反するが、検索を高速化できる。
- 選択条件の冗長性排除
- 選択条件を冗長にすると第2正規形ではなくなる。
- 選択条件を冗長に保持すると正規形に違反するが、検索を高速化できる。
- 選択条件を冗長にすると第2正規形ではなくなる。
- サマリデータの冗長性排除
- 非正規化のリスク
- ①非正規化は検索のパフォーマンスは向上させるが、更新のパフォーマンスを低下させる。
- ②データのリアルタイム性(鮮度)を低下させる。
- ③後続の工程で設計変更すると手戻りが大きい。
- ①非正規化は検索のパフォーマンスは向上させるが、更新のパフォーマンスを低下させる。
- 論理設計には物理設計の知識が必要である。
「第6章 データベースとパフォーマンス」
- インデックス設計:SQLのパフォーマンス改善のための非常にポピュラーな手段。
- アプリケーション透過的
- インデックスを使うかどうかはDBMSが自動的に判断するため、アプリケーションのコードに影響を与えない。
- インデックスを使うかどうかはDBMSが自動的に判断するため、アプリケーションのコードに影響を与えない。
- データ透過的
- テーブルに格納されているデータの中身が影響を受けることはない。
- テーブルの構造が変化することはない。
- テーブルに格納されているデータの中身が影響を受けることはない。
- 大きな性能改善効果
- B-treeインデックス:最も頻繁に利用するインデックス。
- B-treeインデックスの長所:親ソート性、均一性、持続性、処理汎用性、非等値性が平均的に優れている。
- B-treeインデックスの設計指針
- ①大規模なテーブルに対して作成する。
- データ量が少ない場合はインデックスの効果はない。
- データ量が少ない場合はインデックスの効果はない。
- ②カーディナリティの高い列に作成する。
- カーディナリティが高い列ほどインデックスの効果が高い。ただし、値が平均的に分散しているほうが良い。
③SQL文でWHERE句の選択条件、または結合条件に使用されている列に作成する。
- カーディナリティが高い列ほどインデックスの効果が高い。ただし、値が平均的に分散しているほうが良い。
- ①大規模なテーブルに対して作成する。
- B-treeインデックスを利用できていないSQL
- インデックス列に演算を行なっている。
- 索引列に対してSQL関数を適用している。
- IS NULL述語を使っている。
- 否定形(
<>
)を用いている。 - ORを用いている。
- 後方一致、または中間一致のLIKE述語を用いている。
- 暗黙の型変換を行なっている。
- インデックス列に演算を行なっている。
- B-treeインデックスの長所:親ソート性、均一性、持続性、処理汎用性、非等値性が平均的に優れている。
- B-treeインデックスの注意事項
- 主キー及び一位制約の列には作成不要。
- B-treeインデックスは更新性能を劣化させる。
- 定期的なメンテナンスを行うことが望ましい。
- 主キー及び一位制約の列には作成不要。
- アプリケーション透過的
- 統計情報
「第7章 論理設計のバッドノウハウ」
- バッドノウハウ(アンチパターン)のダメな点
- ①システムの品質に左右する。
- ②後から変更することが容易ではない。
- ①システムの品質に左右する。
- 論理設計の代表的なバッドノウハウ
- 非スカラ値
- 1つのセル内で複数の値を持つことができるデータ型や構造。
- かつては標準機能で「配列型」があり、非スカラ値を含むテーブルを作ることができた。
- 情報は可能な限り分割して保存するのが良いが、意味を壊してはいけない。
- 1つのセル内で複数の値を持つことができるデータ型や構造。
- ダブルミーニング
- 同一の列だが、途中から格納するデータが変わっている。(同一の列が2つの意味を持つ。)
- テーブルや列の意味は、一度決めたら容易に変更してはならない。
- 同一の列だが、途中から格納するデータが変わっている。(同一の列が2つの意味を持つ。)
- 単一参照テーブル
- テーブル分割
- 水平分割:レコード単位でテーブルを分割する手段。
- テーブルを分割することでパフォーマンスを改善できる。
- 分割する意味的な理由がない。
- 拡張性に乏しい。
- 他の代替手段がある。
- テーブルを分割することでパフォーマンスを改善できる。
- 垂直分割:列単位でテーブルを分割する手段。
- SQL文のパフォーマンス改善が可能。
- 分割する意味的な理由がない。
- 「集約」で代替可能。
- SQL文のパフォーマンス改善が可能。
- 集約:テーブル分割の代替案に位置づけられる方法。下記の2種類に分類される。
- 列の絞り込み
- 元のテーブルから必要な列だけを持った新しいテーブルを追加作成する。
- 定期的に元のテーブルとの同期が必要。
- 元のテーブルから必要な列だけを持った新しいテーブルを追加作成する。
- サマリテーブル
- 集約関数によってレコードを集約した状態で保持する。
- 事前に集約を行ったテーブルを作っておく。
- 更新のタイムラグによってデータの整合性がとれない時間帯が生じるデータ同期の問題は列の絞り込みと同じ。
- 集約関数によってレコードを集約した状態で保持する。
- 列の絞り込み
- 水平分割:レコード単位でテーブルを分割する手段。
- 不適切なキー
- 主キー、外部キー、結合キーについては
- 可変長文字列は不変性がないため不向き。
- 同じデータを意味するキーは同じデータ型にする。
- キーには固定長文字列の「コード」列が望ましい。
- 可変長文字列は不変性がないため不向き。
- 主キー、外部キー、結合キーについては
- ダブルマスタ:同じ役割を果たすはずのマスタテーブルが2つ存在するようなケース。
- SQLを複雑にして、パフォーマンスを悪化させる。
- システム統廃合によって生じることが多い。
- SQLを複雑にして、パフォーマンスを悪化させる。
- 非スカラ値
- バッドノウハウのどこが悪いか?
- 運用にかかるコストが高くなる。
- エンジニアやプログラマの設計に対する理解を妨げる。
- 設計変更が難しい。
- 運用にかかるコストが高くなる。
「第8章 論理設計のグレーノウハウ」
- グレーノウハウ:バッドノウハウとははっきり断定することができないが、無神経に使うと開発や運用に支障をきたすような設計のこと。
- 代理キー
- 下記のような主キーが決められない、または主キーとして不十分ケースに利用される。
- そもそも入力データに主キーにできるような一意キーが存在しない。
- 一意キーはあるが、サイクリックに使いまわされる。
- 一意キーはあるが、途中で指す対象が変化する。
- そもそも入力データに主キーにできるような一意キーが存在しない。
- 極力代理キーの使用は避けて、自然キーによる解決を図るべきである。
- 代理キーがそもそも論理的に不要なキーのため。
- 論理モデルをわかりにくくしてしまうため。
- 代理キーがそもそも論理的に不要なキーのため。
- 代理キーを使わず、自然キーだけで解決する場合
- そもそも入力データに主キーにできるような一意キーが存在しない。
- データベース側で打つてはない。
- 業務使用を調整する。
- データベースに投入される前のアプリケーションでデータが一意になるように整形する。
- 業務使用を調整する。
- データベース側で打つてはない。
- 一意キーはあるが、サイクリックに使いまわされるか途中で指す対象が変化する。
- 時点や期間を表す列を持つ。
- 時点や期間を表す列を持つ。
- そもそも入力データに主キーにできるような一意キーが存在しない。
- 下記のような主キーが決められない、または主キーとして不十分ケースに利用される。
- 列持ちテーブル
- 利点
- シンプルな設計。
- 入出力のフォーマットと合わせやすい。
- シンプルな設計。
- 欠点
- 列の増減が難しい。
- 無用のNULLを使わなくてはならない。
- 列の増減が難しい。
- 特殊な状況でない限り、原則として列持ちテーブルは使うべきではない。基本的には「行持ち」テーブル構成を採用するべき。
- 行持ち⇔列持ち間のデータ移行はSQLで簡単に変更できる。
- 利点
- アドホックな集計キー:都道府県テーブルに対してつける地方コード列等のような場当たり的につけるキーのこと。
- 多段ビュー
- ビューは物理的にはSELECT文が書かれたファイルにすぎない。
- ビュー定義のSELECT文を実行して、オリジナルのテーブルにアクセスしてデータを取り出している。
- ビューの背後にあるテーブルの存在を常に意識する。
- データクレンジング:業務で利用されていたデータをデータベースに登録できる状態にすること。
- 代理キー
「第9章 一歩進んだ論理設計 ~ SQLで木構造を扱う」
- リレーショナルデータベースで木構造を扱う方法
⚫︎難しく感じた部分
- イメージしづらい部分があり全体的に難しいと感じた。
- 第6章は内部的な内容で特に難しいと感じた。
⚫︎最後に
今回読んだ書籍は全体的に難しく、イメージしづらい部分が多くあるように感じました。
まだまだ理解不足だということを痛感しました...。
これからアウトプットしたり経験を積んだりして慣れていきたいと思います。
気になった方は是非購入を検討してみてはいかがでしょうか。