データベーススペシャリスト 2018年 午後1 問02
データベースでの制約の実装に関する次の記述を読んで、設問1〜3に答えよ。
総合商社のY社は、人事情報管理に RDBMS を用いている。
〔RDBMS の主な仕様〕
人事情報管理データベースに用いている RDBMS の主な仕様は、次のとおりである。
1.参照制約
参照制約では、挙動モードと検査契機モードを指定できる。
(1) 挙動モード
挙動モードには、次の二つがある。
① NO ACTION : 参照先のテーブルの行を削除又は更新したとき、参照元のテテーブルの行に対して何もしない。
② CASCADE : 参照先のテーブルの行を削除又は更新したとき、参照元のテテーブルの行にも削除又は更新を連鎖させる。
(2) 検査契機モード
検査契機モードには、次の二つがある。
① 即時モード: SQL 実行終了ごとに、対象となる全ての行の実行結果に対して、制約を検査する。
② 猶予モード: トランザクション終了時に、トランザクション内の全ての SQLを実行した結果に対して、制約を検査する。
2.トリガ
テーブルに対する変更操作 (挿入・更新・削除)を契機に、あらかじめ定義された処理を、操作対象の行ごとに実行する。 実行タイミング (挿入・更新・削除の前又は後)、列値による実行条件を定義することができる。 ただし、実行タイミングを挿入・更新・削除の前として定義したトリガの処理の中で、テーブルに対する変更操作を行うことはできない。
〔人事情報管理データベースのテーブル〕
人事情報管理データベースの主なテーブルのテーブル構造は、図1のとおりである。索引は、主キーだけに定義されている。

〔人事情報管理の業務概要〕
人事情報管理担当者は、業務上のイベント発生時にテーブルの更新を行うとともに、社内の各部署からの情報提供要求に対応するために、SQL で検索した結果をレポートにして提供している。 業務上の主なイベントとテーブルの更新内容、及びレポート提供の一例は次のとおりである。
1.従業員の退職
満65歳で定年退職及び従業員の自己都合による退職が随時発生する。 定年退職の場合、退職年月日は、満65歳の誕生日の前日である。 従業員を “従業員” テブルに登録するときに、退職年月日に定年退職の年月日を設定する。 自己都合による退職の場合、退職年月日は申告された日に更新する。
退職すると、“従業員” テーブルの退職フラグを、あらかじめ設定している '0'(在籍)から '1' (退職) に更新する。 この処理は、退職年月日の当日に行う。給与計算は毎月20日締めで行う。 また、毎月25日に、“従業員” テーブル及び“従業員家族” テーブルから、当月の20日までに退職した従業員の行を削除する。削除した行を別テーブルに保存するために、実行タイミングを“従業員”テーブルの削除の後としたトリガを定義している。 トリガに定義している処理は、次のとおりである。
・削除した “従業員” テーブルの行を別テーブルに挿入する。
・“従業員家族” テーブルのその従業員の家族の行について、別テーブルに挿入し、その後削除する。
毎月25日に行を削除するための、三つの述語から成る SQL の構文は表1のとおりである。

2.従業員家族構成の変更
従業員ごとの事由によって、家族の増減、扶養対象者数の変更などが随時発生する。このとき、“従業員家族” テーブルへの行挿入、主キー以外の列値の更新(扶養フラグは、扶養対象者でない場合は '0'、扶養対象者の場合は '1' に更新)、行削除を行う。
3.定期的な組織変更及び人事異動
毎年4月1日及び10月1日に組織変更及び人事異動を実施している。組織変更では、部署の新設、廃止が発生する。 このとき、“部署” テーブルに対する行挿入、行削除を行う。
人事異動で、従業員が所属する部署が変更になった場合、“従業員” テーブルの部署コードの更新を行う。
4.レポート提供の一例
福利厚生担当者から人事情報管理担当者に対して、従業員家族向けのレクリエーション企画のために、部署コード順に 2007年1月1日以降に生まれた扶養対象者をもつ従業員数と扶養対象者数の一覧表が欲しいとの依頼があった。 その例を図2に示す。
人事情報管理担当者は、表2の SQL文を用いて、図2の一覧表を作成した。


〔人事情報管理データベースで発生している問題点〕
定型的な業務上のイベントはアプリケーションプログラムで実装している。 しかし、組織変更及び人事異動のイベントで、部署コードなどの更新する列の内容が変動するものは、次のような運用を行っている。
・人事情報管理担当者が、イベント別に用意してある更新 SQL 文のバッチジョブを利用して、業務上のイベントに対応したテーブルの更新を実施する。
・人事情報管理担当者はイベントに応じてバッチジョブへの入力データを作成している。
現状の問題点として、入力データの作成ミスによって、実際に存在しないコードでテーブルを更新することがあり、給与計算システムでトラブルが起きている。 この問題点を解決するために、RDBMS の参照制約機能を利用することにした。参照制約機能の利用案を表3に示す。

〔参照制約機能の利用の検討〕
参照制約機能を利用する以前には、定期的な組織変更及び人事異動に対応する処理は、図 3 に示すように “部署” テーブルの行を更新した後、“従業員” テーブルの行を更新していた。
参照制約機能を利用するに当たって、図3 中の ①〜⑥の更新手順の変更及び処理時間の検討を行った。

設問1:人事情報管理の業務概要について、(1)、(2)に答えよ。
(1)表1中の(a)〜(c)に入れる適切な字句を答えよ。(b, cは順不同)
模範解答
a:'1'
b:21
c:CURRENT_DATE
解説
解答の論理構成
- 退職フラグ条件
【問題文】「退職すると、“従業員” テーブルの退職フラグを… '1' (退職) に更新する」
→ 退職者のみを対象にするため (a) ='1'
。 - 削除対象日付の上限
【問題文】「給与計算は毎月20日締め…毎月25日に…当月の20日までに退職した従業員の行を削除」
→ “20日まで” とは 20 日以前を含むので、DAYELEMENT(退職年月日) < 21
が必要。よって (b) =21
。 - 月をまたぐ判定
退職日が前月以前なら無条件で削除する必要がある。今が何月かを知るには実行日の月を取得する関数が必要。
→MONTHELEMENT(退職年月日) < MONTHELEMENT(CURRENT_DATE)
となるため (c) =CURRENT_DATE
。 - “順不同” の注意
問題指示「(b, cは順不同)」は列挙順の自由を示すだけで、(b) と (c) の内容は上記の通り固定です。
誤りやすいポイント
20
と書いてしまう
退職日が 20 日当日を含むには「< 21」が正解。<= 20
では当日を含みません。SYSDATE
を使う
問題の表記はCURRENT_DATE
。数字・固有名詞の改変は不可です。- 退職フラグ
'0'
と誤解する
'0'
は在籍者です。引用文の読み落としに注意。
FAQ
Q:
A: 同月内で 20 日以前かどうかの判定が欠けるため、
MONTHELEMENT(退職年月日) < MONTHELEMENT(CURRENT_DATE)だけで十分では?
A: 同月内で 20 日以前かどうかの判定が欠けるため、
DAYELEMENT比較が必須です。
Q: 21 日ちょうどに退職した人は削除対象ですか?
A: いいえ。「< 21」にしているため、20 日までが対象です。21 日退職は次月 25 日に削除されます。
A: いいえ。「< 21」にしているため、20 日までが対象です。21 日退職は次月 25 日に削除されます。
Q:
A: ダメです。バッチは毎月 25 日に実行されるため、その時点のシステム日付を動的に取得する必要があります。
CURRENT_DATEを固定値(例:
'2023-05-25')にしても良い?
A: ダメです。バッチは毎月 25 日に実行されるため、その時点のシステム日付を動的に取得する必要があります。
関連キーワード: 参照制約、DATE型、トリガ、データ削除、ユーザ定義関数
設問1:人事情報管理の業務概要について、(1)、(2)に答えよ。
(2)表2中の(d)〜(f)に入れる適切な字句を答えよ。
模範解答
d:従業員.部署コード
e:DISTINCT
f:ORDER BY
解説
解答の論理構成
- 問題文の SQL2 抜粋
SELECT (d) 、COUNT((e) 従業員家族.従業員コード) AS 従業員数、 COUNT(*) AS 扶養対象者数 FROM 従業員、従業員家族 WHERE 従業員.従業員コード = 従業員家族.従業員コード AND 従業員家族.扶養フラグ = '1' AND 従業員家族.生年月日 >= TO_DATE('2007-01-01') GROUP BY (d) (f) (d) - 部署単位で集計・並べ替え
- 依頼は「部署コード順に 2007年1月1日以降に生まれた扶養対象者をもつ従業員数と扶養対象者数の一覧表」
- よって
(d)
に入るのは一覧のキーである従業員.部署コード
。
- 従業員数の重複排除
- 同一従業員に家族が複数行存在するので、そのまま
COUNT(従業員家族.従業員コード)
では重複計上されます。 - 重複排除には
COUNT(DISTINCT 従業員家族.従業員コード)
の構文を使うため(e)
はDISTINCT
。
- 同一従業員に家族が複数行存在するので、そのまま
- 並べ替え句
- 一覧表は「部署コード順」で要求されているため、
ORDER BY
句を付加して(f)
はORDER BY
。
- 一覧表は「部署コード順」で要求されているため、
GROUP BY
・ORDER BY
と列整合- 集計キー
(d)
をGROUP BY
とORDER BY
双方に使用し、SELECT
の先頭列でも同じ列を出力する。
- 集計キー
誤りやすいポイント
COUNT(*)
とCOUNT(列名)
の違いを混同し、従業員数を正しく求められない。GROUP BY
で指定した列をSELECT
に含め忘れる。ORDER BY
にエイリアスを使えず(d)
をそのまま書く必要がある点を見落とす。
FAQ
Q:
A: 重複排除のために一時的なソートやハッシュが走るため、行数が多いと負荷が高まります。インデックスでサポートすると改善できます。
COUNT(DISTINCT …)はパフォーマンスに影響しますか?
A: 重複排除のために一時的なソートやハッシュが走るため、行数が多いと負荷が高まります。インデックスでサポートすると改善できます。
Q:
A: 多くの RDBMS で動作しますが、列追加などで壊れやすく可読性も下がるため、本試験では列名を明示する方が安全です。
ORDER BY 1のように序数指定でも良いですか?
A: 多くの RDBMS で動作しますが、列追加などで壊れやすく可読性も下がるため、本試験では列名を明示する方が安全です。
関連キーワード: GROUP BY, COUNT関数、DISTINCT句、ORDER BY
設問2:表3について、(1)、(2)に答えよ。
(1)次の(a)、(b)の処理を実行した場合、正常終了と、制約検査でエラーのどちらになるか。答案用紙の正常終了・エラーのいずれかを○で囲んで示せ。エラーとなる場合は、その理由を,40字以内で具体的に述べよ。
(a)新規従業員登録のために、所属未定(部署コードが NULL)の行を“従業員”テーブルに挿入する。
(b)ある部署の管理者退職に伴い、“従業員”テーブルから当該従業員を削除する。
模範解答
(a):結果:正常終了
理由:(なし)
(b):結果:エラー
理由:“部署”テーブルの管理者従業員コードの参照制約に違反するから
解説
解答の論理構成
- “参照制約” の仕様
【問題文】では挙動モードに「① NO ACTION」「② CASCADE」が定義されています。NO ACTION
は参照整合性を保持できない操作を禁止します。 - (a) 所属未定の従業員挿入
- 【表3】で “従業員”.“部署コード” の挙動は
UPDATE/NO ACTION
、DELETE/CASCADE
、検査契機は「猶予モード」です。 - 挿入時に “部署コード” が
NULL
の場合、参照制約は適用されません(参照値が存在しないため)。 - よって制約違反は発生せず「正常終了」と判断できます。
- 【表3】で “従業員”.“部署コード” の挙動は
- (b) 管理者従業員の削除
- “部署”.“管理者従業員コード” は【表3】で
DELETE/NO ACTION
と定義されています。 - 当該従業員が “部署” テーブルから参照されている状態で “従業員” テーブルから削除すると、参照先が失われるため
NO ACTION
によりエラーが返されます。 - したがって「エラー」になり、その理由は「“部署”テーブルの管理者従業員コードの参照制約に違反するから」です。
- “部署”.“管理者従業員コード” は【表3】で
誤りやすいポイント
NULL
でも必ず制約検査が行われると誤解する。CASCADE
とNO ACTION
を参照元・参照先で混同する。猶予モード
と即時モード
の違いを結果判定に結び付けられない。- “従業員家族” 側の
DELETE/CASCADE
に気を取られて (b) が許可されると誤判断する。
FAQ
Q:
A: いいえ。参照される側(親)の列に
DELETE/CASCADEが設定されている列は削除しても絶対にエラーにならないのですか?
A: いいえ。参照される側(親)の列に
DELETE/CASCADEがあれば連鎖削除が行われますが、他に
DELETE/NO ACTIONの制約が存在すればそちらが優先し、エラーになる場合があります。
Q:
A: はい。検査はトランザクション終了時です。ただし今回の (a) では
猶予モードの制約違反はトランザクション終了まで検出されませんか?
A: はい。検査はトランザクション終了時です。ただし今回の (a) では
NULLなのでそもそも検査対象外です。
関連キーワード: 参照制約、NO ACTION, CASCADE, NULL値、検査契機
設問2:表3について、(1)、(2)に答えよ。
(2)“従業員”テーブル及び “従業員家族” テーブルから退職した従業員の行を削除して別テーブルに保存するトリガについて、参照制約を利用することによって不具合が発生する。その対策として、“従業員”テーブルのトリガ定義を変更した上で、新たなトリガを定義する。新たに定義するトリガについて、対象となるテーブルのテーブル名、実行タイミング、処理内容をそれぞれ答えよ。
模範解答
テーブル名:従業員家族
実行タイミング:削除の後
処理内容:削除した行を別テーブルに挿入する。
解説
解答の論理構成
- 参照制約による動作確認
表3の “従業員家族―従業員(従業員コード)” のDELETE
挙動モードは CASCADE と記載されています。 - 既存トリガの不具合発生点
問題文には「削除した “従業員家族” テーブルのその従業員の家族の行について、別テーブルに挿入し、その後削除する。」とあります。CASCADE により家族行は RDBMS によって即時削除されるため、“従業員”側トリガが発火した時点では既に行が存在しません。 - 対策の方針
・“従業員”テーブルのトリガでは家族行に触れないよう定義を変更
・削除された家族行を確実に保存するため、家族テーブル自身で AFTER DELETE トリガを定義 - トリガ設計
- テーブル名:従業員家族
- 実行タイミング:削除の後(行が削除された直後に
OLD
値が残る) - 処理内容:
INSERT INTO 家族退職履歴 ... VALUES (OLD.*)
のようにアーカイブ表へ挿入
誤りやすいポイント
- BEFORE と AFTER の取り違え:BEFORE では削除後の行内容が取得できません。
- 親テーブルトリガで子テーブル行を扱おうとする設計ミス:CASCADE が働くと子行は既に消えている。
- 参照制約を付加しただけで業務ロジックが自動で補完されると誤解する点。
FAQ
Q:
A: 制約検査のタイミングだけでトリガの発火タイミング自体は変わりません。今回の論点は CASCADE に伴う削除順序です。
猶予モードと
即時モードの違いはトリガ動作にも影響しますか?
A: 制約検査のタイミングだけでトリガの発火タイミング自体は変わりません。今回の論点は CASCADE に伴う削除順序です。
Q: AFTER DELETE トリガ内でさらに
A: はい、問題文でも「削除の後としたトリガの処理の中で...削除する」と記載があり、AFTER なら同一テーブル・他テーブルへの変更が可能です。
DELETEすることは可能ですか?
A: はい、問題文でも「削除の後としたトリガの処理の中で...削除する」と記載があり、AFTER なら同一テーブル・他テーブルへの変更が可能です。
Q: CASCADE でも削除前に家族行を保存したい場合は?
A: BEFORE DELETE トリガを使い
A: BEFORE DELETE トリガを使い
OLD行を退避する方法もあります。ただし今回の設計方針(削除後まとめて作業)に合わせ AFTER を選択しています。
関連キーワード: 参照制約、CASCADE, AFTER DELETE, トリガ、データアーカイブ
設問3:参照制約機能の利用の検討に示した、参照制約機能を利用した後について、(1)〜(3)に答えよ。
(1)図3中の①〜⑥のデータの削除、挿入、更新の順序を変更せずに運用した場合、不具合が発生することがある。不具合が発生する契機を図3中の丸数字で答えよ。また、発生する不具合の内容を,40字以内で述べよ。
模範解答
契機:①
不具合:削除された部署に所属している従業員が、“従業員”テーブルから削除される。
解説
解答の論理構成
- 前提確認
【表3】に
とある。削除元(親)は“部署”、削除先(子)は“従業員”である。従業員/部署コード … DELETE CASCADE
- 現行手順の再掲
図3 手順①:『“部署”テーブルから不要な行を削除する。』
手順⑤:『“従業員”テーブルの部署コードを更新する。』 - 参照制約導入後の挙動
①で部署行を削除すると,DELETE‐CASCADE により参照している従業員行が自動削除される。
⑤で部署コードを更新しようとしても、既に該当従業員行はないので処理以前にデータが失われる。 - 結論
よって不具合の契機は①、内容は
「削除された部署に所属している従業員が、“従業員”テーブルから削除される。」
誤りやすいポイント
- 「NO ACTION はエラーになる」と早合点し,CASCADE の連鎖削除を見落とす。
- ⑤の UPDATE が先に走ると考え、①の影響を評価しない。
- 検査契機モードの「猶予モード」を即時チェックと混同し、トランザクション終了まで削除が遅れると誤解する。
FAQ
Q: ①ですぐにエラーが返らないのですか?
A: DELETE CASCADE なのでエラーではなく、自動的に従業員行が削除されるため、担当者は問題に気付きにくいです。
A: DELETE CASCADE なのでエラーではなく、自動的に従業員行が削除されるため、担当者は問題に気付きにくいです。
Q: 検査契機モードが「猶予モード」ならトランザクション終了まで削除されませんか?
A: “従業員”.“部署コード”の検査契機モードは【猶予モード】ですが、親行削除に伴う CASCADE はトランザクション内で即時に論理削除されます。
A: “従業員”.“部署コード”の検査契機モードは【猶予モード】ですが、親行削除に伴う CASCADE はトランザクション内で即時に論理削除されます。
関連キーワード: 参照制約、CASCADE, 外部キー、トランザクション、データ整合性
設問3:参照制約機能の利用の検討に示した、参照制約機能を利用した後について、(1)〜(3)に答えよ。
(2)1の不具合の回避のために、図3中の①、③、⑤の順序を変更する。どのように変更すればよいか、①、③、⑤の変更後の順序を答えよ。
模範解答
[ ③ ] → ② → [ ⑤ ] → ④ → [ ① ] → ⑥
解説
解答の論理構成
- 【問題文】では、入力データのミスにより「実際に存在しないコードでテーブルを更新」することが問題と述べられています。
- そこで表3の参照制約案を導入し、
- “従業員.部署コード” に対して「参照先:部署(部署コード)」
- 「UPDATE … NO ACTION」「DELETE … CASCADE」「検査契機モード:猶予モード」
を設定すると宣言されています。
- 参照制約が有効な場合、
- 参照“先”が存在しない状態で参照“元”を INSERT/UPDATE すると制約違反になります。
- 逆に、参照“元”が残っている状態で参照“先”を DELETE しても制約違反です(今回の挙動モードは「CASCADE」ですが、猶予モードなのでトランザクション終了時まで違反が保留されます)。
- したがって
(1) まず③で新しい部署を挿入し参照先を用意する。
(2) ②でコミットし、参照先確定。
(3) 次に⑤で従業員の部署コードを更新する。
(4) ④でコミットし、参照元確定。
(5) 最後に①で不要部署を削除する。参照元が既に異動済みなので制約違反にならない。
(6) ⑥でコミットして完了。 - 以上より「③ → ② → ⑤ → ④ → ① → ⑥」が最適順序となります。
誤りやすいポイント
- 「CASCADE だから削除順序は自由」と思い込み、①を先に実行してしまう。猶予モードでもトランザクション終了時には整合が取れている必要があります。
- ③と⑤のどちらを先にするか迷い、参照先未整備のまま従業員を UPDATE して制約違反になる。
- ②・④・⑥ のコミット位置を軽視し、猶予モードの検査タイミングを誤解する。
FAQ
Q: 「猶予モード」ならトランザクション中は制約違反でもよいのでは?
A: トランザクション終了時には必ず整合が取れていなければなりません。今回の手順では ④ のコミットで制約チェックが走るため、そこまでに参照整合性を満たしておく必要があります。
A: トランザクション終了時には必ず整合が取れていなければなりません。今回の手順では ④ のコミットで制約チェックが走るため、そこまでに参照整合性を満たしておく必要があります。
Q: 「CASCADE」指定なので①で部署を削除しても従業員行が自動で更新されるのでは?
A: 部署側は「DELETE … CASCADE」ですが、従業員側の部署コードは自動更新せず削除連鎖です。従業員行を残したまま部署行を削除すると従業員行も削除され、業務要件に反します。
A: 部署側は「DELETE … CASCADE」ですが、従業員側の部署コードは自動更新せず削除連鎖です。従業員行を残したまま部署行を削除すると従業員行も削除され、業務要件に反します。
Q: 参照制約導入後でも手順③→⑤→①の間にコミットは必要?
A: 必要です。② と ④ のコミットで検査契機が発動し、整合性が保証されます。コミットを省くと違反が発覚せずロールバックになる恐れがあります。
A: 必要です。② と ④ のコミットで検査契機が発動し、整合性が保証されます。コミットを省くと違反が発覚せずロールバックになる恐れがあります。
関連キーワード: 参照制約、CASCADE, 即時モード、猶予モード、トランザクション
設問3:参照制約機能の利用の検討に示した、参照制約機能を利用した後について、(1)〜(3)に答えよ。
(3)表3に示すとおり、“従業員”テーブルの部署コードに参照制約が猶予モードで設定されている。この状況で、“部署”テーブルの部署コードを更新したときの振る舞いに関して、(a)、(b)に答えよ。
(a)RDBMSは猶予モードの制約の検査のために、トランザクション終了時にどのような検査を行っているか、検査内容を55字以内で具体的に述べよ。
(b)(a)の検査を行う際、想定よりも処理時間が長くなるおそれがある。その理由を50字以内で具体的に述べよ。
模範解答
(a):更新によって無くなった部署コードが、“従業員”テーブルの“部署コード”に存在しないことを確認する。
(b):“従業員”テーブルの“部署コード”に索引がなく、全行を参照しなければならないから
解説
解答の論理構成
- 参照制約の仕様確認
【問題文】「① 即時モード」「② 猶予モード: トランザクション終了時に…制約を検査する。」
よって猶予モードでは処理完了後にまとめて検査。 - 検査内容の特定
・表3で “従業員”.“部署コード” が “部署”.“部署コード” を参照。
・更新により “部署” テーブルから削除・変更されたコードが “従業員” に残っていれば参照整合性違反。
⇒ 検査は「更新でなくなった部署コードが、参照元に存在しないこと」の確認となる。 - 処理時間が延びる理由
・図1の注記で「索引は、主キーだけに定義されている。」
・“部署コード” は主キーでないため索引が無い。
・検査時には “従業員” の全行を検索(フルスキャン)。行数が多いほど時間増大。
誤りやすいポイント
- 猶予モードを「最後の SQL 実行直後」と誤解し、途中で検査が行われると考えてしまう。
- CASCADE 動作と猶予モード検査を混同し、検査が不要になると思い込む。
- 索引が主キーにのみ定義されている事実を見落とし、処理時間の影響源を誤答。
FAQ
Q: CASCADE が指定されているのに検査が必要なのはなぜですか?
A: CASCADE が働くのは参照先行の削除・更新時に連鎖操作を行う場面です。猶予モードでは連鎖後に整合性が保たれているかを改めて確認します。
A: CASCADE が働くのは参照先行の削除・更新時に連鎖操作を行う場面です。猶予モードでは連鎖後に整合性が保たれているかを改めて確認します。
Q: 即時モードと猶予モードの混在は性能に影響しますか?
A: 即時モードは SQL 実行ごとに検査するため応答時間が延びやすく、猶予モードはトランザクション終了まで処理を遅延させるのでロールバック時のペナルティが大きくなります。
A: 即時モードは SQL 実行ごとに検査するため応答時間が延びやすく、猶予モードはトランザクション終了まで処理を遅延させるのでロールバック時のペナルティが大きくなります。
Q: 検査時間を短縮する方法は?
A: “従業員”.“部署コード” に索引を追加すればフルスキャンを避けられ、猶予モード検査も高速化します。
A: “従業員”.“部署コード” に索引を追加すればフルスキャンを避けられ、猶予モード検査も高速化します。
関連キーワード: 参照制約、猶予モード、フルテーブルスキャン、索引、CASCADE


