達人に学ぶDB設計徹底指南書　2章　要約

達人に学ぶDB設計徹底指南書の2章を要約してみた

# この記事を書いた人
https://twitter.com/noobmental456

# 2-1 概念スキーマと論理設計
- 概念スキーマを定義する設計を、論理設計と呼ぶ
- 「論理」の意味は、物理層の制約に囚われない意味
- 論理設計は物理設計の前段階に位置づけられる
- 論理設計のステップ
    - エンティティの抽出
    - エンティティの定義
    - 正規化
    - ER図の作成
- エンティティの抽出
    - エンティティは物理実体を伴う必要はない
    - 例えば、顧客、社員、車、税金、注文履歴など
    - このタスクは要件定義にあたる
- エンティティの定義
    - エンティティを抽出した後は、各エンティティがどのようなデータを保持するかを決める必要がある
    - エンティティは、データを「属性（attribute）」という形で保持する
    - 属性とは、二次元表における「列」と同義
- 正規化
    - 正規化（normalization）は、エンティティ（テーブル）について、システムでの利用がスムーズに行なえるよう整理する作業
    - エンティティのフォーマットを整理することが重要である
    - 単にエンティティを抽出するだけだと、システムの利用に耐える状態にはならない
    - そのため、リレーショナルデータベース（DBMS）の論理設計では一番重要な作業と言える
- ER図の作成
    - 大量のエンティティ同士の関係を表現する図を作成する作業
# 2-2 内部スキーマと物理設計
- 物理設計は、論理設計の結果を受けて、データを格納するための物理的な領域や格納方法を決める工程のこと
- 物理設計のステップ
    - テーブル定義
    - インデックス定義
    - ハードウェアのサイジング
    - ストレージの冗長構成決定
    - ファイルの物理配置決定
- テーブル定義
    - 論理設計で定義された概念スキーマをもとに、それをDBMS内部に格納するための「テーブル」の単位に変換していく作業のこと
- インデックス定義
    - インデックス（索引）は、リレーショナルデータベースにおいてテーブルと並んで重要な概念
- ハードウェアのサイジング
    - システムで利用するデータサイズを見積もり、それに十分な容量の記憶装置（ストレージ）を選定すること
    - システムが十分な性能を発揮できるだけのスペックのCPUやメモリを持ったサーバーを選定すること
    - ちなみに、データベースの性能問題の8割はディスクI/Oが原因である
    - データベースにおいては、データの整合性とパフォーマンスの間に強いトレードオフが存在する
    - データの整合性を高くしようとするとパフォーマンスが犠牲になる。反対もある
    - サイジングが大きすぎれば予算を抑えることができたはずで、小さすぎればサービスの運用に影響を及ぼすため、この作業が一番難しい
- キャパシティのサイジング
    - システムで利用するデータ量については、物理的なテーブル定義およびインデックス定義が終わらなければ算出できない
    - サービス終了時までの上限データを見積もるのは難しい。これに対しての有効なアプローチとして、安全率を大きくとって、余裕を持たせたサイジングを行なうこと。容量不足が発生した時に、容易に記憶装置を追加できるような（スケーラビリティ、拡張性が高い）構成にしておくことが重要である
- パフォーマンスのサイジング
    - 性能要件
        - 処理時間（特定の処理が何秒以内に終わるか）
        - スループット（単位時間当たりにどれだけの処理をシステムがこなせるか）
        - これらの単位は１秒あたりの仕事量を示すTPSで扱う
        - 二つの要件を、要件定義の段階で決めておく必要がある
    - リソース使用量の基礎知識
        - 類似の稼働中システムのデータを流用する
        - プロトタイプからおおむね算出する
- ストレージの冗長構成
    - データは可能な限り高い障害性を持たなければならない
    - ここでRAID(はRedundant Array of Independent Disks)という技術が役に立つ
    - 複数のディスクを併用して一つの仮想化したディスクとすることで冗長化する
    - このまとめられたディスクのグループをRAIDグループという
    - またRAIDを用いることで性能向上を期待することができる
    - 複数のディスクにデータを分散することできるため、ボトルネックとなるディスクI/Oを分散することができる
    - RAIDレベルについて
        - RAID0（別名：ストライピング）はデータを分散させて保存する。冗長性がない
        - RAID1（別名：ミラーリング）は同じデータを持つ。性能は上がらない
        - RAID5。データとともに「パリティ」と呼ばれる誤り符号訂正符号を分散して格納する（ちなみにデータベースは書き込み機能よりも読み出し機能が重要視される）
        - RAID10。RAID0とRAID1の良い所取り。組み合わせたもの
    - どのRAIDレベルを扱うべきか？
        - 要件、予算にもよるが選べるならRAID10が望ましい。財布に余裕がないと厳しい
        - なので、データベースのRAIDは少なくともRAID5で構成する。予算があればRAID10。RAID0は論外
    - ファイルの物理配置
        - 開発者が意識すべきなのはデータファイルとインデックスファイル
        - データファイルとはユーザーがデータベースに格納するデータを保持するためのファイル
        - インデックスファイルとはテーブルに作成されたインデックスが格納されるファイル
        - リレーショナルデータベースでは普段テーブルとインデックスが異なるファイルとして管理される
        - リレーショナルデータベースでは、データベースに逐一データの変更を反映するのではなく、一旦ログファイルに変更内容を加えた後、一気にデータベースに変更を加えている。データの反映が終われば不要になるため、ログファイルのデータが増加することはない
        - それぞれのファイルの物理配置を考えた時、最も考えるべきことはサイズと性能である
# バックアップ設計
- バックアップ方式は主に３つある
    - フルバックアップ（完全バックアップ）
ある時点でシステムに保持しているデータを全て保存すること。欠点は、バックアップの時間が長い、ハードウェアリソースへの負荷が高い、サービス停止が必要である
    - 差分バックアップ
データベースへの変更履歴が記されているログファイルを用いて差分でバックアップを取ることができる。利点はログファイル分の更新だけで良いので、バックアップの容量が減る。欠点はリカバリのための手順が複雑になりがちであること。
    - 増分バックアップ
差分バックアップの冗長性を一切排除したもの。利点としては一番バックアップのデータ量が少なくて済む。欠点はリカバリ手順が一番複雑になる。
- バックアップとリカバリはトレーどオフの関係にあり、どのような方式を取れば良いのか？（バックアップ設計の肝）
    - バックアップしない
    - フルバックアップのみ
    - フルバックアップ＋差分バックアップ
    - フルバックアップ＋増分バックアップ
    - 現実的なのはコストから考えて３つ目と４つ目
    - バックアップ設計する上で大切な考え
        - そもそもバックアップは必要なのか？
        - バックアップに使用できる時間
        - リカバリに使用できる時間
        - 何世代までデータを残す必要があるか？
# バックアップの手順
- バックアップ設計が決まればおのずとリカバリ設計も決まる
- バックアップの手順はデータベースにバックアップファイルを戻すリストア
- データベースサーバーに残っているトランザクションログを適用するロールフォワードを最後に行う