ITパスポート 2020年 秋期 問57
問題文
次に示す項目を使って関係データベースで管理する“社員”表を設計する。他の項目から導出できる、冗長な項目はどれか。

選択肢
ア:生年月日
イ:現在の満年齢(正解)
ウ:住所
エ:趣味
🔒 解説は解答すると表示されます
冗長な項目はどれか【ITパスポート 解説】
正解の理由
この表で冗長(余分)な項目は イ(現在の満年齢)です。理由は「満年齢」は「生年月日」と「今日の日付」から常に計算して求められるため、別に表に保存する必要がないからです。
用語の補足:関係データベース(relational database:表形式でデータを管理する方式)では、他の項目から導出できる値をそのまま保存すると「データの不整合(更新漏れで値がずれる)」が起きやすくなります。導出可能な項目は「派生属性(derived attribute:ほかの属性から計算して得られる属性)」と呼ばれ、原則として保存せずに計算で扱うのが正しい設計です。
用語の補足:関係データベース(relational database:表形式でデータを管理する方式)では、他の項目から導出できる値をそのまま保存すると「データの不整合(更新漏れで値がずれる)」が起きやすくなります。導出可能な項目は「派生属性(derived attribute:ほかの属性から計算して得られる属性)」と呼ばれ、原則として保存せずに計算で扱うのが正しい設計です。
また、社員を一意に識別する「社員番号(主キー:primary key)」と、個人を特定する「生年月日」があれば、現在の満年齢はいつでも計算できます。したがって保存すると冗長になります。
解法ステップ
- 表の各列(属性)を見て、「他の列から必ず導けるもの」がないか探す。
- 「生年月日」と「現在の満年齢」を比べる。生年月日があれば年齢は日付差から計算できるので導出可能と判断。
- 導出できるなら冗長属性(削除してもデータの意味は保持できる)として選ぶ。
- 他の列(社員番号、社員名、住所、趣味)は外部情報や個別の値なので導出不可。よって冗長ではない。
選択肢別の誤答解説
-
ア: 生年月日
生年月日は年齢を導出する元データです。社員の生まれた日付は唯一の事実情報であり、他の列からは再現できません。したがって冗長ではありません。 -
イ: 現在の満年齢
ここが冗長です。生年月日と現在日付から計算できる「派生属性」です。保存すると日々変化するため、更新忘れによる不整合が起きやすいです(正解)。 -
ウ: 住所
住所は個人固有の情報で、他の列から自動的に導けません。住所変更が発生しても単独で意味を持つため冗長ではありません。 -
エ: 趣味
趣味も個人の属性であり、ほかの項目から導けないため冗長ではありません。
よくある誤解
-
「年齢はよく使う指標だから保存した方が速い」
→ 一時的な高速化のために保存すると、日付が変わるたびに更新が必要でミスを招きます。報告用のスナップショット以外は計算で対応する方が安全です。 -
「古い年齢の履歴が必要なら生年月日だけではダメだ」
→ 生年月日があれば任意の日付での年齢は算出できます。逆に、ある時点での“年齢そのもの”の履歴を残したい場合は、「スナップショット日(いつ計算したか)」と一緒に保存するべきです。 -
「システムの都合で二重に持たないといけない」
→ 業務要件が特になければ二重に持つのは避けるのが原則。どうしても保持する場合は更新ルールを厳格にして矛盾を防ぐ必要があります。
補足コラム
- データベース設計の基本に「正規化(normalization:データの冗長性を減らし整合性を保つ手法)」があります。今回のケースは「派生属性を表に保存しない」ことで正規化する典型例です。
- ただし業務要件で「ある日の年齢一覧」を保存しておく必要がある、または計算コストのためにキャッシュ(保存)する場合もあります。その場合は「いつの年齢か」を示す日時列を必ず持ち、更新ルールや再計算の仕組みを明確にしてください。
FAQ
Q1. 年齢は絶対に保存してはいけないですか?
A1. 絶対ではありません。だたし、保存する場合は「いつの年齢か(スナップショット日)」を明記し、更新タイミングや再計算の運用を決める必要があります。多くの場合は生年月日を保持して、表示時に計算するほうが安全です。
A1. 絶対ではありません。だたし、保存する場合は「いつの年齢か(スナップショット日)」を明記し、更新タイミングや再計算の運用を決める必要があります。多くの場合は生年月日を保持して、表示時に計算するほうが安全です。
Q2. 年齢の計算方法はどうすればいいですか?
A2. 基本は「年の差」から、誕生日がまだ来ていなければ1引く方法です。数学的には次のように表せます。
ここで は(現在の月日が誕生日より前なら)1、そうでなければ0です。実用例を以下に示します。
A2. 基本は「年の差」から、誕生日がまだ来ていなければ1引く方法です。数学的には次のように表せます。
ここで は(現在の月日が誕生日より前なら)1、そうでなければ0です。実用例を以下に示します。
コード例(Python):
from datetime import date
def calc_age(birth):
today = date.today()
age = today.year - birth.year
if (today.month, today.day) < (birth.month, birth.day):
age -= 1
return age
# 例: 生年月日 1990-07-15
import datetime
print(calc_age(datetime.date(1990,7,15)))
Q3. 「社員番号」は何のために必要ですか?
A3. 社員番号は「主キー(primary key:表の中で各行を一意に識別する値)」です。同姓同名でも社員番号があれば個人を区別できます。
A3. 社員番号は「主キー(primary key:表の中で各行を一意に識別する値)」です。同姓同名でも社員番号があれば個人を区別できます。
関連キーワード: 正規化、関係データベース、冗長性、派生属性、主キー、生年月日、年齢

\ せっかくなら /
ITパスポートを
クイズ形式で学習しませんか?
クイズ画面へ遷移する→
すぐに利用可能!

