データベーススペシャリスト 2010年 午前2 問04
問題文
関係データベース上に実装するエンティティの主キーが複合キーであり、複合キーを構成している属性数が多すぎるので、少なくして扱いやすくしたい。この場合の対応として、適切なものはどれか。
選択肢
ア:複合キーを構成している属性のうち、エンティティの性格を最もよく表している属性を主キーとし、残りの属性を外部キーにする。
イ:複合キーを構成している属性のうち、エンティティの性格を最もよく表している属性を主キーとし、残りの属性を代理キー (alternate key)にする。
ウ:複合キーを連番など代用のキー (surrogate key)に置き換え、複合キーを構成している属性を外部キーにする。
エ:複合キーを連番など代用のキー(surrogate key)に置き換え、複合キーを構成している属性を代理キー (alternate key) にする。(正解)
🔒 解説は解答すると表示されます
サロゲートキー導入【午前2解説】
正解の理由
複合主キーが扱いにくい場合、最も実用的で安全なのは複合キーを連番やUUIDなどのシステム生成キー(サロゲートキー/代用キー)に置き換え、元の複合属性群には一意制約(オルタネートキー/候補キー)を残す方法です。これにより、行識別は単純な単一列の主キーで行い、同時に業務上の一意性(複合条件での重複禁止)も保持できます。選択肢の中では、複合キーをサロゲートキーに置き換え、複合属性をオルタネートキーとして残す エ がこの方針を正しく表しています。
解法ステップ
- 「単一属性を主キーにする(ア・イ)」が成立するか検討:その属性だけで一意性が保証されるかを確認する。多くの場合は保証されないため不適。
- 「サロゲートキーに置き換える(ウ・エ)」のうち、元の複合属性の扱いを確認:一意性を残すべきかどうか。単に外部キーにする(ウ)と一意性が失われるため不適。
- 一意性を保持しつつ主キーを簡潔にする手法は、サロゲートキーをPKにして元の複合属性にユニーク制約を付ける(エ)。よってこれを選ぶ。
選択肢別の誤答解説
- ア: 「残りを外部キーにする」とあるが、外部キー(foreign key)は別テーブルの主キー参照に使うもので、自テーブル内の属性群を外部キーにするのは意味が合いません。さらに一意性が保証されず誤り。
- イ: 「残りをオルタネートキーにする」と読めるが、この選択肢は「複合キーのうち1つの属性を主キーにする」ことを前提としている。単一属性がそもそも一意を保てるなら可能だが、問題の前提は「属性数が多すぎる」=単一属性で十分に識別できないケースが多い。重要な点として、オルタネートキー(alternate key)は「候補キーのうち選ばれなかった一意キー」を指し、候補キーであれば主キーに選ぶことも可能である。したがって「オルタネートキーは主キーの代替にはならない」と単純に否定するのは誤りで、用語を正確に区別して判断する必要があります。
- ウ: 「複合キーをサロゲートキーに置き換え、複合属性を外部キーにする」は不適切。元の複合属性は通常同じレコード内の属性であり、それらを外部キー(他テーブル参照)に変える意味がない。一意性も喪失する可能性が高い。
- エ: 「複合キーをサロゲートキーに置き換え、複合属性をオルタネートキーにする」は、主キーを簡潔にしても業務上必要な一意性を維持するための正しい設計であり、運用・パフォーマンス・整合性の観点で最も適切です。
よくある誤解
- 「オルタネートキーは主キーと別物で主キーになれない」:誤解です。オルタネートキーとは候補キー(candidate key)で、主キーに選ばれなかったものを指します。候補キーなら主キーに選べますし、逆に主キーにしない場合は一意制約(ユニーク)として残すことが一般的です。
- 「サロゲートキーを導入すると業務的意味が消えて全てダメになる」:サロゲートキーは識別を簡潔にするための手段です。業務的意味を持つ属性はオルタネートキーや追加カラムで保持し、必要なら参照用にインデックスやユニーク制約を付けて管理します。
- 「複合キーを外部キーにすれば参照は保たれる」:外部キーは参照関係を表すためのものであり、単に複合属性を外部キーに設定するのは設計意図を誤る可能性があります。参照元・参照先の関係を正しく設計することが重要です。
補足コラム
実務での移行手順(概略)とSQL例:
- テーブルにサロゲートキー列を追加(SERIAL/IDENTITYやUUID)。
- サロゲートキーを主キーに設定。
- 元の複合属性に対してユニーク制約を追加(オルタネートキーとして保持)。
- 子テーブルが元の複合キーで参照している場合は、子テーブルにサロゲートキー参照列を追加してデータ移行し、外部キー定義を更新する。
SQL例(PostgreSQL風):
-- 1. サロゲートキー追加
ALTER TABLE orders ADD COLUMN orders_id BIGSERIAL;
-- 2. 主キー変更(既存のPKを削除した上で)
ALTER TABLE orders DROP CONSTRAINT orders_pkey;
ALTER TABLE orders ADD PRIMARY KEY (orders_id);
-- 3. 元の複合属性にユニーク制約を追加
ALTER TABLE orders ADD CONSTRAINT orders_unique_business UNIQUE (cust_id, order_date, item_code);
-- 4. 子テーブル移行の一例(簡略)
ALTER TABLE order_lines ADD COLUMN orders_id BIGINT;
UPDATE order_lines ol
SET orders_id = o.orders_id
FROM orders o
WHERE ol.cust_id = o.cust_id AND ol.order_date = o.order_date AND ol.item_code = o.item_code;
ALTER TABLE order_lines ADD CONSTRAINT fk_orderlines_orders FOREIGN KEY (orders_id) REFERENCES orders(orders_id);
注意: 実際の移行ではトランザクション、整合性チェック、ダウンタイム計画が必要です。
FAQ
Q. いつサロゲートキーを導入すべきですか?
A. 複合キーが長くてインデックスやJOINが非効率、もしくは変更される可能性がある場合に検討します。ただし業務で意味ある識別子は別カラムで残し、ユニーク制約を設けることが前提です。
A. 複合キーが長くてインデックスやJOINが非効率、もしくは変更される可能性がある場合に検討します。ただし業務で意味ある識別子は別カラムで残し、ユニーク制約を設けることが前提です。
Q. オルタネートキーは必ずユニーク制約を付けるべきですか?
A. 業務上その組合せでの一意性が必要なら必ず付けます。ユニーク制約を付けなければ、サロゲートキー導入後に重複が許されてしまうことがあります。
A. 業務上その組合せでの一意性が必要なら必ず付けます。ユニーク制約を付けなければ、サロゲートキー導入後に重複が許されてしまうことがあります。
Q. 子テーブルが多数ある場合の注意点は?
A. 参照整合性の移行が手間になります。既存の外部キーをサロゲートキーに置換する必要があるため、移行スクリプトと段階的な切替を検討してください。
A. 参照整合性の移行が手間になります。既存の外部キーをサロゲートキーに置換する必要があるため、移行スクリプトと段階的な切替を検討してください。
関連キーワード: 主キー、サロゲートキー(代用キー)、オルタネートキー(候補キー・一意キー)、複合キー、外部キー、ユニーク制約、正規化、データ移行

\ せっかくなら /
データベーススペシャリストを
クイズ形式で学習しませんか?
クイズ画面へ遷移する→
すぐに利用可能!

