基本情報技術者(FE)対策

正規化とSQL

正規化は「どこまで分けたか」を答えさせる

データベースの出題は、正規化の段階を判定する問題と、SQL を読んで結果を選ぶ問題の 2 つが柱です。設計論を語らせる問題は出ないので、表を見て段階を言い当てられる状態を作ります。

正規化とは、1 つの表に押し込まれた項目を、重複と矛盾が起きないように分けていく作業です。判定に使う言葉は関数従属で、ある項目が決まれば別の項目が 1 つに決まる関係を指します。商品コードが決まれば商品名が 1 つに決まるので、商品名は商品コードに関数従属しています。

3 つの段階を 1 枚の表で通す

次の受注表を材料にします。主キーは受注番号と商品コードの組です。

受注番号受注日顧客コード顧客名商品コード商品名数量
10014月1日C01青山商店P10えんぴつ5
10014月1日C01青山商店P20ノート3

第 1 正規形は、1 つの欄に複数の値が入っている状態や繰返し項目をなくし、1 行 1 組にした形です。上の表はすでにその形になっています。

第 2 正規形は、主キーの一部だけで決まる項目を追い出した形です。商品名は商品コードだけで決まり、受注日と顧客の情報は受注番号だけで決まります。どちらも主キーの一部にしか従っていないので、商品表と受注表に分け、元の表には受注番号と商品コードと数量だけを残します。

第 3 正規形は、主キー以外の項目を経由して決まる項目を追い出した形です。分けたあとの受注表では、受注番号が決まると顧客コードが決まり、顧客コードが決まると顧客名が決まります。顧客名は主キーに間接的にしか従っていないので、顧客表へ移します。

判定の手順は 3 手です。まず主キーを決め、次に主キーの一部で決まる項目を探し、最後に主キー以外を経由して決まる項目を探します。前者が残っていれば第 1 正規形どまり、後者が残っていれば第 2 正規形どまりです。

SQL は集計と結合が読めればよい

科目Aで問われる SQL は、結果の表を選ばせる形がほとんどです。押さえるべきは GROUP BY と HAVING、そして結合です。

SELECT 商品コード, SUM(数量) AS 合計数量 FROM 受注明細 WHERE 受注番号 >= 1000 GROUP BY 商品コード HAVING SUM(数量) >= 10

WHERE と HAVING はどちらも絞り込みですが、働く時点が違います。WHERE はグループにまとめる前の行を絞り、HAVING はまとめたあとのグループを絞ります。したがって WHERE の条件に SUM のような集計関数は書けません。この違いを突く選択肢が定番です。

結合は、2 つの表を共通の列でつなぐ操作です。

SELECT A.受注番号, B.顧客名 FROM 受注 A, 顧客 B WHERE A.顧客コード = B.顧客コード

結合条件を書き忘れると、すべての行の組合せが並ぶ直積になります。10 行と 20 行の表なら 200 行です。行数が不自然に多い選択肢は、この直積を表していると考えて外せます。

出やすい周辺の用語

主キーは行を 1 つに特定する列で、空値を許しません。外部キーは他の表の主キーを参照する列で、参照先に無い値を入れられない決まりが参照制約です。この制約があるおかげで、顧客表に無い顧客コードを受注表に書けなくなります。正規化で表を分けたあと、整合性を保っているのがこのしくみです。

生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア
編集 LuaGate編集部