関係データベースにおけるテーブルの設計理論を2回連続で解説する。
テーブルの正規化(1/2)今回:第1正規形、第2正規形、第3正規形(正規形 = Normal Form、1NF、2NF、3NFと表記)を扱う。
テーブルの正規化(2/2)次回:ボイス・コッド正規形、第4正規形、第5正規形(BCNF、4NF、5NFと表記)を扱う。
2017年の解説動画
※ 動画の最後の部分で、デザイナビューのコネクタを利用して外部キー制約の設定ができなかったと話しているが設定可能である。
※ 設定時の条件 1: 外部キーの参照元フィールドが 主キー として設定済み 2: 外部キーと参照元キーのデータ型が一致する
演習の概要
前回の演習で作成したテーブルの構造を修正する
1/3 テーブルのフィールドに外部キー制約を設定
2/3 テーブルにレコードを追加
外部キーの値は「外部キーの参照先のテーブルのレコード」から選んで入力できるようになる
例)
studentsテーブルに「s_id: 1 , s_name: こばし」
groupsテーブルに「g_id:3, g_name: データベース」
があって
student_groupテーブルに「s_id: 1, g_id: 3」を記録すると、こばしがデータベースのメンバーになるとする
このとき
student_groupテーブルの s_id と g_id フィールドは外部キーで、その値は
students の s_id とgroupsのg_idフィールドから値を選ぶ
ように外部キー制約で設定する
ChatGPTで生成したテーブルの図
c_nameは s_nameの生成ミス
s_idとg_idが主キー
状況確認:
・前回の続きの演習です。前回と同じパソコンを利用してください。
・student_group の各レコードの値がgroupsとstudentsのidと対応するか確認する
・対応しないデータがある場合
studentsやgroupsにレコードを追加する
または
student_group の対応しないレコードの値を修正する
リレーションの設定手順:
・テーブル student_group をクリックして選択する
・テーブルの構造タブをクリックして表示する
リレーションビューボタンを押す。
下記の作業例の画像を参考にして 外部キー制約 を2つ設定する
リレーション設定作業の例)
※この画像ではconstraint properties(制約プロパティ)の制約名を aaa と bbb と場当たり的な名前にした。
説明的な名前にするならgroup_keyやstudent_keyにしよう。
外部キー制約の種類の設定
この演習ではRESTRICTを設定する。
studentsに外部キー制約を設定している例)
この設定の動作チェックは第4回演習(2/3)でおこなう。
外部キー制約には CASCADE と SET NULL と NO ACTION(RESTRICTと同じ)がある
詳しく知りたい人はこちら参照 https://qiita.com/suin/items/21fe6c5a78c1505b19cb
保存する を押す。
・データベース「mytest3122333」をクリックする
デザイナでテーブル間のリレーションを確認(スクリーンショットを撮りWebclassに提出)
下の例の画像参照
外部キー制約の動作確認
・外部キー制約を設定したテーブルにデータを挿入・削除・修正して動作を確認する
提出方法:
phpMyAdmin の デザイナー 機能を利用してテーブルのリレーションを確認する。
→ スクリーンショットを第4回課題 問1としてWebClassに提出
スクリーンショットの例)
※トラブル対応
デザイナに外部キー制約のリンクが表示されていない → 表示切替ボタンを押す
デザイナのテーブルの移動がカクカクする → マウスをゆっくり移動させる
デザイナのテーブルの移動がカクカクする →phpMyAdminを一旦閉じて開きなおす
演習用データベースmytest3123888に次の作業を行う。
(1/6) student_group テーブルのフィールドを1つ以上追加
どのようなフィール名と型を設定するかも自分で考えてよい。
追加方法: 構造→ カラムを追加→ 実行
例)グループに所属した時点で決まる項目を考える
入会年月日
役職
担当
(2/6) テーブルを新規作成(1つ以上追加する)
他のテーブル(例えばstudents)から外部キーとして参照する主キー(例えばid)をフィールドに加えること。
テーブル名とフィールド名(2個以上)と型は自分で企画して考える。
追加方法: データベース名「mytest3123888」をクリックー>テーブルを作成
(3/6) テーブルにレコードを挿入
テーブル(sexualities)を選択 → 挿入
必要に応じてレコードを件数追加する。idフィールドの値はテーブルのA_I設定で自動入力する
例 表記は英語でも日本語でも絵文字でもOK
id sexuality
1 female
2 male
3 none
↑レコードの挿入の例
テーブル新規作成ではない→
(4/6) 元からあるテーブル(例えばstudents)に外部キーを設定
例)
studentsテーブルに外部キーを追加する
追加方法: 構造→ カラムを追加→ 実行
追加したカラムの「タイプ(データ型)」は INT を選ぶ(外部キー制約として他のテーブルの主キーに接続するため)
studentsテーブルにフィールド(カラム)を追加する例)
タイプ(データ型)は INT
NULL も A_I も設定しない
(5/6) studentsに既にあるレコードの追加したフィールドの値を修正
studentsテーブルの外部キーの値を新規追加したテーブルに存在するidの値に修正する必要がある
studentsの既存のレコードの追加フィールドの値はデフォルト値(0など)なので修正する
(6/6) 追加した外部キーにリレーション(外部キー制約)を設定
設定方法: studentsテーブル → 構造 → リレーション
提出方法
課題(2/3)と同様にデザイナのスクリーンショットを保存
→第4回課題 問2としてWebClassに提出
デザイナでリレーションを表示した例)
※トラブル対応
テーブル間のリレーションを設定する際にエラーが発生する場合がある。
主な原因は外部キー参照制約に違反するため。外部キーの値を修正して整合させてエラーを回避できる。
テーブルのレコードの修正方法:
追加したフィールドの値を修正する
表示→ 修正する値をクリック
追加したテーブルの値を修正する
表示→ 修正する値をクリック
■操作して学ぶ 正規化ラボ(2026年度) https://kobashi.github.io/NormalizationZoo/
今回は3NFまで進める
■専門用語の多い正規化の解説(2025年度まで)
■@ITのデータベース正規化の解説記事が分り易くて詳しいので紹介
http://www.atmarkit.co.jp/ait/articles/0605/11/news124.html
他にも テーブルの正規化 で検索して解説記事を探して自分が理解しやすい例を探すとよい。
テーブルのキーAからキーBを導出できるならキーBの記録は必要になる
例1) 生年月日 → 星座
例2) 定価x個数 → 小計 → 合計
導出項目はテーブルの設計上は不要
ただし処理の効率化のためにあらかじめ導出した値を記録する場合もある
テーブルの正規化をやめて分離せずに結合したままにしたり、導出項目を残してDBMSの処理効率UPを狙うことを 非正規化 という
Webclassの問3に回答する。採点は次回講義日以降に行う。
以下に示す「受験者名簿」のテーブルについてデータベースのテーブルを「再設計」してください。
※再設計 企画することではない。元のテーブルの構造を修正する。
この課題ではテーブルを正規化して複数のテーブルに分解することになる。
「受験者名簿」では〇の付いたフィールドが主キー(と候補キー)である。このテーブルは第1正規形であるが第2正規形ではない(補足参照)
各フィールドについて考慮する条件:
受験料は入試区分で決まる
学費は学科で決まる
郵便番号から都道府県と市町村が決まる。番地など住所の詳細までは決まらない
年齢や干支は生年月日から決まる。テーブルにする必要があるか検討する。
同じ出願者番号で複数の入試区分と学科に出願できる
例)
出願者番号 1122 として 住所 氏名 出身校 などを登録した
出願者番号 1122 が 総合型選抜 受験番号 3344 を受験
出願者番号 1122 が 一般入試前期3科目型 受験番号 5566 で受験
テーブル「受験者名簿」
〇受験番号
判定結果
(〇出願者番号、〇入試区分、〇学科) 複合キー
受験料
学費
出身校
氏名
生年月日
受験者の年齢
受験者の十二支の干支
郵便番号
都道府県
市町村
番地など
回答の注意点
導出項目は削除(特定の法則で決定できるのでテーブルに記載しないことにする)
第3正規形にする(必要に応じて別の表を追加してフィールドを整理する)
の2点を考慮して設計変更する。
設計を変更したテーブルと追加するテーブルを全て示すこと。
追加するテーブルの名称は適当に自分で考えてよい。
回答書式:
テーブル名に続けてフィールド名をカンマか「、」で区切って()で括る
主キーのフィールド名の先頭に ○ (WIndows:まる と入力して変換)を付ける
外部キーには先頭に※(WIndows:こめ と入力して変換)を付ける
主キーかつ外部キーのフィールド名には ○※フィールド名 と両方の記号を付ける
例)
天候記録テーブル(〇ID、日時、※地区ID、※天候ID、気温)
天候テーブル(〇天候ID、名称、記号)
地区テーブル(〇地区ID、地区名)
(補足)
非候補キーの「入試区分」から決まるキー「受験料」があるので第2正規形ではない。(完全従属していない)
非候補キーの「学科」から決まるキー「学費」があるので第3正規形ではない。(推移的従属がある)
非候補キーの「生年月日」から決まるキー「受験時の年齢」や「受験者の十二支の干支」がある。(導出項目がある)
非候補キーの「郵便番号」から決まるキー「都道府県、市町村」があるので第3正規形ではない。(推移的従属がある)
Paizaラーニングの「新・SQL入門編1:SQLを始めよう」
Paizaラーニングの「新・SQL入門編2:SELECT文を理解しよう」
https://paiza.jp/works/sql/new-primer
まで取り組んでおくとよいでしょう。