正規化(2) 第1正規形
作成日時:2025-12-11
更新日時:2025-12-11
下記の条件を満たす場合、第1正規形(first normal form, 1NF)となる。
リレーション「R(A1, A2, A3…)」は、その各ドメイン「dom(Ai) (i=1…n)」がシンプルである。
「ドメインがシンプル(アトム)」であるとは、下記のいずれかに言い換えられる。
- ドメインの直積だったりべき集合(部分集合)が存在しない
- 単一値を取る
- それ以上分割できない
- 繰り返し項目が無い
簡単に言えば、カラムに格納されているデータがそれ以上分解できない状態ならば1NF。
下記のテーブルは”好きなバンド”カラムがバンド名を繰り返しているので、1NFを満たしていない。
| 社員ID | 好きなバンド |
|---|---|
| A001 | (メタリカ, メガデス, スレイヤー, アンスラックス) |
1NFにするなら、下記の形になる。
| 社員ID | 好きなバンド |
|---|---|
| A001 | メタリカ |
| A001 | メガデス |
| A001 | スレイヤー |
| A001 | アンスラックス |
シンプルではないドメインが存在する場合は、非第1正規形または入れ子型リレーションという。
コラム:名前やCSV、JSONが格納されていたら1NFを満たさないのでは?
| 名前 | 情報 |
|---|---|
| 山田 太郎 | {“address”: {“prefecture”: “東京”, “zip”: “xxx-xxxx”}, “hobby”: [“ギター”, “イラスト”]} |
名前が姓名で分割可能であるし、情報カラムに含まれるJSONも個々の要素に分割可能である。
1NFの厳密な定義に照らし合わせれば、非第1正規形になる。
しかし、システム/案件的にその形がベストならば、1NFを満たさないがトレードオフとして許容していいと考える。
「ミドルネームも入力できるように、名前全体でカラムに保持する」や、
「どういう属性が入るか分からないから、いったんJSONで格納」など。
個人的にはJSONを使いたくない
JSONデータに対する検索や更新処理のパフォーマンスが気になる。
JSONのような半構造化データは、何が入っているか曖昧で、意図しないバグを生み出しかねない。
JSON型ではなく、TEXTやVARCHARにJSON文字列を格納した場合、不正なJSONが格納されることも考えなければならない。
かと言って無理やりリレーションで実現しようとするとEAVになりそうで、それはそれでアンチパターンとなる。
ケースバイケースで最適な設計を選ぶ。