1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【学習まとめ】達人に学ぶDB設計徹底指南書(第2版)

1
Posted at

はじめに

book_image.jpg
📘達人に学ぶDB設計徹底指南書(第2版)

上記を読破したので、自分用の備忘もかねて本記事を執筆することとしました。
本書を購入しようか迷っている方、要点だけざっくりと知りたい方、同書を既に読んだことがあり復習したい方などにとって役に立てますと幸いです。

以下、注意点をいくつか記載します。

・個人的にわざわざ書き起こす必要はないと判断した内容、あまり重要ではないと思った内容については省略しています。
・基本的には要点まとめとしていますが、著書の表現を自分がわかりやすいように言い換えている箇所があります。論理的に逸脱しないよう注意して記載しているつもりですが、あらかじめご了承ください。
・実際の著書は説明が丁寧で非常にわかりやすいです。本記事ではあくまで必要最低限の内容に絞って記載しており、具体例等はややイメージしにくいかもしれません。
・「補足」と記載されているものについて、これは著書に記載されている内容ではなく、読んでいて個人的に補足しておきたい点を記載しています。

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

DBMSの違いは設計に影響しない

DBMSはあくまでモデルを具体的に表現したものに過ぎず、設計の方法論はDBMSに拠らず実装可能である。
ただし、各DBMSが独自機能を発展させてきた背景から、設計が少し影響を受けることはある。

DOAとPOA

DOA(Data Oriented Approach)

データ(データベース)の設計をしてから、プログラム(プロセス)を設計する設計思想のこと。

(補足)
例)コンビニのPOS(レジ)の設計
業務プロセス(商品スキャン⇒合計金額算出⇒支払い受付⇒レシート発行&売上記録)を定義し、各処理で必要なデータ(商品情報、税率、支払い日付など)を後から定義する。

POA(Process Oriented Approach)

プログラム(プロセス)の設計をしてから、データ(データベース)を設計する設計思想のこと。

(補足)
例)コンビニのPOS(レジ)の設計
必要なデータ(商品情報、税率、支払い日付など)を先に定義し、それを基に業務プロセスを定義する。

DOAはPOAの欠点を克服すべく登場した。
DOAが優れている理由は以下の通りである。

  • データがあまり変化しない(永続性)ため、データの意味や形式が先に決まっていれば、複数のプログラムで共用することも容易である。
  • 業務要件の仕様変更にも柔軟に対応できる。

現在はDOAが主流となっており、だからこそデータ(データベース)設計がシステムの品質を決める最も重要な外因と言っても過言ではない。

3層スキーマモデル

システム(ここではデータベース)を三つのスキーマに基づいて記述したモデルのこと。

外部スキーマ

ユーザーから見てデータベースがどのような機能/インターフェースを持つかを定義するスキーマのこと。
端的に「ユーザーから見たデータベース」であり、ビューなどが該当する。
データベースだけではなく、画面のUIや入力データ等も該当する。

概念スキーマ

データベースに保持するデータの要素およびデータ同士の関係を記述するスキーマのこと。
端的に「開発者から見たデータベース」であり、テーブル定義などが該当する。
概念スキーマの設計を「論理設計」と言い、データベース設計において重要な位置づけとなる。

内部スキーマ

概念スキーマで定義された論理データモデルを具体的にどのようにDBMS内に格納するかを定義するスキーマのこと。
端的に「DBMSから見たデータベース」であり、データの物理的定義(テーブルやインデックス等)が該当する。
内部スキーマの設計を「物理設計」と言い、論理設計と対になる。

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

データベース設計の手順

システム開発におけるデータベース設計は、以下の手順で実施される。

1.概念スキーマ(論理設計)
 ⅰ.エンティティの抽出
 ⅱ.エンティティの定義
 ⅲ.正規化
 ⅳ.ER図の作成
 
2.内部スキーマ(物理設計)
 ⅰ.テーブル定義
 ⅱ.インデックス定義
 ⅲ.ハードウェアのサイジング
 ⅳ.ストレージの冗長構成決定
 ⅴ.ファイルの物理配置決定

俯瞰的には、概念スキーマ(論理設計) ⇒ 内部スキーマ(物理設計)の手順で行われる。
論理設計は原則として物理的制約に依存せず、最初にデータベース設計を行う際は、まずは物理層の制約を脇において話を進めることになる。

論理設計の手順

1.概念スキーマ(論理設計)
 ⅰ.エンティティの抽出
 ⅱ.エンティティの定義
 ⅲ.正規化
 ⅳ.ER図の作成

ⅰ.エンティティの抽出

どのようなエンティティが必要になるかを抽出すること。
エンティティ(実体)とは、現実世界に存在するデータの集合体を指す言葉である。
それには物理的実体の有無は問わない。

▽例(物理的実体あり)
顧客、社員、店、車など

▽例(物理的実体なし)
税、会社、注文履歴など

これは「どういうデータを扱いたいか」という問いの変形でもある。

ⅱ.エンティティの定義

各エンティティがどのような属性(列)を保持するかを決定すること。
例えば「顧客」というエンティティに対して「名前」「住所」「電話番号」「メールアドレス」といった属性(列)を定義する作業である。
特に「キー」という属性(列)の定義が重要である。(詳細は第3章にて説明する)

ⅲ.正規化

エンティティ(テーブル)についてシステムの利用がスムーズに行えるように整理する作業のこと。
データベースの設計において最も重要な土台をなす。
詳しくは第3章にて説明する。

ⅳ.ER図の作成

正規化によって細分化された大量のエンティティ同士の関係性を表現する図を作成すること。
ER図とは、Entity-Relationship図の省略形である。
詳しくは第4章にて説明する。

物理設計の手順

2.内部スキーマ(物理設計)
 ⅰ.テーブル定義
 ⅱ.インデックス定義
 ⅲ.ハードウェアのサイジング
 ⅳ.ストレージの冗長構成決定
 ⅴ.ファイルの物理配置決定

ⅰ.テーブル定義

概念スキーマを基に「テーブル」単位に変換する作業のこと。
(補足:各カラムのデータ型の定義等もここで実施される。)

ⅱ.インデックス定義

パフォーマンス向上に寄与するインデックスを定義する。
詳細は第6章にて説明する。

ⅲ.ハードウェアのサイジング

「サイジング」は大きさを決めることであり、「キャパシティ」と「パフォーマンス」の二つの観点から実施する。

キャパシティのサイジング

システムで利用するデータサイズの見積もりに対して十分な容量のストレージを選定すること。

キャパシティは物理テーブル定義とインデックス定義が完了した時点で算出できる。
データ量は、テーブルに加えて、テキストや画像やHTMLといった様々な形式のファイル分も加算する必要がある。

また、システム運用開始後のデータ量の増加も見越してスケーラビリティを確保することが望ましく、以下の具体策が考えられる。

  • 余裕を持たせたサイジングを行う
  • オンプレで後から記憶装置を追加できるような構成にする
  • クラウド利用によりストレージ容量を漸増していく
パフォーマンスのサイジング

システムが本領発揮できるためのCPUやメモリを選定すること。また、性能問題のほとんど(約8割)はストレージI/Oのネックによって引き起こされるため、ストレージ選定も含まれる。

性能要件は「応答時間(どれだけ速いか)」と「スループット(どれだけ多いか)」から定義される。

ただ、パフォーマンスのサイジングを見積もることは難しく、根拠となる基礎数値が必要となる。
この基礎数値を得る方法は2つある。メリット/デメリット併せて下記に示す。

サイジング方法 メリット デメリット
類似の稼働中システムのデータを利用 費用抑制 適当な類似システムが見つからないと精度低下
開発初期でプロトタイプによる性能検証(PoC実施の場合もあり) 正しく実施すれば高精度 予算とスケジュールの制約あり

ⅳ.ストレージの冗長構成決定

高い耐障害性を持つシステムを構築するために「RAID(Redundant Array of Independent Disks)」という技術を利用する。

RAID0(ストライピング)

データを複数のディスクに分割して保存する。冗長性はない。

RAID1(ミラーリング)

複数のディスクに全く同じデータを持つ。

RAID10

RAID0とRAID1を組みあわせた技術のこと。
RAID1(ミラーリング)のグループを使ってRAID0(ストライピング)の構成を取る。

RAID5(パリティ分散)

「パリティ」と呼ばれる誤り訂正符号を最低3本のディスクに分散して格納すること。
ディスク1本の破損なら復元可能であり、データ分散によりI/O性能の向上も期待できる。

採用すべきRAIDパターンはどれか

優先度としては以下の通りである。(※)

RAID10(or RAID6) > (予算の壁) > RAID5

RAID0は論外である。(1本でも故障したら復旧不可のため)
RAID1はパフォーマンスの向上が見込めないのが難点である。

(※)これはあくまでオンプレの場合の話。後述するがクラウドではRAID5/6は推奨されていない。

ⅴ.ファイルの物理配置決定

ファイルI/O量の大きさは以下の通り。

データファイル(テーブルデータ) > インデックスファイル(インデックスデータ) = 一時ファイル (一時データ) > ログファイル > システムファイル(DBMS管理用データ)

各ファイルを分散したディスク(RAIDグループ)に保持するのが望ましい。
妥協案としては、I/Oコストの低いファイルを独立したディスク(RAIDグループ)にまとめるパターンである。

レプリケーション

レプリケーションとは、マスター/レプリカ系で複数のデータベースを用意し、データが同じになるようにする技術のこと。
可用性の向上を図ったり、リードレプリカ(=レプリカ系でアプリケーションの読み込み処理のみを受け付けること)を増やすことで読み込みスループットを向上させたりする。

クラウドにおける冗長構成

AWSではRAID5/6を推奨していない。
AWSのEBS(Elastic Block Store/ブロックストレージ)ではデフォルトで同一AZ内にレプリカが作成され、障害検出時はF/Oによって業務継続が可能となるため。

また、マルチリージョンやクロスリージョンレプリケーションといった冗長化構成の組み方も可能である。
ただし、当然コストは嵩張るので、RTO/RPOの業務要件と予算制約を考慮する必要がある。

バックアップ設計

バックアップ方式には以下の3種類が存在する。

  • フルバックアップ
  • 差分バックアップ
  • 増分バックアップ

一般的には、

  • フルバックアップ + 差分バックアップ
  • フルバックアップ + 増分バックアップ
    が選択されることが多い。(著者の経験では約9割程度)

リカバリ設計

「障害発生時に、バックアップファイルから完全に元の状態に復旧するまで」の作業は「リストア」「リカバリ」「ロールフォワード」に分けられる。

リストア

バックアップファイルを戻す作業のこと。

リカバリ

バックアップしていたトランザクションログを適用して変更分を反映する作業こと。

ロールフォワード

データベースサーバーに残っているトランザクションログを適用すること。

第3章 論理設計と正規化 ~なぜテーブルは分割する必要があるのか?

キー

キーとは、特定のレコードを特定するための列の組み合わせのこと。

外部キーの参照制約整合性について

外部キーの役割はフィールド値の制約を課すことである。

【例】
テーブルが以下の2つあり、外部参照の関係がある。

  • 「社員」テーブル(「部署」カラムを持つ)
  • 「部署」テーブル
    「社員」テーブルの「部署」カラム ⇒ 「部署」テーブル(外部参照)
    「部署」テーブルに存在しているフィールドが「開発/人事/営業/総務」の場合、
    「社員テーブル」に「部署カラム」が「広報」のフィールドを持つ社員を追加することはできない。
    「部署」テーブルに「研究」フィールドを追加することは可能である。

キーに設定すべき値について

下記のルールを徹底する。

  • コードやIDといった表記体系の定まったデータであること。
  • 固定長文字列のデータ型に格納して使用すること。

これらのルールが順守されていないと、参照時に不整合が生じてしまう。

制約

テーブル定義上、以下の3つの制約をかけることができる。
①NOT NULL制約
②一意制約
③CHECK制約(あるカラムの取りうる範囲を制限する)

正規化

データベースで保持するデータの冗長性を排除し、一貫性と効率性を保持するためのデータ形式のこと。

第1正規系

一つのセルに一つのフィールドが格納されていること。(このフィールドを【スカラー値】とも呼称する。)
これにより主キーが各列の値を一意に決定できるようになる。

第2正規系

部分関数従属を解消し、完全関数従属のみのテーブルを構築すること。
部分関数従属とは、複合主キーの一部の列に対して従属する列があること。

例)
[会社コード,社員ID]を主キーとするテーブルにおいて、[会社名] ⇒ [会社コード]と従属する関係がある場合、それは部分関数従属である。)

第3正規系

推移的関数従属を分割すること。
推移的関数従属とは、主キーから定まる特定のフィールドAが更に他のフィールドBの主キーとなる場合([主キー] ⇒ [フィールドA] ⇒ [フィールドB])、この第2段階と第3段階の関数従属性を分割すること。

正規化について

  • 正規化によって分割したテーブルはいつでも結合で元に戻すことができる。
  • 原則として第3正規系までは正規化を実施する必要がある。

第4章 ER図 ~複数のテーブルの関係を表現する

概要

ER図とは

テーブル同士の関係性を明示するために作成する図のこと。
Entity-Relationship図の略称系である。

テーブル間の関連パターン

テーブル間の関連パターンは「1対1」「1対多」「多対多」の3パターンの関連がある。

1対1

2つのテーブルの主キーが一致するケースであり、あまり見かけない。
(テーブルの主キーが一致するのであればまとめてしまって問題ないから。)

1対多

最もよくある関連タイプ。
例えば「会社テーブル」と「社員テーブル」のようなケースを考えると、「会社:1」に対して「社員:多」という関係がある。
これは普通の日本語で言えば「一つの会社では複数の社員が働いている。」ということを指す。

「多」のケースは「0以上」と「1以上」の場合があるが、その差異をER図では表記可能である。

多対多

少し特殊なカテゴリ。
例えば「学生」テーブルと「講義テーブル」の履修登録を管理するようなシステムを想定する場合、学生:多に対して講義:多となる。

このようなケースでは、関連実体を設ける。
関連実体とは、「多対多のエンティティ間に作られる第3のエンティティ」である。

上記の例では「受講」テーブルを追加し、カラム(主キー)に「学生コード」と「講義コード」の2つを保持するようにする。
これにより「学生1に対して受講多」「講義1に対して受講多」の関係を保持することができる。

ER図のフォーマット

代表的なER図のフォーマットには、「IE(Information Engineering)記法(鳥の足)」と「IDEFIX」がある。
(以下、LibreOfficeで作成した稚拙な図が連続しますが、ご容赦ください。)

IE(Information Engineering)記法(鳥の足)

IE図の例

IE_normal.jpg

IE図の例の説明

IE_explanation.jpg

IDEF1X

IDEF1Xの例

IDEF1X_normal.jpg

IDEF1Xの例の説明

IDEF1X_explanation.jpg

第5章 論理設計とパフォーマンス ~正規化の欠点と非正規化

正規化の功罪

正規化には功罪がある。

✅メリット
データの整合性を保持できる。

❌デメリット
SQLは非常に遅くなり、パフォーマンス劣化を招いてしまう。(結合を利用するため)

正規化と検索パフォーマンスの間にはトレードオフの関係がある。

著者のミック氏としては、「原則として非正規化は許容されない。」という立場をとっている。
非正規化はあくまで最終手段であり、様々なトレードオフを考慮しながら慎重に実施する必要のある難しい仕事である。それがエンジニアの本務である。

非正規化とパフォーマンス

冗長性排除によって引き起こされる性能問題には、大きく分けて以下の2パターンに分けられる。

  • サマリデータの冗長性排除
  • 選択条件の冗長性排除

以下の例では、例えばお歳暮などの注文受付を管理するテーブルを考慮する。

サマリデータの冗長性排除

「受注日ごとの注文数」などの検索条件が必要になった場合、テーブル間の結合によって取得できる。
パフォーマンス向上のために、例えば商品数などのサマリデータのカラムを追加することで、正規化には違反するものの検索時のパフォーマンスは大きく向上する。

選択条件の冗長性排除

「特定の受注日の商品一覧」などの検索条件が必要になった場合に、同じようにテーブル間の結合によって取得できる。
パフォーマンス向上のために、例えば「受注日」などの選択条件のカラムを追加することで、正規化には違反するものの検索時のパフォーマンスは大きく向上する。

非正規化のリスク

非正規化には以下のようなリスクが伴う。

  • 更新SQLのパフォーマンス低下
  • データのリアルタイム性(鮮度)の低下
  • 設計変更による手戻り

更新SQLのパフォーマンス低下

例えば「受注」テーブルに「商品数」といったサマリデータのカラムを追加した場合
「受注」テーブルにレコードを追加する場合に商品数を計算する必要がある
注文変更時に「受注」テーブルの「商品数」カラムのフィールドを変更する必要があり、更新処理の負荷を考慮しなければならない。

データのリアルタイム性(鮮度)の低下

(上記と同じ例を考慮して)「商品数」が受注受付後に変更されるのであれば、そのタイミングを考慮する必要がある。
反映周期が短ければシステムへの負荷は高くなるが、ユーザーにとっては好ましい。
両者のバランスが取れる平衡点を見つけ出す必要がある。

設計変更による手戻り

DOAの原則に従い、データモデルの変更は大きな改修コストを発生することを意味する。
論理設計は正規化の理論を理解しているだけではなく、それによって生じる様々なトレードオフを知り尽くしたうえで、あらゆる要件を見つけ出す平衡点を探し出す能力が必要とされる。

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

パフォーマンスを決める要因

データベースのパフォーマンスを決める主な要因は以下の通り。

  • インデックスと統計情報
  • ディスクI/Oの分散
  • SQLにおける結合(正規化)

インデックスと統計情報

インデックスは「DBMS内にテーブルとは独立に保持されるオブジェクト」である。

統計情報(メタデータ)は、SQLがどのような経路でデータを探しに行くのが最も効率的かを決定する最大の要因である。
最近のDBMSではコストベース(DBMSに最短経路を一任するアーキテクチャ)が主流になっている。

インデックス設計

インデックスがパフォーマンス改善でポピュラーな理由

インデックスは以下の観点でパフォーマンス改善の非常にポピュラーな手段である。

アプリケーション透過的

インデックスには透過性(存在を意識しなくてよいこと)があり、インデックスを使用するか否かはDBMSが自動的に判断する。

データ透過的

インデックスを作成することでテーブルに格納されているデータの中身が影響を受けることがない。

大きな性能改善効果

インデックスの性能改善効果はしばしば劇的である。
ただし、やみくもにインデックスを作成する行為は「インデックスショットガン」と呼ばれ、アンチパターンの一つに該当する。

B-treeインデックス

B-treeインデックスは、最も頻繁に利用するインデックスである。
長所として、平均点の高さが挙げられる。他のインデックスが一長一短であるのに比べて汎用性が高い。

以下、様々な観点でB-treeインデックスの特徴を記載する。

均一性

どのような値を指定しても同じくらいの速度で結果を得られる。
これは平衡木(どのルーフもルートからの距離が一定の木のこと)であり、常にリーフまでの距離が一定のため探索を同じ量で行えるから。

ただし、テーブルのレコード追加/変更/削除によって非平衡木になっていくことがある。

持続性

計算量がO(logn)であり、データ量の増加に伴う処理時間の増加が緩やかなカーブを描く。
木の高さが低いため持続性がある。

処理汎用性

レコードの追加/変更/削除いずれの操作でも計算量はO(logn)である。

非等値性

等号のみならず、不等号やBETWEEN句といった範囲検索に対しても高速化を可能とする。
ただし、否定条件はB-treeインデックスは効果を発揮しない。

親ソート性

B-treeインデックスは構築時にキー値をソートして保持する。
ソート処理では、メモリに載りきらないあふれ分をストレージに書き出し、非常に大きなI/Oコストを発生させることがあるが、B-treeインデックスではソート処理自体をスキップすることができる。

B-treeインデックスを適用すべき列

データ量が大きい

データ量が少ない場合、フルスキャンと性能差はあまり生じない。
目安として、レコード数が100,000件以下の場合はあまり効果がない。(ただしストレージやサーバの性能など環境要因に依存する)

カーディナリティが高い

カーディナリティ(特定の列がどのくらいの種類の列を持つか)が高く、なおかつフィールドが平均的に分散していること。

インデックス列に演算等が行われていない

インデックス列に対して以下の条件に合致する場合はインデックスが機能しないため注意する必要がある。

  • 演算が行われている
  • SQL関数が適用されている
  • IS NULL述語が適用されている
  • 否定形が使用されている
  • 前方一致('hoge%'など)以外のワイルドカードLIKE述語が使用されている
  • 暗黙の型変換を行っている

B-treeインデックスに関するその他の注意点

主キー&一意制約の列には作成不要

主キーや一意制約を作成する場合は内部的にインデックスが作成されているため、インデックスの指定は不要である。

更新性能は劣化する

インデックス作成対象のカラムのフィールドが変更されると、それにともなってインデックス(オブジェクト)に対する更新も発生する。
これはインデックス・ショットがアンチパターンと見なされる所以でもある。

定期的なメンテナンスが望ましい

テーブルの更新に伴ってインデックスの構造が崩れてしまうため、運用において定期的なメンテナンスを行う必要がある。
更新頻度は、DBMSごとにインデックス構造がどれくらい崩れているかを示す指標値があるため、それを調べてみることを推奨する。

統計情報

統計情報はテーブルやインデックスに対するメタデータである。
DBMSはこのメタデータを頼りにSQLのアクセスパスを決定する。

SQL文によってテーブルにアクセスする流れ

SQL文を実行した場合、下記の流れでテーブルにアクセスすることになる。

SQL文の発行
 ⇓
パーサ(文法チェック)
 ⇓
オプティマイザ(最適化ブレーン/ここでは統計情報がないためにカタログマネージャに問い合わせ)
 ⇓
カタログマネージャ(統計情報の管理)
 ⇓
オプティマイザ(最適化ブレーン/取得した統計情報から最適な経路を選択)
 ⇓
テーブル

統計情報の設計指針

統計情報それ自体はDBMSによって自動的に取得されるため、あくまで間接的な関与となる。
統計情報をどのように実施するかは以下の2点を考える。

(補足)
統計情報の取得は、主に明示的に実行したときや、DBMS依存でテーブルに大きな更新が発生したときに実施される。

統計情報の収集タイミング

データが更新された後になるべく早く、ただし原則として夜間帯に実施する。
また、統計情報の取得はDBMSによって定期的に実行されている可能性もあるため、マニュアル等で確認しておくことが望ましい。

統計情報収集の対象

基本的に大きな更新があったテーブルを対象とする。

統計情報の凍結について

現状の統計情報を変更させたくない場合であれば、統計情報の凍結を行うことが望ましい。
具体的にはサービス終了時のデータを想定した状態での統計情報が存在する場合など。

オプティマイザは必ずしも最適な経路を選択するわけではなく、データ量の増加に伴って実行計画が変更し、パフォーマンスが劣化することが珍しくないため、このような凍結が実施される。

インデックス以外のチューニング方法

パーティション

テーブルの特定列をキーとしてデータの物理配置をキーごとにまとめる機能のこと。
パーティションキーをWHERE条件に指定して検索クエリの物理的読み込み量を減らす。

1つのテーブルに対して1つのパーティションキーしか指定できない。

ヒント句

強制的に実行計画を変更する機能のこと。
実装が難しい一方で、アプリケーションに変更を入れずにパフォーマンス改善可能となる。

パラレルクエリ

通常シングルコアで実行されるクエリの処理を分割してマルチコアで実行すること。
あくまでサーバやストレージ帯域のリソースが潤沢に余っている状態で力を発揮する。

オンメモリ

テーブルやインデックスのデータをメモリに乗せるチューニングのこと。
メモリが潤沢に余っていて全体的な性能の底上げを図りたい場合に有効である。

第7章 論理設計とアンチパターン

アンチパターンとは

真似してはいけない設計パターンのこと。
実際の開発現場ではアンチパターンに該当する論理設計が溢れている。

非スカラ値(第1正規系未満)

第1正規系を満たしていない設計のこと。

(補足)
1フィールドに複数の値が格納された状態のこと。

配列型によって非スカラ値を含むテーブルを作ることができるようになった。
しかし、安易に配列型を使用するべきではなく、第1正規系の確保を優先すべきである。

ダブルミーニング

1つの列が複数の意味を持つテーブル設計のこと。
列の意味が不明確になることでシステムのバグを生み出す原因になる。

単一参照テーブル

あらゆるタイプのマスタテーブルを一つのテーブルにまとめたテーブル設計のこと。
例えば、会社コード:会社名、部署コード:部署名等のマスタテーブルは同様の構造であり、これを一つにまとめてしまうことである。

✅メリット
マスタテーブルが減ってER図やスキーマがシンプルになったり、コード検索のSQLを共通化できるため保守/管理が容易になる。

❌デメリット
コード値の列の可変長文字列をかなり長く宣言する必要があったり、バグに気が付きにくくなったり、データテーブルのコード列とデータ型が異なるため外部キーによる外部参照整合性制約を付与することができない。

テーブル分割

水平分割

レコード単位にテーブルを分割すること。
そもそも正規化の理論から分割する意味がない、拡張性に乏しい(テーブルが段々と増加する)等の問題がある。
ストレージI/Oのボトルネックを解消するためであれば、パーティション機能を利用すべき。

垂直分割

カラム単位にテーブルを分割すること。
水平分割と同様に正規化の理論から分割する意味がないため採用すべきではない。

集約 - テーブル分割の代替案に位置づけられる方法

列の絞り込み(マート)

テーブルから、主キー+頻繁に参照する列のみを絞り込んだ新たなテーブル(マート)を作成すること。

メリット
✅オリジナルテーブルに手を加えずにパフォーマンス向上を図れる。

❌デメリット
データ同期の問題が発生する。

サマリテーブル

事前にテーブルに対して集約を行ったテーブルを作成しておくこと。
メリット/デメリットともにマートの作成と同じ。

キーに使用すべきではないデータ型

キー(※)のデータ型に可変長文字列を使ってはいけない。
※主キー、外部キー、テーブルの結合で使用される結合キーなど

理由は以下の2つある。

  1. キーが満たすべき条件である不変性を備えていないから。
  2. 固定長文字列と混同するから。

(補足)
固定長文字列は空白の穴埋め(パティング)をするため、可変長文字列とは物理的に異なる値になることがほとんど。

ダブルマスタ

同じ役割を果たすマスタテーブルが複数存在すること。(顧客マスタA、顧客マスタBなど)
別々のシステムで利用されていたマスタ同士がシステムの結合によって同じドメインに存在するようになった場合に生じる。

ゾンビマート

BI/DWHの運用現場で見られる、数年間使用されていないのに削除も躊躇われるマートのこと。
パフォーマンス改善に効果が発揮すると判明するとアドホック的に作られ始める。

多段マート

BI/DWHの運用現場で見られる、マートから更にカスケードされたマートのこと。
データソースを追いにくい、いつ時点のデータ断面なのかもわかりにくくなるなどのデメリットがある。

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

グレーノウハウとは

アンチパターンとは断定できないが、無神経に使うと開発や運用に支障をきたす設計のこと。

代理キー

主キーが決められない、または主キーが不十分なケースがある。
例えば、以下のようなケースが想定される。

  1. 主キーにできる一意なキーが存在しない。
  2. 一意キーはあるがサイクリックに使いまわされる。(値が枯渇したので一番最初に戻る、など)
  3. 一意キーはあるが途中で指す対象が変わる。(市町村の合併で市町村コードの指す対象が変わるなど)

このようなケースで代理キーが問題解決に利用される。
新たなカラムとして人工的なキーをシステム側に付与すること。

ただし、原則としては代理キー含む論理的に不要なキーは使用を避けるべきである。

自然キー

先述のケース2,3に該当する場合、自然キーによる解決が可能である。
以下に自然キーによる解決方法を記載する。

タイムスタンプ

(省略)

インターバル

新たに「開始年度」「終了年度」の列を追加して、データが有効な期間を管理すること。
現在も有効なレコードに対しては、「終了年度」に9999年を設定したり、NULLを設定したりする。

アドホックな集計キー

例えば都道府県を管理するテーブルに地方を指すカラムがなく、「地方コード」をアドホック的に追加する場合を想定する。
コード体系が短いスパンで変わる、別のコード体系が必要になる等の問題あり。

この問題点を解決する手段は下記の通り。

  • 都道府県の主キーと地方コードを別のテーブルに分離すること。
  • ビューを使用して地方コードを追加すること。
  • SQL文のCASE分を工夫してアドホックキーを疑似的に作成すること。

多段ビュー

ビューに対して更にビューを作成すること。
パフォーマンスの悪化に加えてテーブルとビューの依存関係をわかりにくくするめ仕様が複雑になり管理が困難となる。

データクレンジングの重要性

データクレンジングとは業務で利用されたデータをデータベースに登録できるように洗浄すること。
論理設計に先立って実施される必要がある。

代表的なデータクレンジング

一意キーの特定

例えばホテル等の宿泊管理データを想定する場合、宿泊客は名前や宿泊日からは一意に定めることができないため、宿泊客コードが必要となる。
そもそも宿泊客コードを付与するために必要なのが後続の「名寄せ」である。

名寄せ

似通った名前を寄せ集めて統合すること。
人名や企業名の表記揺れを統一して解消する。

名寄せには一般的に以下の二つの方法がある。

  • 別の情報と組み合わせて確度を高める。
  • 情報の出現頻度から判断する。(例えば会社名などはユニークなものが多いため判定できやすい。)

第9章 一歩進んだ論理設計 ~RDBで木構造を扱う

(省略)

おわりに

実務でDBデータのマイグレーションやらJDBC経由でMySQLのレコード書き変えるアプリ開発やらの経験があり、今後を見据えてDB設計もできるようになりたい!という私にとって非常に学びの多い一冊でした。

著者のミックさんの説明がわかりやすく、文章も平易なので非常に読みやすかったです。あまり知識がない方でも、最低限の基礎の基礎を知っていれば、すんなりと最後まで読み切れる内容なのではないかと思います。

また、読んでいて飽きるといったことがあまりなく、実家に帰省した時の飛行機でずっと読んで時間を潰せるくらいには興味深かったです。

ただ、実際に現場でDB設計してみろと言われても、ここで学習した内容をフル活用してスラスラと進められるかは怪しいです。
コーディングにしろ何かアプリ開発してみろと言われますし、どこかで実践編として手を動かしてDB設計をやってみてもいいかもしれません。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?