「達人に学ぶ DB設計指南書」を読みました その3
はじめに
「達人に学ぶ DB設計指南書」は、翔泳社より出版されている書籍です。
https://www.shoeisha.co.jp/book/detail/9784798124704
今回は、こちらの書籍のまとめや感想などをお伝えします。
その2はこちら
https://yajima.sytes.net/posts/20230614
内容まとめ
第4章 ER図 ~複数のテーブルの関係を表現する
テーブル同士が互いにどういう関係にあるのか、ということを明示するために作る図をER図(Entity-Relationship Diagram:実体関連図)という。
関連性には以下の3種類がある。
- 一対一
- 一対多
- 多対多
第5章 論理設計とパフォーマンス ~正規化の欠点と非正規化
正規化は、パフォーマンスを悪化させてしまう可能性がある。
なぜなら、正規化したテーブル群からデータを取得しようとすると、SQLのJOINの数が増えてしまうためだ。
正規化とパフォーマンスはトレードオフの関係性にある。
正規化すればパフォーマンスは落ちていき、代わりにデータの整合性は上がる。
エンジニアによって、正規化すべきかどうかの意見は異なる。
設計時は、概念スキーマだけでなく物理設計についての知識が求められる。
第6章 データベースとパフォーマンス
データベースのパフォーマンス設計という観点において重要なのは、インデックスと統計情報である。
インデックス
インデックスとは、(x, a)という形式の配列データ。
x
はキー。
a
はx
に結びつく情報(実データまたはポインタ)。
インデックスはパフォーマンス改善の最もポピュラーな手段である。
その理由は、以下の3点。
- アプリケーション透過性
- インデックスを作成する場合、アプリケーションの変更は不要(空気のように透明)
- データ透過性
- インデックスを作ったとしてもデータは影響を受けない(設計を修正するような手戻りがない)
- 大きな性能改善効果
- インデックスの効果は絶大である
統計情報
統計情報とは、「SQLがどのような経路(パス)でデータを取得するか」という情報のこと。
B-tree
通常のデータベースは、B-treeというインデックスの形式を採用している。
B-treeが全ての項目で最も優れているというわけではないが、キー検索速度、データ量の増加によるパフォーマンス劣化、等号と不等号、ソート処理など、全項目の平均点が高い。
インデックス設計
インデックスを作成する際の指針として以下が挙げられる。
- 大規模なテーブルに作成する
- データ量が少ない場合は、インデックスを使わない方が高速な場合もある
- カーディナリティの高い列に作成する
- カーディナリティとは「その列が、どれくらいの種類の多さを持つか」を表す概念
- 例えば性別は以下の値をとるとする
- 男性
- 女性
- その他
- この時のカーディナリティは3となる
- SQL分でWHERE句の選択条件、または結合条件に使用されている列に作成する
- インデックスは、SQLの中で使用されないと意味がない
- ただし、以下の場合はインデックスを使用できないので注意する
- インデックス列に演算を行なっている
- NG:
WHERE col_1 * 1.1 > 100;
- OK:
WHERE col_1 > 100/1.1;
- SQL関数も同様に使用できない
- NG:
- IS NULL述語を使っている
WHERE col_1 IS NULL;
- 否定形
WHERE col_1 <> 100;
- OR
WHERE col_1 = 99 OR col_1 = 100;
- LIKE句(前方一致はOK)
- NG:
WHERE col_1 LIKE '%a';
- NG:
WHERE col_1 LIKE '%a%';
- OK:
WHERE col_1 LIKE 'a%';
- NG:
- 暗黙の型変換
- 文字列型のカラムに対して数値を指定すると、インデックスは使用できない
- NG:
WHERE col_1 = 100;
- OK:
WHERE col_1 = '100';
- NG:
- 文字列型のカラムに対して数値を指定すると、インデックスは使用できない
第7章 論理設計のバッドノウハウ
配列型
RDBMSによっては配列型をサポートしているものもあるが、原則使用しないこと。
アプリケーションの配列とはミスマッチなので、値ごとに行を分けること。
ダブルミーニング
同じテーブルなのに、ある行以降は列の意味や役割が変わってしまうようなテーブルはバッドノウハウとなる。
列を、アプリケーションの「変数」のように使用してしまうと上記のような状況に陥る。
列の意味は、一度決めたら変更できない。
単一参照テーブル
(たまたま)構造が同じデータを、一つのテーブルにまとめてしまうこと。
オブジェクト指向言語における「ポリモーフィズム」に似ている。
テーブル分割
例えば、売り上げテーブルを、年度ごとに分けてしまうとバッドノウハウとなる。
- 売り上げ_2001
- 売り上げ_2002
- 売り上げ_2003
パフォーマンス改善の目的で実施されることが多い。
原則、代替手段としてRDBMSの「パーティション」機能を使うこと。
パーティション機能であれば、テーブルを分割することなくパフォーマンスを改善できる。
不適切なキー
主キーや外部キー、結合キー(テーブルの結合条件で使用されるキー)に対して、VARCHAR型を使ってしまうとバッドノウハウとなる。
理由は以下の通り。
- 文字列は変わりやすいから
- 氏名、会社名、部署名などは変わる可能性がある
- 可変長文字列は、固定長文字列とは同じ値にならないから
- 可変長文字列の「テスト」と、固定長文字列の「テスト」は同じではない可能性がある
- なぜなら、固定長文字列は空白による穴埋め(パディング)をするため
ダブルマスタ
同じ意味のデータが2つのテーブルに分かれて格納されていると、バッドノウハウとなる。
システムの統廃合で起きやすい。
バッドノウハウのどこが悪いのか?
バッドである理由①:エンジニアはそんなに頭が良くない
バッドノウハウは、非常に複雑な構造になりやすい。
エンジニアはそのような複雑な構造を理解することが困難なので、開発の過程でバグを生んでしまう可能性が高い。
バッドである理由②:設計変更の難しさ
RDBは、構造を後から変更するのが難しいから。
ERモデルまで手戻りが発生すると、開発コストがどんどん膨れ上がってしまう。
バッドである理由③:データ構造がコードを決めるのであって、その逆ではない
下手くそなデータ構造に対して、エレガントなプログラミングを行うことは不可能。
システム開発において最も重要なのは、コーディングではなくデータ設計である。
感想
本書を読んだ感想を一言で表すと、非常に勉強になりました。
今までなんとなく行なっていたデータベースの設計を、きちんと体系立てて言語化してくれました。
データベースの構造は、一度開発を始めてしまうと後から変更するのが難しいので、最新の注意を払って設計しないとならず、設計者の責任は重大です。
よって、データベース設計を行う場合は本書の内容を思い出しながら取り組もうと思いました。
システム開発に携わる方に向けて、ぜひ一読いただくことをおすすめします!
折に触れて読み返したい一冊でした。