はじめてのデータベース設計 〜テーブル設計の基本をやさしく解説〜
はじめに
こんにちは!今回は、データベースのテーブル設計をこれから始める方向けに、基本の考え方や手順をまとめました。
私自身もプライベートでアプリを作ってみたとき、「どんなテーブルが必要?」「どうやってデータを整理するの?」と悩みながら、手探りで設計をしていきました。
ですが調べてみるとDBの設計にはちゃんとした考え方の型(ルール) があって、それを知るだけでグッと整理しやすくなりました。
アプリ開発においてDBは欠かせない存在
アプリを作るときには、ほとんど必ず「データを保存する場所」が必要になります。
- ユーザー情報を保存する
- 商品一覧を表示する
- イベントの予約状況を管理する など…
その保存場所こそが「データベース(DB)」です。
最初にやること
アプリを作るときにいきなりテーブルを作るのではなく、まずは 「どんなデータを扱いたいか」 をしっかり整理するところから始めます。
データを抽出する
たとえば、イベント予約アプリを作る場合なら、
- ユーザー情報(誰が使うのか)
- イベント情報(いつどこで何をするのか)
- 予約情報(誰がどのイベントに予約したのか)
といったデータが必要になります.
ここで意識するポイントは:
- アプリ上にどんな情報を表示したいか
- ユーザーがどんな操作(登録・検索など) をするのか
実際に紙に書いたり、メモ帳にリストアップしてみるのもおすすめです。
エンティティ(実体)を定義する
「エンティティ」とは、テーブルになる“もの” のことです。
たとえば、上の例なら以下のように分けられます。
エンティティ(テーブル) | 管理する内容 |
---|---|
users(ユーザー) | 名前、メールアドレスなど |
events(イベント) | イベント名、日時、会場など |
reservations(予約) | 誰がどのイベントに予約したか情報 |
ポイントは、1エンティティ = 1種類の情報にすること
「イベント情報と予約情報が混ざってる」「ユーザー情報に予約がくっついてる」…など、
ごちゃっとしていると後々大変になります。
主キー(Primary Key)とは?
テーブル設計で絶対に外せないのが「主キー(PK)」の存在です。
データベースのテーブルには、同じような情報がたくさん並んでいます。
でもその中から「この1件!」ってピンポイントで探し出したいとき、どこを手がかりにするかを決めるのが主キー(PK) です。
たとえば、こんなテーブルの場合
id | 名前 | 学部 |
---|---|---|
1 | 小野 | 農学部 |
2 | 内田 | 工学部 |
3 | 小野 | 工学部 |
このとき、「名前が『小野』の人のデータをください」と言っても、2人いるので特定できません。
でも「id = 1の人ください」ならちゃんと特定できます。
主キーのルール
項目 | 内容 |
---|---|
一意である | 主キーの値が重複してはいけません(すべての行でユニークであること) |
NULL禁止 | 主キーの値がNULL(空っぽ)になってはいけません |
1テーブルに1つだけ | テーブルには必ず1つだけ主キーを設定します(複数カラムで構成もOK) |
正規化
正規化とは、データの重複や矛盾をなくして、整理された形に整えること。
正規化の目的
- 同じ情報を何度も書かなくてよくなる(重複の削減)
- データの更新や削除がラク(更新ミス・削除漏れが起きにくい)
- 無駄なくキレイな設計になる(長く使えるDBに!)
正規化のステップ(3段階)
正規形 | やること | 目的 |
---|---|---|
第1正規形 | セルに複数の値を入れない | 検索や管理がしやすくなる |
第2正規形 | 部分的に依存するデータを分ける | 主キーの一部に依存する列を分離 |
第3正規形 | 間接的に依存するデータを分ける | 推移的な関係をなくしてスッキリ |
第1正規形(1NF)
- 1つのセルに1つの値だけ入れる
- 情報が混在していると検索・更新が大変になるのでNG!
構成例
ダメな例(1セルに複数値)
ID | 生徒ID | 名前 | 学部名 | 科目名 |
---|---|---|---|---|
1 | 1 | 小野 | 農学部 | 心理学, 栄養学 |
カラムを増やすのもNG
ID | 生徒ID | 名前 | 科目1 | 科目2 |
---|---|---|---|---|
1 | 1 | 小野 | 心理学 | 栄養学 |
よい例(正規化された形)
ID | 生徒ID | 名前 | 学部名 | 科目名 |
---|---|---|---|---|
1 | 1 | 小野 | 農学部 | 心理学 |
2 | 1 | 小野 | 農学部 | 栄養学 |
3 | 2 | 内田 | 工学部 | 栄養学 |
第2正規形(2NF)
- 主キーの一部にしか依存しない列(部分関数従属)を取り除く
- テーブルを分けて、矛盾を防ぐ
構成例
生徒テーブル
生徒ID | 名前 | 学部ID |
---|---|---|
1 | 小野 | 1 |
2 | 内田 | 3 |
履修テーブル
生徒ID | 科目ID |
---|---|
1 | 1 |
1 | 2 |
2 | 2 |
科目テーブル
科目ID | 科目名 |
---|---|
1 | 心理学 |
2 | 栄養学 |
第3正規形(3NF)
-
推移的関数従属を取り除く
- 例:生徒ID → 学部ID → 学部名
- 間接的に依存している列は別テーブルに切り出す
構成例
生徒テーブル
生徒ID | 名前 | 学部ID |
---|---|---|
1 | 小野 | 1 |
2 | 内田 | 2 |
学部テーブル
学部ID | 学部名 |
---|---|
1 | 農学部 |
2 | 薬学部 |
3 | 工学部 |
ER図(Entity-Relationship図)
テーブルとテーブルの関係性を図にしてわかりやすくしたものです。
よくある関係
関係 | 説明 |
---|---|
1対1 | あまり使われない |
1対多 | 基本的な構成(例:学部と生徒) |
多対多 | 中間テーブルを作って表現(例:生徒と科目) |
中間テーブルは、正規化の過程で自然と生まれてきます。
テーブル定義
実際にデータベースに登録する際の物理設計で、カラムやデータ型などを明記します。
テーブル定義の例:students テーブル
カラム名 | データ型 | PK | NOT NULL | デフォルト値 |
---|---|---|---|---|
id | INT | ○ | ○ | |
name | VARCHAR(25) | ○ | ||
faculty_id | INT | ○ |
- INT:整数(IDなどに使う)
- VARCHAR(n):文字列(n文字まで)
- NOT NULL:値が必ず必要なカラムに設定
- デフォルト値:未入力時に入る初期値
テーブル名は 複数形(students, subjectsなど) にするのが一般的です
設計の流れまとめ
論理設計(考える段階)
- 管理したいデータの抽出
- エンティティ(表にするもの)の定義
- 正規化(第1〜第3まで)
- ER図で関係性を可視化
物理設計(形にする段階)
- テーブル定義(カラム・データ型・制約など)
- インデックス設計(必要があれば)
おわりに
データベース設計は「整理整頓」とよく似ています。
見やすく、探しやすく、間違えにくくする工夫が正規化であり、
ER図やテーブル定義はその工夫をカタチにする作業です
是非参考にやってみてください。
Discussion