こんにちは、4年目エンジニアの nakaSay です。
本記事では「データベースのきほん」という書籍の内容をかい摘み、いくつかのパートに分けて記事を投稿しています。
本書籍は入門書であり、記事では以下のような内容を取り上げる予定です。気になった方は是非気軽にお立ち寄りください。
- データベースの全体像
- リレーショナルデータベースとは
- データベースに関わるお金の話
- データベースとアーキテクチャ構成
- DBMS を操作するときの基本知識
- SQL文の基本
- トランザクションと同時実行制御
- テーブル設計の基礎
- バックアップとリカバリ
テーブル設計の基礎
ここでは、RDBにおけるテーブル設計の基礎について説明します。
RDBにおいて、データを管理・保存するための唯一の入れ物は「テーブル」です。
データは様々なものがあるため、何らかの基準を元にテーブルを整理する必要があり、それが「テーブル設計」と呼ばれています。
整理された結果、テーブルは共通の属性を持ったデータの集合となります。
これを表現する言葉に「テーブル名は必ず複数形か集合名詞で表現できる」という格言があり、例えばトマトやレタスなどのデータが格納されていれば「Vegetables」というテーブル名を付けることができます。
そのため、テーブルは「野菜」や「果物」など、現実世界でカテゴライズされている概念や集合を表したものとなります。
なので、現実世界で名前のついていない雑多な集まりはテーブルに存在しません。
基本ルール
テーブル設計のアンチパターン(やってはいけないパターン)として以下のようなものがあります。
- 「何でもボックス」のような何の関連性も無いランダムな集合
- 「トマトテーブル」や「レタステーブル」など個々のモノがテーブル階層となる
- 現実世界の文脈で個々に作りたい場合などは除く
テーブル設計は自由度が高いですが、基本ルールは「最上位の概念集合」にまとめることです。
- 例)「一般会員テーブル」と「プレミア会員テーブル」を作るのではなく、「会員テーブル」にまとめる
データの一意性
テーブルの「列」は個体の「属性」で、会員テーブルであれば「年齢」や「性別」などが個々の特性として考えられます。
各データは識別できる必要があるため、全ての属性が全く同じというデータは存在してはいけません。
そのため、「必ず主キーを設定する」という大原則があります。
主キーとは一意な識別子で、一般的にはIDを使うことが多いです。
可変であったり重複するものは一意であることを保証できないため、「名前」などを主キーに使うことはできません。
つまり、テーブルとは「一意な識別子を持った共通項によってまとめられたモノの集合」と言えます。
正規形
前節では「テーブルとは何か」ということを中心に説明しましたが。次に具体的なテーブル設計のセオリーについて説明します。
テーブル設計において構築された基本的なセオリーに「正規形(Normal Form)」があります。
正規形は第1正規形から第5正規形までありますが、第3正規形まで抑えていれば実務としては十分なレベルです。
第1正規形(1NF)
第1正規形の定義は「1つのセルに複合的な値を含んでいない」というものです。
例えば「扶養者」など、複数の値が紐づく場合は別テーブルに分離してカテゴライズすることが必要です。
もし複合的な値を含んでしまう場合、主キーから値を特定することができなくなり一意性を失ってしまいます。
RDBではこの定義に反するテーブルを作ることは技術的に不可能なため、RDBのテーブルは全て自動的にこれを満たしています。
第2正規形(2NF)
第2正規形の定義は「部分関数従属を含んでいない」というものです。
テーブル内の各レコードは主キーを持っていて、我々はその値を元に紐づくデータを取得することができます。
つまり、テーブルとは「主キー(入力値)から対応したデータ(出力値)を得る」関数と捉えることができ、この主キーと他の列の間に成立する関数的な一意性のことを関数従属性と呼びます。
主キーは複数列の組み合わせで表現されることもあり、その際に「主キーの一部の値から、一部の列の値を特定できる」場合があります。つまり、部分的に関数従属性が発生しているのですが、これは複数の集合が混ざっている状態といえます。
そのため、それらを分離して適切にカテゴライズすることが必要です。
主キーが1つの列だけで決まる場合は自動的に第2正規形を満たしています。
第3正規形(3NF)
第3正規形の定義は「推移関数従属を含んでいない」というものです。
第2正規形では「主キーの一部の値から、一部の列の値を特定できる」場合でしたが、第3正規形では「主キー以外の列から、一部の列の値を特定できる」場合を考えます。
主キーから見ると「主キー → 非主キー → 特定の列」と推移しているため、この状態を推移関数従属と呼びます。
この場合も複数の集合が混ざっている状態と言えるため、テーブルを分離することが必要です。
ER図
正規化を行うと、テーブルが分割されて数が増えていきます。
正規化の目的はあくまで「更新異常」のリスクをなくすことが目的なのですが、結果としてテーブルの数が増えるのも事実です。
複雑な業務システムであれば、テーブルの数は軽く数百に達します。
そうなってくると人間の能力で全てのテーブルの関係性を把握することが難しいため、ER図(Entity-Relationship Diagram)と呼ばれるテーブル間の関連性を一望することができる技術が存在します。
https://www.ntt.com/business/services/rink/knowledge/archive_58.html
まとめ
- テーブルとは集合である
- テーブルとは関数である
- 上の2つを覚えておけばテーブル設計は終わったも同然である
- それでも不安な人は、「第2正規形」と「第3正規形」のルールだけ覚えておくと良い
- 増えたテーブルは「ER図」を描いて整理すると良い
参考