基本情報技術者試験問題に挑戦しよう!「関係モデル」をPython+SQLiteでつくって学ぶ【GitHub対応】

基本情報技術者試験

基本情報技術者試験とは

基本情報技術者試験は、情報処理推進機構(IPA)が実施し、「情報処理の促進に関する法律」に基づき経済産業省が認定する国家試験である。

ITエンジニアとしてキャリアをスタートする方のIT基礎力を問う試験で、「ITエンジニアの登竜門」とも呼ばれる。

「基本情報技術者試験」の試験範囲は、IPAのWebサイトに掲載されているシラバスに明記されている。


それでは、基本情報技術者試験(科目A)のサンプル問題にチャレンジしてみよう。

問24 関係モデルにおいて表X から表Y を得る関係演算はどれか。

ア 結合(join)        イ 射影(projection)
ウ 選択(selection)      エ 併合(merge)

出典:基本情報技術者試験 科目A サンプル問題(2022年12月)

正解:イ

データベースとは

一定の規則に従って関連性のあるデータを蓄積したもの。

関係モデル

データの関係を集合論などの数学モデルで表現したもの。

関係データベース

行と列から構成される2次元の表で表現されるデータベースである。

データ操作

関係演算

関係演算は、関係データベースの表から目的のデータを取り出す演算である。以下のデータ操作ができる。

射影(projection) 表の中から特定の列を抽出する

選択(selection)  表の中から条件に合致した行を抽出する

結合(join) 二つ以上の表を結合して、一つの表を生成する

設問では列が抽出されているので、「射影」である。

ちなみに、「併合」という演算はない。


(以下追記:2026.9.23)
試験制度については、2027年度からの変更が予定されている。最新の試験情報はIPA公式サイトで確認しよう。

ここから実践編

さて、この3つの演算を、これからSQLiteとPythonで実際に試していこう。

なお、この記事で使用するコードは、学習用リポジトリ pc-labo-fe-exam-python の 05_kankei_model フォルダにまとめている。

(注意)以下の「SQLiteでテーブルを作る」から「結合をSQLで試す」までのコードは、1つのファイルに続けて書いていく前提の抜粋である。「SQLiteでテーブルを作る」で作った conn と cur を、そのあとのブロックでもそのまま使い続けるため、途中のブロックだけを単独でコピペして実行すると NameError になる。上から順につなげて実行するか、05_kankei_model/kankei_model.py(1本にまとまった完成版)をそのまま使ってほしい。

SQLiteでテーブルを作る

設問の表X(商品番号・商品名・価格・数量の4列)を、そのままSQLiteのテーブルとして作る。

import sqlite3

conn = sqlite3.connect(":memory:")  # ファイルを作らず、メモリ上にDBを作る
cur = conn.cursor()

cur.execute("""
CREATE TABLE 商品 (
    商品番号 TEXT PRIMARY KEY,
    商品名   TEXT NOT NULL,
    価格     INTEGER NOT NULL,
    数量     INTEGER NOT NULL
)
""")

sqlite3.connect(":memory:") とすると、ファイルを作らずにメモリ上だけでデータベースを試せる。学習用に何度も作り直す場合に便利である。
SQLiteはテーブル名・列名に日本語(商品、商品番号など)をそのまま使えるので、設問の表と同じ名前で作成している。

PythonからSQLiteに接続する

Pythonには sqlite3 モジュールが標準で組み込まれているため、追加のインストールなしでSQLiteを操作できる。sqlite3.connect() で接続を作り、cursor() でSQL文を実行するためのカーソルを取得する、という流れは、上のコードにすでに含まれている。

データを登録する

設問の表Xにある5行のデータを、executemany() でまとめて登録する。

cur.executemany(
    "INSERT INTO 商品 (商品番号, 商品名, 価格, 数量) VALUES (?, ?, ?, ?)",
    [
        ("A01", "カメラ",   13000, 20),
        ("A02", "テレビ",   58000, 15),
        ("B01", "冷蔵庫",   65000, 8),
        ("B05", "洗濯機",   48000, 10),
        ("B06", "乾燥機",   35000, 5),
    ],
)
conn.commit()

SQL文の中の ? は、あとに続くタプルの値をあてはめるプレースホルダーである。値を直接文字列に埋め込まず ? を使うことで、SQLインジェクションを防げる。

射影をSQLで試す

射影は「表の中から特定の列を抽出する」演算である。商品 テーブルから、商品番号と数量の列だけを取り出してみよう。

cur.execute("SELECT 商品番号, 数量 FROM 商品")
for row in cur.fetchall():
    print(row)

実行結果

('A01', 20)
('A02', 15)
('B01', 8)
('B05', 10)
('B06', 5)

この結果を見比べると、設問の表Yとまったく同じ内容になっていることが分かる。
SELECT 商品番号, 数量 FROM 商品 のように取り出す列を指定することで、表Xから表Yを得られる。
このようにSQLの SELECT で必要な列だけを指定すると、関係代数の射影に対応する操作を確認できる。

選択をSQLで試す

選択は「表の中から条件に合致した行を抽出する」演算である。価格が50,000円以上の商品だけを取り出してみよう。

cur.execute("SELECT * FROM 商品 WHERE 価格 >= 50000")
for row in cur.fetchall():
    print(row)

実行結果

('A02', 'テレビ', 58000, 15)
('B01', '冷蔵庫', 65000, 8)

WHERE 価格 >= 50000 という条件によって、5商品のうち、条件に合う2商品の行だけが取り出されている。列はすべて残っている点が、射影との違いである。

結合をSQLで試す

結合は「二つ以上の表を結合して、一つの表を生成する」演算である。設問には登場しないが、理解を深めるために、商品番号ごとの仕入先を管理する 仕入先 テーブルを追加で用意し、商品 テーブルと結合してみよう。

cur.execute("""
CREATE TABLE 仕入先 (
    商品番号 TEXT PRIMARY KEY,
    仕入先名 TEXT NOT NULL
)
""")
cur.executemany(
    "INSERT INTO 仕入先 (商品番号, 仕入先名) VALUES (?, ?)",
    [
        ("A01", "サンプル商会"),
        ("A02", "サンプル商会"),
        ("B01", "家電卸センター"),
        ("B05", "家電卸センター"),
        ("B06", "家電卸センター"),
    ],
)

cur.execute("""
SELECT 商品.商品名, 仕入先.仕入先名
FROM 商品
JOIN 仕入先 ON 商品.商品番号 = 仕入先.商品番号
""")
for row in cur.fetchall():
    print(row)

実行結果

('カメラ', 'サンプル商会')
('テレビ', 'サンプル商会')
('冷蔵庫', '家電卸センター')
('洗濯機', '家電卸センター')
('乾燥機', '家電卸センター')

商品 テーブルだけを見ても仕入先は分からないが、仕入先 テーブルと JOIN することで、2つの表にまたがる情報を1つの表として取り出せている。これが結合である。

基本情報の問題をもう一度解いてみる

ここまでで、射影・選択・結合をそれぞれSQLとPythonの実行結果として確認できた。3つの演算をあらためて比較すると、次のようになる。

演算何をするか今回のSQL
射影(projection)列を絞り込むSELECT 商品番号, 数量 FROM 商品
選択(selection)行を絞り込むSELECT * FROM 商品 WHERE 価格 >= 50000
結合(join)複数の表をつなげるSELECT ... FROM 商品 JOIN 仕入先 ON ...

「射影をSQLで試す」で実行した SELECT 商品番号, 数量 FROM 商品 の結果は、設問の表Yと完全に一致した。表Xから、商品番号と数量の列だけを絞り込んだものが表Y——これはまさに射影の定義そのものである。行数(5行)は変わらず、列だけが4列から2列に減っている点も、射影の特徴と一致している。したがって、正解はイ(射影)であることを、実際のSQL実行結果として確認できた。

まとめ

  • 関係演算には代表的なものとして「射影(列を絞る)」「選択(行を絞る)」「結合(表をつなげる)」の3種類があるが、「併合」という演算は存在しない
  • SQLiteとPythonの sqlite3 モジュールを使えば、追加のインストールなしでこれらの演算を手元で試せる
  • 実際にSQLを実行して結果を見比べることで、「列が絞られていれば射影」というような判断基準を、暗記ではなく体験として身につけられる

Python+SQLiteのコードを筆者のGitHubリポジトリで公開

この記事で扱ったコードは、以下の筆者のGitHubリポジトリで公開している。

GitHub – HappyTalk10/pc-labo-fe-exam-python
Contribute to HappyTalk10/pc-labo-fe-exam-python development by creating an account on GitHub.

コメント

タイトルとURLをコピーしました