【応用情報】午後『データベース』のリレーションを制する!第1回『必ず1対多』編
はじめに
今回は、応用情報技術者試験の午後『問6:データベース』 に出題されることが多い(ほぼ毎回)リレーションを回答する際のポイントについて書きます。
対象読者
応用情報技術者試験の受験を予定している方で、午後にデータベースを選ぶか検討している人。
またはデータベースを選ぶことにした人。
リレーションって、そんなに大事?
リレーションの設問は少ないものの、正しく読み解いて回答しないと他の設問を解く時に共倒れになったりしますし、そもそも正しく理解することが開発SEとして必要なことであると、私は思います。
ポイントとは?
判断材料のことを指します。
問題文のER図を見た瞬間に「こういう場合は、こうだな!」と、効率よく解けるのが理想です。
今回のサンプル
では、実際の過去問を例にパターンごとの解説をします。
※出典:令和6年度 春期 応用情報技術者試験 午後 問題冊子
前提
回答は凡例に従って線を空欄(この図では『a』)に入れるようなイメージです。
ただし、その中で『←→:多対多』は使いません。
理由は『実装できないから』です。
多対多を実装するには『連関エンティティ』を挟む必要があり、ER図も変わります。
※その話はデータベーススペシャリスト試験のレベルであり、脱線するのでまたの機会に。
前提の中でも・・・
そういうわけで、実際に使うのは下記の2種類となります。
- ー:1対1
- →:1対多(逆向きの『←:多対1』も含む)
そして、出題される確率が高いのは圧倒的に『1対多(多対1も含む)』です!
過去の記事で過去問を分析しておりますので、よろしければご参照ください。
【過去31回分】応用情報技術者試験(午後 問6:データベース )過去問と模範解答を見て傾向と対策を考えてみた。
1つ目:必ず『1対多』になるパターン
ここでは分かり易い例として、テーブル『会社』と『会社記念日』を見ましょう。
これは典型的なパターンですが、理由を知ることでリレーションを空欄にされても一瞬で見抜けます。
ちなみに、実線のアンダーラインが主キーであることは凡例に記載されています。
- テーブル『会社』の主キーは『会社番号』
- テーブル『会社記念日』の主キーは『会社番号』と『会社記念日』
はい、この時点で確定です。理由は
- テーブル『会社』と『会社記念日』に共通する項目は『会社番号』のみである。
- テーブル『会社』は項目 『会社番号』のみで一意制約となる(それだけが主キーだから)
- テーブル『会社記念日』は項目 『会社番号』と『会社記念日』の組合せで一意制約となる。
- つまり、テーブル『会社記念日』の項目『会社番号』 は重複することがある。
実際のデータをイメージしてみよう
上記の説明だけでは分かり辛いので、実際にテーブル定義を作ってみましょう。
まず、データはこのようなイメージです。
テーブル『会社』
会社番号(主キー) | 会社名 | 業種 |
---|---|---|
1001 | A社 | IT |
1002 | B社 | 小売 |
1003 | C社 | 物流 |
テーブル『会社記念日』
会社番号(主キー) | 会社記念日(主キー) | 会社記念日名 |
---|---|---|
1001 | 10/1 | 創立記念日 |
1001 | 12/13 | 社長誕生日 |
1002 | 3/23 | 創立記念日 |
1002 | 9/20 | 従業員感謝デー |
1003 | 6/7 | 創立記念日 |
1003 | 11/14 | 会長誕生日 |
まず、テーブル同士でリレーション(結合)できそうな項目が『会社番号』というのは分かりますね。
そしてテーブル『会社記念日』 の方は、会社番号が同じ行が複数あります。
項目『会社記念日』との組合せで主キーになるので、それが許されます。
実際にデータにしてみると『重複が許されるのかどうか』がイメージしやすいので、ぜひ試してみてください。
ついでに実務っぽい使い方もしてみよう
問題文には書いていない内容ですが、これらのテーブルに貼られたリレーションがどのように使われるのか、SQLを実行してみます。
PostgreSQLで書きますので、よろしければ試してみてください。
※簡単に試す方法はこちらの記事を参考にして下さい。
まず、先程のデータを作ります。
-- 会社テーブルを作る
CREATE TABLE 会社 (
会社番号 INTEGER PRIMARY KEY -- 主キー
, 会社名 VARCHAR
, 業種 VARCHAR
);
-- 会社テーブルにデータを登録
INSERT INTO 会社 VALUES
(1001,'A社','IT')
,(1002,'B社','小売')
,(1003,'C社','物流')
;
-- 会社記念日テーブルを作る
CREATE TABLE 会社記念日 (
会社番号 INTEGER
, 会社記念日 VARCHAR
, 会社記念日名 VARCHAR
, PRIMARY KEY(会社番号,会社記念日) -- 主キー
);
-- 会社記念日テーブルにデータを登録
INSERT INTO 会社記念日 VALUES
(1001,'10/1','創立記念日')
,(1001,'12/13','社長誕生日')
,(1002,'3/23','創立記念日')
,(1002,'9/20','従業員感謝デー')
,(1003,'6/7','創立記念日')
,(1003,'11/14','会長誕生日');
そして、リレーションを張って両方のテーブルからデータを取得するSELECT文を発行します。
下記は1つの例なので、取得する項目や条件は業務要件によって変わります。
-- 会社名と業種と記念日の情報を取得
SELECT
ki.会社番号
,sh.会社名
,sh.業種
,ki.会社記念日
,ki.会社記念日名
FROM 会社記念日 ki
LEFT OUTER JOIN 会社 sh ON ki.会社番号 = sh.会社番号
ORDER BY ki.会社番号 ,ki.会社記念日;
実行すると、このような結果になります。
『会社名、業種、記念日の全ての情報を1つの表で欲しい』という要件の場合です。
さいごに
いかがでしたか?
「リレーション1つ説明するのに、わざわざテーブル定義を作ったり、SQLを実行するのはやり過ぎでは?」
と思うかもしれません。
ですが、実務で役立てるには本質を理解する必要があるので、あえて面倒なやり方を取ってみました。
ここまでやっておいて、まだ続きがあります(笑)
次回以降は 『1対1』の場合や、判断ができない場合などを解説します。
懲りずに付いてきていただけると嬉しいです^^;
では、今回は以上です。
ここまでお付き合い頂き、ありがとうございましたm(_ _)m
Discussion