データベーススペシャリスト試験 2021年 午後103


テーブルの移行及びSQL の設計に関する次の記述を読んで、 設問1,2に答えよ。

 A社は,不動産賃貸仲介業を全国規模で行っている。 RDBMS を用いて物件情報検索システム(以下, 検索システムという)を運用している運用部門のKさんは,物件情報を検索する SQL文を設計している。  
〔検索システムの概要〕  検索システムは,物件を管理するシステムを補完するシステムであり, 社内利用者が接客するとき,当該システムの “物件” テーブルを利用している。
1.社内利用者の接客業務の概要  (1) 物件を探している借主に対して,当該借主の希望に近い物件を探す支援を行い, 借主と貸主との間の交渉 賃貸契約の仲介を行う。  (2) 物件の貸主に対して, 物件の審査を行う。 当該貸主に長期の空き物件がある場合、周辺の競合物件の付帯設備 (以下, 設備という) の設置状況を調査し,当該空き物件に人気の設備を増強することなど, 物件の付加価値を高める対策の助言を行うこともある。
2.“物件” テーブル  (1) A社が仲介する全ての物件を, 物件コードで一意に識別する。  (2) 物件の沿線, 最寄駅, 賃料, 間取りなどの基本属性を記録する列がある。  (3) エアコン, オートロックなどの設備が設置されているかどうかの有無を記録する列があり,一つの物件に最大20個の設備の有無を記録できる。  (4) 記録されている 20 個の設備について,どの設備もいずれかの物件に設置されているが, 20個全ての設備が設置されている物件は限られている。  (5) 設備に流行があるので,テーブルの定義を変更し, 記録する人気の設備を毎年入れ替える処理を行っている。 この処理を物件設備の入替処理と呼んでいる。  (6) “物件” テーブルの全ての列に NOT NULL 制約を指定している。
3.“物件” テーブルのテーブル構造, 主な列の意味と制約及び主な統計情報  “物件” テーブルのテーブル構造を図1に, 主な列の意味 制約を表1に,RDBMS の機能を用いて取得した主な統計情報を表2に示す。
データベーススペシャリスト試験(令和3年 午後I 問3 図1)
データベーススペシャリスト試験(令和3年 午後I 問3 表1)
データベーススペシャリスト試験(令和3年 午後I 問3 表2)
4.検索システムの課題  Kさんは, 社内利用者に聞取り調査を行い、その結果を二つの課題にまとめた。  (1) “物件”テーブルの各設備の有無を示す列 (以下、総称して設備列という)の数は不十分で、 借主からの問合せに十分に対応できていない。 追加したい設備は,テレワーク対応, 宅配ボックス, 追い焚き風呂などがあり、現在の 20個を含め、全部で100個ある。 将来, 増える可能性がある。  (2) 設備の設置済個数が分からない。 例えば, 借主から物件に設置されているエアコンについて問合せがあったとき, 設置されている正確な個数が分からず,別の詳細な物件設備台帳を調べなければならない。  
〔物件の設備に関する調査及び課題への対応〕 1.物件の設備に関する調査  Kさんは,現在検索できる設備の組合せを述語に指定した SQL 文を調査した。その SQL 文の例を、 表3に示す。 そしてKさんは, SQL 文の結果行を保存するファイルの所要量を見積もる目的で, 表3の各SQL文の結果行数を見積もった。
データベーススペシャリスト試験(令和3年 午後I 問3 表3)
2.物件の設備に関する課題への対応  Kさんは,物件の設備に関する課題に対応するため、 次の 2案について長所及び短所を比較した結果, 案 B を採用することにした。
案A:“物件” テーブルにエアコン台数列を追加する。 案B:追加・変更するテーブルのテーブル構造を、 図2に示すとおりにする。  ・“設備” テーブルを追加する。図1に示した “物件” テーブルを “新物件” テーブルに置き換える。  ・“物件設備” テーブルを追加する。
データベーススペシャリスト試験(令和3年 午後I 問3 図2)
 設備コードは, 全設備を一意に識別するコードで, そのうち20個は, “物件” テーブルの各設備列に対応させた。 また, “設備” テーブルの設備名の列値に “物件” テーブルの設備列名をそのまま設定し, 今後追加される設備名を含めて重複させないことに決めた。
3.テーブルの移行   Kさんは,追加・変更するテーブルへの移行を,次のような手順で行った。
(1) “設備”, “新物件” 及び “物件設備” テーブルを定義した。 (2) “物件” テーブルから設備列 20個を除いた全行を, “新物件” テーブルに複写した。 (3) “設備” テーブルに100個の設備を登録した。 エアコン又はオートロックを登録する SQL文の例を, 表4の SQL4 に示す。 (4) “物件設備” テーブルには “物件” テーブルにある設備に限って行を登録した。 エアコン又はオートロックがある行を登録する SQL文の例を, 表4の SQL5に示す。 ここで, 設置済個数列に1を設定し, 正確な個数を移行後に設定することにした。 (5) テーブルの統計情報を取得した。 主な統計情報を表5に示す。
データベーススペシャリスト試験(令和3年 午後I 問3 表4)
データベーススペシャリスト試験(令和3年 午後I 問3 表5)
〔テーブルの移行の検証〕  Kさんは, テーブルの移行を次のように検証し、 新たなビューを定義した。
1.SQL 文の検証  テーブルの移行の前後で SQL文が同じ結果行を得るか検証するため,移行前のSQL 文 (表3のSQL1, SQL2) に対応する移行後の SQL文を, それぞれ表 6 のSQL6, SQL7のとおりに設計した。 そして, "1.物件の設備に関する調査” で保存したファイルを用いて, SQL1 と SQL6 の結果行, SQL2 と SQL7 の結果行がそれぞれ一致することを確認した。
データベーススペシャリスト試験(令和3年 午後I 問3 表6)
2.ビューの定義  Kさんは, “物件” テーブルの定義を削除した後でも実績のある SQL文を変更することなく使いたいと考えている。 そのために “物件” テーブルにあった沿線列,かつ,エアコン列とオートロック列の両方を表示するビュー “物件”を, 図3のとおりに定義した。
データベーススペシャリスト試験(令和3年 午後I 問3 図3)

テーブルの移行及びSQL の設計に関する次の記述を読んで、 設問1,2に答えよ。

設問1〔物件の設備に関する調査及び課題への対応〕について,(1)〜(4)に答えよ。

(1)表 3 中の(イ)、 (ロ)に入れる適切な数値を,(ハ)〜(ホ)に入れる適切な字句を答えよ。 ここで,沿線, エアコン, オートロックの列値の分布は互いに独立し,各列の列値は一様分布に従うと仮定すること。

模範解答

イ:1,000 ロ:3,000 ハ:COUNT(*) ニ:TOTAL ホ:沿線,TOTAL

解説

解答の論理構成

  1. 前提確認
    • “行数” 1,600,000、沿線の種類 400 → 1沿線当たり行数=
    • 各設備列は値 YN の2種類で一様 →
    • 列どうしは「互いに独立」。
  2. (イ)SQL1 の見積行数
    • 条件確率:沿線 = 指定線 かつ Y かつ Y
    • 行数=
  3. (ロ)SQL2 の見積行数
    • Y OR Y:
    • 全体確率:
    • 行数=
  4. (ハ)〜(ホ)SQL3 の集計句
    • 分子は「条件を満たす行数」→ COUNT(*)
    • 分母は WITH TEMP(TOTAL) で求めた全行数列→ TOTAL
    • GROUP BY には 沿線TOTAL の両方を指定する必要がある(TOTAL を選択句で使用するため)。

誤りやすいポイント

  • OR 条件を単純に と誤算しがち(重複部分の控除を忘れる)。
  • GROUP BY 沿線 のみとすると TOTAL が非集約列扱いでエラーになる。
  • 「一様分布=半数が Y」を忘れ、実務経験則で偏った分布を想定してしまう。

FAQ

Q: CROSS JOIN TEMP を使う理由は何ですか?
A: “TOTAL” を各行に付けておくことで、GROUP BY した後でも全件数を分母にできるからです。サブクエリで毎回 COUNT するよりシンプルかつパフォーマンスが安定します。
Q: GROUP BY 沿線,TOTAL の順序は重要ですか?
A: 順序は問いません。同じグループ化キーを指定していれば結果は同じです。重要なのは TOTAL を含めることです。

関連キーワード: 一様分布, 独立事象, 条件付き確率, GROUP BY, 集約関数

設問1〔物件の設備に関する調査及び課題への対応〕について,(1)〜(4)に答えよ。

(2)“2. 物件の設備に関する課題への対応” について, K さんが採用した案Bの長所を一つ, 本文中の用語を用いて, 25字以内で具体的に述べよ。

模範解答

・物件設備の入替処理が不要である。 ・全設備の有無と個数の問合せに答えられる。 ・将来,増える設備に対して追加で対応できる。

解説

解答の論理構成

  1. 現行方式の課題
    • 【問題文】「(5) 設備に流行があるので,テーブルの定義を変更し, 記録する人気の設備を毎年入れ替える処理」を実施しており、列の増減作業が発生。
  2. 案Bの構造
    • 図2では“設備”と“物件設備”を追加。設備は行で増やすため列変更不要。
  3. 結果
    • 行追加だけで設備の増減を吸収でき、列を削除・追加する「物件設備の入替処理」が不要となる。
    • よって長所は「物件設備の入替処理が不要である」と言える。

誤りやすいポイント

  • 「全設備の有無と個数が分かる」を答えると列幅問題の改善という別の観点になるため、入替処理の不要化を明示しないと減点されやすいです。
  • 「正規化できる」「可変長に対応」など抽象表現のみで本文中の用語「物件設備の入替処理」を使わないと失点します。
  • 25字以内という制約を意識しすぎて主語やキーワードを削り過ぎると、具体性不足で評価が下がります。

FAQ

Q: 入替処理が不要になる理由を一言で説明すると?
A: 列でなく行として設備を管理するので、追加時はINSERTだけで済むからです。
Q: 案Aでも列追加で個数管理はできないのか?
A: 案Aは列を追加するたびにスキーマ変更が発生するため、頻繁な設備入替には不向きです。
Q: 正規化の段階で言えば案Bは第何正規形?
A: “物件設備”で多値属性を分離しているため第3正規形を満たしています。

関連キーワード: 正規化, 多値属性, スキーマ変更, マスタ管理

設問1〔物件の設備に関する調査及び課題への対応〕について,(1)〜(4)に答えよ。

(3)表 4 中の(a), (c)及び(d)に入れる適切な字句を(b), (e)に入れる一つの適切な述語を答えよ。(a, bは順不同、d, eは順不同)

模範解答

a:物件コード,'A1',1 b:エアコン='Y' c:UNION ALL d:物件コード, 'A2', 1 e:オートロック='Y'

解説

解答の論理構成

  1. 列順・値の決定
    • 【問題文】「INSERT INTO 物件設備(物件コード, 設備コード, 設置済個数)」
      ⇒ 3列目に固定値「1」を入れる指示は「(4)…設置済個数列に1を設定し」と明示。
    • SQL4 で設備コードが登録されている例:
      INSERT INTO 設備 VALUES ('A1', 'エアコン')
      INSERT INTO 設備 VALUES ('A2', 'オートロック')
      ⇒ 設備コードは 'A1', 'A2' しかあり得ない。
    • 以上から (a) と (d) は「物件コード,'A1',1」と「物件コード,'A2',1」。
  2. 抽出条件の決定
    • 【問題文】「…エアコン又はオートロックがある行を登録する SQL文の例を, 表4の SQL5に示す。」
      ⇒ WHERE 句は各列の値が 'Y' であることを判定するだけ。
    • 設備列名は エアコンオートロック で固定なので
      (b) は「エアコン='Y'」、(e) は「オートロック='Y'」。
  3. 2つの SELECT を連結する演算子
    • 行をまとめてインサートするため、重複検査を省きパフォーマンス重視の
      UNION ALL が最適(UNION だと重複チェックが走る)。
    • したがって (c) は「UNION ALL」。

誤りやすいポイント

  • UNION と UNION ALL の混同
    行数が巨大(【問題文】の表2で「1,600,000」行)なので重複チェックがかかる UNOIN は性能劣化の原因。
  • 設備コードの記号ミス
    SQL4 の 'A1', 'A2''a1', 'A01' などと書き換えると参照整合性違反。
  • 列順の取り違え
    INSERT 対象列を明示していても VALUES/SELECT 側が「設備コード, 物件コード…」の順になると挿入失敗。

FAQ

Q: 設置済個数を後で更新するなら最初は NULL にしても良いのでは?
A: 【問題文】「(6)“物件” テーブルの全ての列に NOT NULL 制約を指定している。」と同様に、移行先も NOT NULL の想定です。そこで暫定値として 1 を入れ、その後正しい値へ更新する方が簡便です。
Q: (c) を UNION にしてはいけませんか?
A: 技術的には可能ですが、UNION は重複行を排除するためにソートやハッシュ処理を行います。1,600,000 行規模ではコストが高くなるため、重複が決して起こらない今回のケースでは UNION ALL が推奨されます。
Q: WHERE 句に (エアコン='Y' OR オートロック='Y') とまとめて1本で登録する方法は?
A: 物件ごとに設備を別レコードに分けたい要件(正規化)と、設備コードを挿入時に固定したい要件が両立しにくく、結局 CASE 文や JOIN が必要になります。SELECT を分けて UNION ALL する方がシンプルです。

関連キーワード: 正規化, UNION ALL, 挿入パフォーマンス, WHERE 句, 外部キー

設問1〔物件の設備に関する調査及び課題への対応〕について,(1)〜(4)に答えよ。

(4)表5中の (あ)、(い) に入れる適切な数値を答えよ。

模範解答

あ:1,600,000 い:20

解説

解答の論理構成

  1. “新物件”側の行数確認
    【問題文】表2
    「行数 1,600,000」を持つ“物件”テーブルが手順(2)でそのまま“新物件”に複写された。したがって物件コードは“新物件”でも“物件設備”でも最大1,600,000件になる。
  2. “物件設備”への登録条件
    手順(4)
    「“物件”テーブルにある設備に限って行を登録した」とあり、SQL5 でも WHERE エアコン = 'Y' など Y 行だけを INSERT している。
    さらに【問題文】3.(4)
    「どの設備もいずれかの物件に設置されている」と書かれている。これにより 20設備のいずれかは必ず各物件に存在すると解釈でき、結果として物件コードは全件現れる。
    ⇒ (あ)=「1,600,000」
  3. 設備コードの種類
    手順(3) で 100種類の設備コードを“設備”に登録したが、手順(4) では「20個は“物件”テーブルの各設備列に対応させた」と限定している。移行時に登録対象はこの20種類のみ。
    ⇒ (い)=「20」
  4. 以上より表5の空欄は
    (あ)1,600,000、(い)20 となる。

誤りやすいポイント

  • 「100種類登録したのだから設備コードは100」と思い込む
    手順(4)は“20個に限って行を登録”と明記。
  • 「全物件に設備があるとは限らない」と考え列値個数を小さくする
    【問題文】3.(4)から「どの設備もいずれかの物件に設置」→20設備のどれかは必ず存在する、という前提を取りこぼしがち。
  • 行数と列値個数の混同
    表5が求めているのは distinct 個数であり、登録行数そのものではない点を見落としやすい。

FAQ

Q: 100種類分の設備コードをすべて物件設備に入れなかったのはなぜですか?
A: 手順(4)の目的は旧“物件”テーブルの20列を正しく正規化することです。まずは既存データだけを移行し、残り80種類は新規物件登録時に利用する想定だからです。
Q: もし一つも設備を持たない物件が存在した場合、(あ)はどうなりますか?
A: その場合は当該物件の物件コードが“物件設備”に現れなくなるため、(あ)は1,600,000より小さくなります。本設問は「どの設備もいずれかの物件に設置されている」という文脈上、全物件に少なくとも1設備があると読み取り 1,600,000 と判断します。

関連キーワード: 正規化, 主キー, DISTINCT, INSERT-SELECT, 統計情報

設問2〔テーブルの移行の検証〕について,(1)〜(3)に答えよ。

(1)表 6中の(f)〜(j)に入れる適切な字句を答えよ。(h, iは順不同)

模範解答

f:INNER JOIN g:INNER JOIN h:・S1.設備名='エアコン'   ・S1.設備コード='A1' i:・S2.設備名='オートロック'   ・S2.設備コード='A2' j:・(S.設備名='エアコン' OR S.設備名='オートロック')   ・(S.設備コード='A1' OR S.設備コード='A2')

解説

解答の論理構成

  1. 旧 SQL の要件確認
    • SQL1 は「沿線 = '○△線'」かつ「エアコン = 'Y' AND オートロック = 'Y'」を満たす行を取得。
  2. 新スキーマへの写像
    • “新物件” で「沿線 = '○△線'」を判定。
    • “物件設備” は物件と設備の多対多を表すため、同じ物件に対して “エアコン” と “オートロック” の 2 行が必ず存在する必要がある。
  3. 2行の存在を保証するための結合方法
    • 1物件に対し2レコードを必須としたい=結合に漏れがあってはいけない ⇒ INNER JOIN
    • よって (f)(g) ともに INNER JOIN
  4. 設備を特定する述語
    • 手順(3) で INSERT INTO 設備 VALUES ('A1', 'エアコン')('A2', 'オートロック') と登録している。
    • 同じ行は「設備名」でも「設備コード」でも一意に指せるので、(h)(i)(j) いずれも名称/コードのいずれか、あるいは両方を組み合わせた句が正答。
  5. OR/AND の違い
    • SQL6 は2回結合して AND 条件、SQL7 は1回結合後に OR 条件でフィルタ。

誤りやすいポイント

  • LEFT JOIN を選ぶと「どちらかが欠けていても行が残る」ため SQL1 の意味を満たさない。
  • (h)(i) で =IN の使い分けを間違え、冗長なサブクエリを作ってしまう。
  • SQL7 で DISTINCT を忘れると「エアコンとオートロック両方ある物件」が2行重複して返る可能性を見落とす。

FAQ

Q: 名称とコードのどちらで検索すべきですか?
A: 手順(3) で「設備名」の一意性を保証しているため、どちらでも正しく機能します。パフォーマンス面ではインデックスの有無に依存します。
Q: なぜ SQL6 は結合を2回書くのですか?
A: 「両方の設備が同一物件に存在する」ことを保証するには、同じ物件コードで2つの異なる設備コードを持つ行を同時に満たす必要があるためです。
Q: OR 条件を使って1回の結合で AND 要件を表せませんか?
A: 1回結合+OR では「いずれか一方がある物件」しか判定できません。AND 要件を OR 句のみで表すことはできません。

関連キーワード: INNER JOIN, 多対多リレーション, 正規化, SQL述語, 等価結合

設問2〔テーブルの移行の検証〕について,(1)〜(3)に答えよ。

(2)表6中の SQL7の選択リストにある DISTINCT の目的は、結果行の重複を排除するためである。 この SQL7で行が重複するのはどのような場合か。 本文中の用語を用いて, 30字以内で具体的に述べよ。

模範解答

エアコンとオートロックの両方が設置されている場合

解説

解答の論理構成

  1. 【問題文】表6の SQL7
    SELECT DISTINCT B.物件コード, B.物件名 ...
    とあり、DISTINCT で重複除去しています。
  2. 同じ表6で 物件設備 BS を JOIN し、さらに 設備 S(j) 条件を付与。
    (j) は「設備名が 'エアコン' 又は 'オートロック'」を意味します。
  3. 物件に
    • エアコンだけ → 1 行
    • オートロックだけ → 1 行
    • エアコンとオートロック両方 → 2 行
      のようにヒット数が異なります。
  4. 両方がある場合、同じ 物件コード2 回返るので重複し、DISTINCT が必要となります。
  5. したがって設問の「行が重複する場合」は「エアコンとオートロックの両方が設置されている場合」となります。

誤りやすいポイント

  • 「沿線が同じ物件が多いから重複」と勘違いする
    → 重複源は設備の二重ヒットです。
  • LEFT JOININNER JOIN の違いに気を取られ、本質を見落とす
    → JOIN 種別ではなく 同じ物件が複数行マッチするかどうかが鍵。
  • 別名 BSS の結合条件を読み飛ばし、DISTINCT を不要と判断する。

FAQ

Q: DISTINCT を外し GROUP BY 物件コード, 物件名 にしても良いですか?
A: 技術的には可能ですが、DISTINCT の方がシンプルでパフォーマンスも同等か上回る場合が多いです。
Q: 物件に 3 種類以上の設備を検索条件にしたら重複行は増えますか?
A: はい。OR 条件で指定する設備数が増えるほど、複数設備を持つ物件は重複ヒットし、DISTINCT がより重要になります。

関連キーワード: DISTINCT, INNER JOIN, 重複行, OR 条件, 正規化

設問2〔テーブルの移行の検証〕について,(1)〜(3)に答えよ。

(3)図3中の(k)〜(o)に入れる適切な字句を答えよ。

模範解答

k:・BS1.設備コード='A1'  ・BS1.設備コード IS NOT NULL l:'Y' m:'N' n:LEFT OUTER JOIN o:BS1.設備コード='A1'

解説

解答の論理構成

  1. “エアコン” の識別
    • 【問題文】の SQL4 に「('A1', 'エアコン')」とあるため,'A1' が “エアコン” を示す設備コードと確定。
  2. ビューで返したい値
    • ビュー“物件”は旧 “物件” テーブルと同じ列を提供する目的で定義されている(本文「実績のある SQL文を変更することなく使いたい」)。
    • 旧テーブルでは “エアコン” 列に Y/N が必ず格納されていた(NOT NULL 制約あり)。
  3. 外部結合を選択
    • ある物件に “エアコン” 情報が存在しない場合でも,行自体は返し N を表示する必要があるため,新物件 を基点に LEFT OUTER JOIN を用いる。
  4. CASE 式の判定
    • JOIN して一致する設備コードがあるとき BS1.設備コード は非 NULL,無いとき NULL。
    • よって (k) には「BS1.設備コード='A1'」という一致条件と,「BS1.設備コード IS NOT NULL」を OR で併記すれば十分。
    • 一致していれば (l)'Y',そうでなければ (m)'N'
  5. 他設備への適用
    • “オートロック” についても,同様に 'A2' を使い,JOIN はすべて LEFT OUTER JOIN で統一する。
  6. 以上より,(k)〜(o) の具体値を導出。

誤りやすいポイント

  • INNER JOIN を使うと設備が無い物件が消え,NULL→'N' の置換ができなくなる。
  • CASE 式の条件を BS1.設備コード='A1' だけにすると,外部結合で NULL が来たときに WHEN が偽になり ELSE へ落ちるため見かけ上問題ないが,可読性・要件(有無判定と一致条件の両立)を満たさないと採点で減点される危険。
  • IS NOT NULL を忘れて CASE WHEN BS1.設備コード='A1' THEN 'Y' … と書くと,“A1 以外の設備コードを誤って結合した場合” にも 'N' となり不正確。

FAQ

Q: INNER JOIN ではなく LEFT OUTER JOIN を選ぶ決め手は何ですか?
A: “新物件” 側に行が存在しても対応する設備が未登録のケースで,ビューが N を返してほしいからです。INNER JOIN だと該当物件行が消えてしまいます。
Q: CASE 式で BS1.設備コード IS NOT NULL を条件に入れるのは冗長では?
A: 'A1' 以外の設備を誤って JOIN した場合にも 'Y' と判定されないよう二重チェックを入れています。可読性と安全性の観点で必須です。
Q: 'Y''N' をハードコーディングする理由は?
A: 旧 “物件” テーブルが文字列で Y/N を保持していたと【問題文】表1に明確に規定されており,同一インタフェースを維持するためです。

関連キーワード: OUTER JOIN, CASE式, NULL判定, ビュー, 正規化
← 前の問題へ次の問題へ →

©︎2025 情報処理技術者試験対策アプリ