応用情報技術者 2018年 秋期 午後 問06
入室管理システムの設計に関する次の記述を読んで、設問1~5に答えよ。
H社は中堅の食品会社で、社内システムのデータベースの統合を検討している。現在、社内システムごとにデータベースのサーバを用意して運用しているが、関係データベース管理システム(以下、RDBMSという)のライセンスコストと運用コストを削減するために1台のサーバに統合し、各社内システムのデータベースは、統合したサーバのRDBMSでスキーマを分けて管理することになった。
〔社員情報の共用〕
全ての社内システムは、社員IDや氏名などの社員情報を使用する。現在は、人事システムが管理している社員情報のマスタデータを月次処理で各社内システムに配布して運用しているが、最新の情報が反映されるのが翌月になること、月次処理の運用負荷が大きいことなどから改善が望まれている。今回、サーバを統合するに当たり、各社内システムにデータを配布するのではなく、人事システムが管理する社員情報に関連する実表を参照する方式に変更することを検討している。人事システムの社員情報に関連する実表を表1に示す。

セキュリティの観点から検討した結果、人事システム以外の社内システムから社員情報に関連する実表を直接参照するのではなく、社員情報を使用する社内システムごとに必要な列だけをビュー表として公開し、ビュー表を参照する方式を採用することに決定した。
〔入室管理システム〕
会社内の特別な部屋の入退室管理を行う入室管理システムは、サーバ統合の対象となるシステムの一つである。入室管理システムで利用する主な実表とビュー表を表2に、E-R図を図1に、入室に関する主なユースケースを表3に示す。



表3のユースケース“入室”で、入室可否をチェックし、否の場合は0を、可の場合は1以上を返すSQL文を図2に示す。ここで、“社員ID”は指定された社員IDを格納する埋込み変数、“:室ID”は指定された室IDを格納する埋込み変数、“:今日”はSQL文実行時の現在日付を格納する埋込み変数である。また、ROOMは入室管理システムのスキーマ名で、表は“スキーマ名.表名”で表記する。

〔各社内システムのRDBMSユーザ〕
社内システムごとにデータベース管理者(以下、DBAという)が存在する。DBAは表の所有者であり、他のユーザに対して、自分が所有する表へのアクセス権限を付与することができる。DBAは、各社内システムのアプリケーションプログラム(以下、APという)が表のデータにアクセスすることができるようにAP用のユーザに対して、適切な権限を付与する。各社内システムのスキーマ名と、DBA用、AP用のRDBMSユーザ名を表4に示す。

〔RDBMSの表のアクセス権限に関する主な仕様〕
使用しているRDBMSの表のアクセス権限に関する主な仕様を(1)、(2)に示す。
(1) 表のデータに対して、所有者以外のユーザが参照、挿入、更新及び削除を行うためには、表に対して対応するアクセス権限(SELECT, INSERT, UPDATE及びDELETEの各権限)を所有者から付与してもらう必要がある。
(2) ビュー表にアクセスする場合、そのビュー表が参照する表のアクセス権限は不要である。
〔入室管理システム用の社員ビュー表〕
表2のビュー表“入室管理用社員”を定義するSQL文を図3に示す。

このビュー表を入室管理システムのAPが参照だけできるように権限を付与するSQL文を図4に示す。

〔入室申請時の確認の強化〕
管理者は、“申請者が入室希望社員の組織長であること”を確認することになった。
そのため、ビュー表“入室管理用社員”に組織長の氏名が必要となり、図5に示すSQL文に変更した。

設問1:
図1に適切なエンティティ間の関連を記入し、E-R図を完成させよ。図1の凡例に倣うこと。
模範解答
(図を参照)


解説
解答の論理構成
-
エンティティの列構成を確認
・ビュー表 “入室管理用社員” は列に “社員ID” をもつ(【表2】)。
・実表 “室” は列に “室ID” をもつ(【表2】)。
・実表 “入室許可” は列に “社員ID, 室ID” をもつ(【表2】)。
・実表 “入退室ログ” は列に “社員ID, 室ID” をもつ(【表2】)。 -
“入室許可” と他エンティティの関係を決定
“入室許可” は「同じ社員に対して複数の室が許可される」「同じ室に対して複数の社員が許可される」ため、“社員ID” と “室ID” が外部キーとなる。
よって
・“入室管理用社員”1 ―▶ 多 “入室許可”
・“室”1 ―▶ 多 “入室許可” -
“入退室ログ” と他エンティティの関係を決定
“入退室ログ” は「社員が室を利用するたびに蓄積される」ログであり、ログ件数は社員・室のどちらに対しても多側になる。
よって
・“入室管理用社員”1 ―▶ 多 “入退室ログ”
・“室”1 ―▶ 多 “入退室ログ” -
多対多は存在しないかを確認
“入室許可” と “入退室ログ” の間で多対多が生まれる可能性があるが、E-R図では両者の直接関連を求めていない(ログは許可の有無を参照するだけで外部キーを持たない)。したがって矢印は不要。 -
以上を図に反映
凡例の「―――――――――――▶」は1対多を示すため、4本の矢印を描画すれば完成となる。
誤りやすいポイント
- “入退室ログ” を多対多と誤認し「←――――――――――→」を描いてしまう。ログは中間エンティティではなく実績テーブルなので1対多。
- ビュー表 “入室管理用社員” を「たかがビュー」と軽視し実表 “社員” を図に書いてしまう。問題で求められたエンティティは【表2】に示された4つのみ。
- “入室許可” に対して「社員が1件しか許可を持たない」と思い込み1対1を書く。許可期間が変われば別行となるため多側。
FAQ
Q: “入室許可” に日付列があるのに多対多ではないのですか?
A: 多対多かどうかは列の種類ではなく外部キーの組合せで判定します。“入室許可” は “社員ID” と “室ID” を借り持つ1対多の子エンティティです。
A: 多対多かどうかは列の種類ではなく外部キーの組合せで判定します。“入室許可” は “社員ID” と “室ID” を借り持つ1対多の子エンティティです。
Q: “入退室ログ” と “入室許可” を結ぶ線が無いのはなぜ?
A: “入退室ログ” には “入室許可” の主キー列(許可開始年月日など)が含まれておらず直接参照しません。アプリケーションから SQL で照合しているだけなので E-R図上のリレーションシップは不要です。
A: “入退室ログ” には “入室許可” の主キー列(許可開始年月日など)が含まれておらず直接参照しません。アプリケーションから SQL で照合しているだけなので E-R図上のリレーションシップは不要です。
Q: ビュー表でも外部キーは考えるべき?
A: ビューは論理的な参照専用オブジェクトです。E-R図では実表と同様にエンティティとして扱いますが、物理的制約(外部キー制約など)は設定できません。今回は論理関係のみを示しています。
A: ビューは論理的な参照専用オブジェクトです。E-R図では実表と同様にエンティティとして扱いますが、物理的制約(外部キー制約など)は設定できません。今回は論理関係のみを示しています。
関連キーワード: E-R図、1対多リレーション、外部キー、ビュー表
設問2:
表2に示した実表“入室許可"における、主キーを答えよ。
模範解答
社員ID, 室ID, 入室許可開始年月日
解説
解答の論理構成
- 主キーは「表の行を一意に識別する列(組)」である
- 【問題文】の「表2 入室管理システムで利用する主な表」で実表 “入室許可” の列は
・社員ID
・室ID
・入室許可開始年月日
・入室許可終了年月日 - 【問題文】のユースケース “入室許可登録” には
「既に実表 “入室許可” に同じ社員ID、室ID、入室許可開始年月日の行が存在する場合は、入室許可終了年月日を更新する。」
と記載されている - すでに行があるか否かの判定条件が「社員ID」+「室ID」+「入室許可開始年月日」の3項目だけで行われている
- したがって、この3項目の組が唯一性を担保しており、主キーに採用される
結論:主キーは「社員ID, 室ID, 入室許可開始年月日」です。
誤りやすいポイント
- 「入室許可終了年月日」まで含めた4列を主キーと誤認する
→ 更新対象行の検索条件に使われていない点に注意 - 一意制約の根拠を表構造だけで判断し、ユースケース(業務ルール)を見落とす
- 「社員ID」のみを主キーにしてしまい、同一社員が複数室へ入室許可を持つケースを想定し忘れる
FAQ
Q: 「入室許可終了年月日」を主キーに含めないと日付範囲が重複しませんか?
A: 重複有無はアプリケーションや別の制約で管理できます。主キーは行識別用であり、ユースケースが示すように識別に必要なのは3列です。
A: 重複有無はアプリケーションや別の制約で管理できます。主キーは行識別用であり、ユースケースが示すように識別に必要なのは3列です。
Q: なぜ「室ID」を外してはいけないのですか?
A: 同じ社員が複数の室に別々の期間で許可を持つ可能性があるため、「社員ID」だけでは一意になりません。
A: 同じ社員が複数の室に別々の期間で許可を持つ可能性があるため、「社員ID」だけでは一意になりません。
Q: 複合主キーを避けてサロゲートキー(連番)を設ける方法は適切ですか?
A: 実務では有効ですが、本設問は業務識別子ベースで主キーを設定しているので、問題の前提に従います。
A: 実務では有効ですが、本設問は業務識別子ベースで主キーを設定しているので、問題の前提に従います。
関連キーワード: 主キー、複合キー、一意制約、エンティティ、データモデリング
設問3:
図2中のaに入れる適切な字句を答えよ。
模範解答
a:COUNT(*)
解説
解答の論理構成
-
目的の確認
【問題文】には「表3のユースケース“入室”で、入室可否をチェックし、否の場合は0を、可の場合は1以上を返すSQL文を図2に示す。」とあります。求められているのは行数の有無であり、0 か 1 以上 の数値を返す集計結果です。 -
図2のSQL文の構造
図2では
sql SELECT a FROM ROOM.入室許可 WHERE 社員ID = :社員ID AND 室ID = :室ID AND 入室許可開始年月日 <= :今日 AND 入室許可終了年月日 >= :今日と示されています。WHERE 句で対象レコードを絞り込んだ後、SELECT 句で件数を取得すれば、存在しない場合 0、存在する場合 1 以上 を返せます。 -
集計関数の選定
文字列や日付をそのまま返すと入退室可否を判断できません。必要なのはレコード数なので、行数を返す集計関数 COUNT() が最適です。COUNT() は絞り込んだ結果セットの行数を返し、存在しない場合は 0、存在する場合は行数(少なくとも 1)になります。 -
結論
以上より a に入る字句は COUNT(*) となります。
誤りやすいポイント
- COUNT(列名) を用いると、列に NULL が含まれると正しい件数が返らない可能性があります。本問は行の有無を確認するだけなので COUNT(*) を選択します。
- SELECT 1 や EXISTS 句を思い浮かべる受験者もいますが、図2の構文(集計結果を直接返す形式)と「0 又は 1 以上を返す」という要件を満たすのは COUNT(*) です。
- SUM や MAX など他の集約関数を用いると、0/1 以外の値や想定外のNULLになる恐れがあり不適切です。
FAQ
Q: EXISTS 句を使えばもっと高速では?
A: 図2の形式が固定されているため、指定箇所 a には単一の式しか入れられません。EXISTS は SELECT 句に置けないため使用できません。
A: 図2の形式が固定されているため、指定箇所 a には単一の式しか入れられません。EXISTS は SELECT 句に置けないため使用できません。
Q: COUNT(社員ID) と COUNT() の違いは?
A: COUNT(社員ID) は列が NULL の行をカウントしません。行の有無を確実に判定する目的には COUNT() が安全です。
A: COUNT(社員ID) は列が NULL の行をカウントしません。行の有無を確実に判定する目的には COUNT() が安全です。
Q: なぜ 1 以上 とだけ書かれているのに 1 に限定しないの?
A: 同一社員が複数期間にわたり重複登録されている場合など、理論上複数行ヒットする可能性があります。そのため「1 以上」と表現されています。
A: 同一社員が複数期間にわたり重複登録されている場合など、理論上複数行ヒットする可能性があります。そのため「1 以上」と表現されています。
関連キーワード: COUNT関数、行数取得、集約関数、SQL埋込み変数、レコード存在確認
設問4:ビュー表“入室管理用社員”について、(1)、(2)に答えよ。
(1)図4中のb〜eに入れる適切な字句を答えよ。なお、表は“スキーマ名.表名”で表記すること。
模範解答
b:GRANT
c:SELECT
d:HR.入室管理用社員
e:ROOM_AP
解説
解答の論理構成
-
ビュー表を「参照だけできるように」する
問題文では、 “このビュー表を入室管理システムのAPが参照だけできるように権限を付与する”
と記載されています。参照=SELECT 権限を付与することだと分かります。 -
権限付与は GRANT 句を用いる
RDBMS の標準 SQL では、権限付与は GRANT 構文を使用します。
したがって b には GRANT が入ります。 -
付与する権限は SELECT
参照のみを許可するため、INSERT や UPDATE ではなく SELECT を指定します。
よって c には SELECT が入ります。 -
権限の対象オブジェクト
ビュー表は “スキーマ名.表名” で表記するという指示があり、対象となるビューは
“HR.入室管理用社員” です。したがって d には HR.入室管理用社員 が入ります。 -
権限を受け取るユーザ
表4より、入室管理システムの AP 用ユーザ名は “ROOM_AP” と明示されています。
そのため e には ROOM_AP が入ります。 -
以上を順に並べると
GRANT SELECT ON HR.入室管理用社員 TO ROOM_AP
となり、模範解答と合致します。
誤りやすいポイント
- SELECT 権限だけで良いところを、誤って ALL を付与してしまう。これでは「参照だけ」という要件を満たしません。
- ビュー表名の前にスキーマ名を付け忘れる。異なるスキーマ間で操作する場合、完全修飾名を省くと実行時に “表が見つからない” エラーが発生します。
- 権限の付与先として DBA 用ユーザ “ROOM_DBA” を書いてしまうケース。AP が実際に接続するのは “ROOM_AP” です。
FAQ
Q: ビュー表にアクセスする際、基になる実表への権限も必要ですか?
A: 問題文の仕様(2)に“ビュー表にアクセスする場合、そのビュー表が参照する表のアクセス権限は不要である”とあるとおり、ビュー単体への権限だけで参照できます。
A: 問題文の仕様(2)に“ビュー表にアクセスする場合、そのビュー表が参照する表のアクセス権限は不要である”とあるとおり、ビュー単体への権限だけで参照できます。
Q: GRANT SELECT ON ... を発行できるのは誰ですか?
A: 表(またはビュー)所有者である DBA、ここでは “HR_DBA” が発行します。“ROOM_DBA” や “ROOM_AP” には他スキーマのオブジェクトに対する権限付与はできません。
A: 表(またはビュー)所有者である DBA、ここでは “HR_DBA” が発行します。“ROOM_DBA” や “ROOM_AP” には他スキーマのオブジェクトに対する権限付与はできません。
Q: 将来 UPDATE も許可したい場合はどうすればよいですか?
A: GRANT SELECT, UPDATE ON HR.入室管理用社員 TO ROOM_AP のように複数権限をカンマ区切りで追加します。ただし要件変更時は最小権限の原則を再確認しましょう。
A: GRANT SELECT, UPDATE ON HR.入室管理用社員 TO ROOM_AP のように複数権限をカンマ区切りで追加します。ただし要件変更時は最小権限の原則を再確認しましょう。
関連キーワード: RDBMS権限管理、GRANT文、ビュー、スキーマ、アクセス制御
設問4:ビュー表“入室管理用社員”について、(1)、(2)に答えよ。
(2)ビュー表を参照する権限を付与するSQL文を実行するユーザ名を答えよ。
模範解答
HR_DBA
解説
解答の論理構成
-
ビュー表 “入室管理用社員” はスキーマ “HR” に属します。
――【問題文】「CREATE VIEW HR.入室管理用社員 …」
したがって、このビューの所有者は “HR” スキーマの DBA です。 -
各システムの DBA/AP ユーザは次のとおりです。
――【問題文】表4「人事システム」「スキーマ名 HR」「DBA用ユーザ名 HR_DBA」
所有者は “HR_DBA”、参照したい入室管理システムの AP ユーザは “ROOM_AP” です。 -
アクセス権限の付与は所有者だけが行える、という仕様があります。
――【問題文】(1)「表のデータに対して、所有者以外のユーザが参照…を行うためには…所有者から付与してもらう必要がある。」 -
したがって、ビュー表を参照する権限を付与する SQL 文(GRANT 文)を実行できるのは、所有者 “HR_DBA” です。
誤りやすいポイント
- GRANT 文の実行者を「付与される側(ROOM_AP)」と勘違いする。付与は所有者が行う点に注意。
- 「ビューだから所有者は不要」と早合点する。ビューも格納スキーマのオブジェクトであり、所有者権限が必要です。
- スキーマ名 “HR” を見落として “ROOM_DBA” と答えてしまうケース。スキーマとシステムをセットで確認することが大切です。
FAQ
Q: ビュー表の場合でも所有者が権限を付与する必要がありますか?
A: はい。【問題文】(1) の仕様はビューにも適用されます。
A: はい。【問題文】(1) の仕様はビューにも適用されます。
Q: AP ユーザが自分で GRANT 文を実行してはいけないのですか?
A: AP ユーザは所有者ではないので実行権限がありません。所有者 “HR_DBA” が代わりに実行します。
A: AP ユーザは所有者ではないので実行権限がありません。所有者 “HR_DBA” が代わりに実行します。
Q: DBA 以外にシステム管理者アカウントで付与しても良いですか?
A: 試験問題の前提では、表の所有者=各システムの DBA と定義されているため、想定される実行者は “HR_DBA” です。
A: 試験問題の前提では、表の所有者=各システムの DBA と定義されているため、想定される実行者は “HR_DBA” です。
関連キーワード: GRANT, 権限管理、スキーマ、ビュー、所有者
設問5:
図5中のfに入れる適切な式を答えよ。
模範解答
f:T1.所属組織ID = T3.組織ID AND T3.組織長の社員ID = T2.社員ID
解説
解答の論理構成
-
追加事項の確認
【問題文】には、ビュー表を修正した理由として
“管理者は、‘申請者が入室希望社員の組織長であること’を確認することになった。そのため、ビュー表“入室管理用社員”に組織長の氏名が必要となり”
とあります。したがって新しい列 “組織長氏名” は「組織長本人が ‘社員’ 表に登録している “氏名”」を取り出す必要があります。 -
参照すべき実表と列
表1の実表 “社員” には
“社員 ID、氏名、…、所属組織 ID”
があり、実表 “組織” には
“組織 ID、組織名、組織長の社員 ID”
が定義されています。
・入室希望社員(T1)は “所属組織 ID” を持つ
・その “所属組織 ID” が参照する実表 “組織” の主キーは “組織 ID”
・同じ “組織” 行には “組織長の社員 ID” が格納される
・組織長本人の “氏名” は再び実表 “社員” から取得できる -
結合パスの確定
上記より、(入室希望社員)と (組織)は
T1.所属組織ID = T3.組織ID
で結合。
次に、(組織)と (組織長)は
T3.組織長の社員ID = T2.社員ID
で結合。 -
式の完成
2つの結合条件を AND で連結すれば良いので、f には
T1.所属組織ID = T3.組織ID AND T3.組織長の社員ID = T2.社員ID
が入ります。
誤りやすいポイント
- “組織長の社員 ID” を直接 “所属組織 ID” に結合してしまう
→ 列同士の意味が異なり、論理的整合性を欠きます。 - “組織長氏名” を取得するためにサブクエリを使おうとする
→ 本問は単純な内部結合で十分です。 - 列名のタイポや別名の付与忘れ
→ 試験では “社員ID” と “社員 ID”、“組織長の社員 ID” のように空白の有無も区別されるので注意が必要です。
FAQ
Q: 自己結合ではなく 3 表結合にした理由は?
A: “組織長の社員 ID” は実表 “組織” にあり、組織長本人の “氏名” は実表 “社員” にあるため、間に “組織” 表を挟んだ 3 表結合が最小構成です。
A: “組織長の社員 ID” は実表 “組織” にあり、組織長本人の “氏名” は実表 “社員” にあるため、間に “組織” 表を挟んだ 3 表結合が最小構成です。
Q: ビュー表経由で参照するとき、基となる実表の権限は不要ですか?
A: 【問題文】“(2) ビュー表にアクセスする場合、そのビュー表が参照する表のアクセス権限は不要である。” とある通り、ビューに対する SELECT 権限さえあれば基表の権限は不要です。
A: 【問題文】“(2) ビュー表にアクセスする場合、そのビュー表が参照する表のアクセス権限は不要である。” とある通り、ビューに対する SELECT 権限さえあれば基表の権限は不要です。
Q: “組織長氏名” を取得するのに LEFT JOIN を使うべきですか?
A: 本問では入室希望社員には必ず所属組織が設定され、組織には必ず組織長が登録されている前提なので INNER JOIN(WHERE 句による等価結合)で問題ありません。
A: 本問では入室希望社員には必ず所属組織が設定され、組織には必ず組織長が登録されている前提なので INNER JOIN(WHERE 句による等価結合)で問題ありません。
関連キーワード: ビュー表、内部結合、自己結合、アクセス権限、射影


