こんにちは、数強塾代表の藤原進之介です。この記事は参考書『藤原進之介の最強120講義』の第118講「データベース設計とSQL」のWeb版です。第6部「情報Ⅱへの橋」に置いた講で、共通テスト「情報Ⅰ」での重要度はC(情報Ⅱの内容であり、出題範囲外)です。
第90講で1枚の表を分ける理由を、第91講で選択・射影・結合という関係演算を扱いました。この講はその続きで、「分け方を手順にする」=正規化と、SQLという言語の話です。
結論
- 書かれた設計と、配られた教材が食い違っている。 学習指導要領解説は関係演算とデータベース操作言語(SQL)を情報Ⅱに置いたが、実際にSQL文を載せているのは情報Ⅰの教員研修用教材のほうで、情報Ⅱの教員研修用教材には
SELECTもWHEREも1度も出てこない。 - これは矛盾ではなく、目的の違いである。 分析はデータを一度メモリに載せて何十通りにも変形するので pandas が速く、共有と一貫性が問われる場面ではRDBとSQLが要る。目的が違えば道具が違う。
- 正規化は「操作」ではなく「設計」の話である。 第90講で見た3つの不整合を、第1〜第3正規形という手順に形式化したもの。ただしその手順を扱えと国が書いているのは専門学科の教科「情報科」の側であって、共通教科の情報Ⅱ側ではない。
なぜそうなるのか
1. まず、制度文書が何を情報Ⅱに置いたか
学習指導要領解説 情報編の、情報Ⅱ(3)「情報とデータサイエンス」ア(ア)に、この一文があります。
「データベースの管理や操作を行うプログラミング言語」が指しているのはSQLです。情報Ⅱの教員研修用教材 第3章 学習11 が「RDBを操作するためにはSQL(Structured Query Language)を使う」と自分で書いているので、ここは解釈の余地がありません。
つまり制度上の役割分担は明快です。情報Ⅰは表の構造を知る。情報Ⅱは関係演算を言語で書く。
2. ところが、配られた教材は逆を向いている
同じ語が①学習指導要領解説 情報編 ②情報Ⅰ教員研修用教材 ③情報Ⅱ教員研修用教材 で何回出てくるかを、全分冊を空白・改行を除去したうえで数えました(2026年8月3日、当方で実施。調べた範囲は最後の章に明記します)。
| 語 | 解説 (共通教科) |
解説 (専門教科) |
情報Ⅰ教材 | 情報Ⅱ教材 |
|---|---|---|---|---|
| SQL | 0 | 0 | 8 | 21 |
SELECT |
0 | 0 | 3 | 0 |
FROM |
0 | 0 | 4 | 0 |
WHERE |
0 | 0 | 2 | 0 |
INNER JOIN |
0 | 0 | 1 | 0 |
INSERT INTO |
0 | 0 | 1 | 0 |
DELETE |
0 | 0 | 1 | 0 |
セミコロン ; |
0 | 0 | 11 | 0 |
| pandas | 0 | 0 | 0 | 18 |
| データフレーム | 0 | 0 | 1 | 20 |
| RDB | 0 | 0 | 0 | 14 |
| NoSQL | 0 | 0 | 2 | 11 |
赤くした列がこの講の核心です。 情報Ⅰの教員研修用教材 第4章 学習21 には、動くSQL文が載っています。SELECT * FROM 書籍 WHERE 作者ID=1001; のように、セミコロンまで含めて11個の文が書かれている。
一方、情報Ⅱの教員研修用教材には、SQL文が1行も無い。 SELECT も FROM も WHERE も、セミコロンすら1つも出てきません。
「SQLが21件もあるではないか」と思うかもしれません。中身を1件ずつ見ると、こうなります。
- 13件は
NoSQLの一部(「NoSQL」「Not only SQL」という語の中のSQL) - 残り8件も、言語の名前としての言及です。「RDBを操作するためにはSQLを使う」「SQLにはMySQLやSQLiteなどの無料のものから有料のものまで様々」といった文で、MySQL・SQLiteという製品名の中のSQLも含まれています
3. 教材は、SQLの代わりに何を勧めているか
「これらの言語」とはRとPythonのことで、続く記述では pandas のデータフレームが主役になります。語数もそのとおりで、pandas 18件・データフレーム 20件に対し、SQL文は0行。学習12でも「リレーショナルデータベースのように二つのデータを結合したり,重複データを取り除いたりすることができる」と、pandasが関係演算の役をそのまま引き受けています。
制度文書が情報Ⅱに置いたSQLを、国の情報Ⅱ教材は名前だけ出して実物を見せていない。そして実物を見せているのは情報Ⅰの教材のほうです。
これは批判ではありません。読者がどちらを勉強すべきかの判断材料として書いています。結論を先に言えば——SQLを実際に書けるようになりたいなら、参照すべきは情報Ⅰの教員研修用教材 第4章 学習21 です。 情報Ⅱの教材を開いてもSQL文は出てきません。
4. なぜ pandas を勧めるのが妥当なのか
ここで「教材が手を抜いている」と読んではいけません。分析という目的においては、これは正しい判断です。
分析の作業とは、同じデータを何十通りにも変形して眺めることです。 平均を取り、絞り込み、外れ値を外し、別の切り口で集計し直し、グラフにしてみて、また戻る。この往復を1日に何十回もやる。
このとき、データがディスクの上のデータベースにあると、変形するたびに問い合わせを投げて、結果を受け取ることになります。往復のたびに、データベースは表を読み直す。一方、pandasはデータを最初に1回だけメモリに載せ、あとはその場で変形します。
この差は実測できます。 あとで詳しく示しますが、結果だけ先に書きます(明細20万行、同一マシンで3回測定。いずれも安定)。
| 場面 | SQL | pandas | 速いほう |
|---|---|---|---|
| A 1回だけ集計する | 0.07秒 | 0.14秒 | SQLが約1.9倍 |
| B 同じデータに20通りの集計 | 1.44〜1.50秒 | 0.14秒 | pandasが約10〜11倍 |
| C 20万行から1件取り出す(索引あり) | 0.0001秒 | 0.12秒 | SQLが約1,200倍 |
場面Bが「分析」です。教材が「ずっと簡単に高速に」と書いた根拠はここにあります。1回読み込めば、あとは何回変形しても読み込み直さない。
5. それでも、RDBとSQLが要る場面
では pandas だけでいいのかというと、そうではありません。上の表の場面Cを見てください。20万行から1件を取り出すだけなら、SQLは pandas の約1,200倍速い。 索引(インデックス)を使って、目当ての行に直接たどり着けるからです。pandasは全件をメモリに読み込んでから絞るので、1件のために20万行を運ぶことになります。
これは速さだけの話ではありません。データが大きく、しかも複数の人・複数のプログラムから同時に共有される場面では、RDBでなければ成り立ちません。 第90講で書いたとおり、DBMSの本体は「速く探せること」ではなく「一貫性を保つこと」だからです。1人が分析用に手元へコピーしたデータフレームには、他人の更新は届きません。
情報Ⅱの教材自身も、RDBが万能でないことを逆側からきちんと書いています。
同じ箇所は「現在ではNoSQLは Not only SQL の略とされることが一般的であり,RDBとRDB以外のデータベース両方を使う手法が登場している」とも書いています。
だから整理はこうなります。目的が違えば道具が違う。
| 目的 | 道具 | 理由 |
|---|---|---|
| 手元のデータを何十通りにも変形して探索する | pandas / R | 1回読めば以後メモリ上。往復が無い |
| 大量のデータから少数を正確に取り出す | RDB+SQL+索引 | 全件を運ばずに済む |
| 複数の人・プログラムが同時に読み書きする | RDB+SQL | 一貫性を機械が保証する |
| 表の形に収まらないデータを大量に貯める | NoSQL | 分散処理に向く |
道具の優劣ではありません。自分がいまどの場面にいるかを言えることが、設計です。
6. 正規化はなぜ「操作」ではなく「設計」の話なのか
ここまでが「操作」の話でした。ここからが「設計」の話です。
第90講で、1枚の大きな表に詰め込むと更新不整合・挿入不整合・削除不整合の3つが起きることを見ました。そして「表を分ければ消える」と書きました。その「分け方」を、感覚ではなく手順にしたものが正規化です。
なぜ手順が要るのか。「分ける」は、やってみるとわかりますが、どこまで分けるかが自明ではないからです。分けなさすぎれば不整合が残り、分けすぎれば結合ばかりになって使いにくい。止まるべき場所を決める規則が要る。それが第1正規形・第2正規形・第3正規形という3つの段です。
3つの段は、それぞれ違う種類の「ぶら下がり」を取り除きます。
- 第1正規形:1つのセルに複数の値が入っている状態をほどく。ほどかないと、そもそも列として集計できない
- 第2正規形:主キーが複数の列の組(複合キー)のとき、キーの一部だけで決まってしまう列を外へ出す
- 第3正規形:キーではない列が、別の列を決めている状態を外へ出す
第2と第3は、言い方は違いますが正体は同じです。「主キー以外のものが、何かを決めている」=1枚の表に2つの事実が混ざっている。
7. 正規化を一行で言うと「一事実一箇所」
この原理には名前がついています。IPA「基本情報技術者試験 シラバス Ver.9.2」の、データ中心設計の用語例にこう並びます。
1つの事実は、1か所にだけ書く。 なぜこれで3つの不整合が全部消えるのか。書いてある場所が1か所なら、直す場所も1か所しかないので直し漏れようがない(更新不整合の消滅)。事実が独立した表に住んでいれば、他の事実が無くても登録できる(挿入不整合の消滅)。他の事実を消しても、こちらは消えない(削除不整合の消滅)。
3つの不整合は別々の病気ではなく、「同じ事実が複数の場所に書かれている」という1つの原因の、3つの症状だったのです。正規化は対症療法ではなく、原因そのものを断つ手順です。
8. ただし ——「情報Ⅱで正規化を学ぶ」とは書かれていない
ここは正確に書かなければなりません。
学習指導要領解説 情報編の全文で「正規化」は6件あり、その6件すべてが第2部=専門学科の教科「情報科」の科目「データベース」の記述です。共通教科の情報Ⅰ・情報Ⅱの記述には0件。 さらに、情報Ⅱ教員研修用教材の全7分冊にも「正規化」は0件です(「冗長」も0件、「一貫性」も0件)。
余談ですが、「第二正規形」という語は解説 情報編の全文に1度も出てきません。「第一正規形から第三正規形まで」という範囲の書き方しかしていないためで、「第一正規形」2件・「第三正規形」2件に対して「第二正規形」は0件になります。語だけを機械的に数えると「第二正規形は扱われない」という誤読が生まれます。範囲表現に挟まれた語は数えられない——これは覚えておいてください。
では共通教科の側で正規化にまったく触れないのかというと、そうでもありません。情報Ⅰの教員研修用教材 第4章 学習21 には「テーブルの正規化」という語が1件あります。
理由は書いてある。手順は書いていない。 第一正規形も第二正規形も第三正規形も出てきません。
| 資料 | 正規化の理由 | 正規化の手順 (第1〜第3正規形) |
|---|---|---|
| 学習指導要領解説(共通教科・情報Ⅰ/Ⅱ) | 記述なし | 記述なし |
| 情報Ⅰ 教員研修用教材 | あり(学習21) | なし |
| 情報Ⅱ 教員研修用教材 | なし(0件) | なし |
| 学習指導要領解説(専門教科「データベース」) | あり | あり |
主語を分けて言えばこうなります。「情報Ⅱでは正規化を学びます」と国の一次資料が書いている事実は、私が調べた範囲ではありません。ただし教科書の側は別です。日本文教出版の『情報Ⅱ』(教科書番号703)は、第3章「情報とデータサイエンス」の中に「リレーショナルデータベースの設計と操作」という節を置いています(同社公式サイトの目次、2026年8月3日確認)。「設計」という語が節タイトルに入っている。
つまり——国が書いた枠には正規化の手順が無く、教科書会社が枠の中に足している、というのが2026年8月時点の実態です。情報Ⅱを履修する人は、自分の教科書がどこまで書いているかを確かめてください。 発行者は3社しかありません(一般社団法人教科書協会の高等学校「情報」のページで、情報Ⅰが7社・情報Ⅱが3社。2026年8月3日確認)。
9. 正規化の続きは、高校の外にある
正規化の手順が高校の共通教科に無いなら、どこにあるのか。IPAの情報処理技術者試験のシラバスを3段階並べると、段差がはっきり見えます。いずれも一次資料です。
(3)データの正規化 ・データの正規化の必要性(ただし,正規化の詳細な内容は問わない)
(3)データの正規化 正規化の目的と手順,第1正規形,第2正規形,第3正規形を理解する。
用語例 完全関数従属,部分関数従属,推移関数従属
(4)データベースのパフォーマンス設計 処理の高速化のためにあえて正規化を行わず,表の結合にかかる時間を短縮するなど,パフォーマンスを考慮したデータベース設計の考え方を理解する。
用語例 非正規化
3段目が面白い。 レベル3になると、シラバスが自分で「あえて正規化を行わない」設計を教えると言い出します。正規化すれば表が増え、表が増えれば結合が増え、結合が増えれば遅くなるからです。正規化は正義ではなく、一貫性と速さのトレードオフの一方の端です。
第91講で「結合=直積+選択なので行数が爆発する」と書きました。正規化とは、その爆発を自分から買いに行く行為でもあります。だから買いすぎたら戻す。それが非正規化です。
手で確かめる
ここからは実際に手を動かします。以下の出力はすべて SQLite 3.51.0 / pandas 2.3.3 / Python 3.9.6 で実際に実行し、確認したものです(2026年8月3日)。人名・団体名はすべて例示用の架空名です。
第91講では生徒表と成績表を使いました。この講では重複を避けて、文化祭の仕入伝票を題材にします。 伝票には、伝票番号・発注日・どの団体か(団体コード・団体名・顧問名)・何をいくつか(商品コード・商品名・単価・数量)が書かれています。最後の1行が問題を生みます。「1件の伝票」に「複数の明細」がぶら下がっているからです。
4-1. 非正規形 —— 1つのセルに詰め込む
いちばん素朴なのは、伝票1枚を1行にして、明細をまとめて1つのセルに書くことです。
CREATE TABLE 仕入0NF(伝票番号 INTEGER PRIMARY KEY, 発注日 TEXT,
団体コード TEXT, 団体名 TEXT, 顧問名 TEXT, 明細 TEXT);
【非正規形】1件の伝票=1行。明細が何件でも1つのセルに詰め込まれている
(101, '2026-08-20', 'C01', '演劇部', '青木先生', 'G01:紙コップ:30:200, G02:割りばし:12:300')
(102, '2026-08-21', 'C02', '写真部', '伊藤先生', 'G01:紙コップ:30:150, G03:紙皿:25:150')
(103, '2026-08-22', 'C01', '演劇部', '青木先生', 'G03:紙皿:25:100')
(104, '2026-08-22', 'C03', '茶道部', '上田先生', 'G02:割りばし:12:500')
これで困ることを、実際に確かめます。
問い①「紙コップは全部で何個仕入れたか」→ SQLで書けるか
SUM(数量) と書きたいが、数量という列が存在しない。合計関数が使えない。
苦しまぎれに LIKE で数えると → 2 件("伝票の数"であって"個数"ではない)
問い②「割りばしの単価を12→15に上げる」→ 1行のUPDATEで書けるか
単価という列が無いので、文字列の中身を書き換えるしかない。
(101, 'G01:紙コップ:30:200, G02:割りばし:15:300')
(104, 'G02:割りばし:15:500')
→ 動いてはいるが、これはデータベースの操作ではなく文字列の置換である。
もし単価12の別商品「G05:輪ゴム:12」があれば、REPLACE の対象がずれる危険が常にある。
列になっていない値は、集計できません。 これが第1正規形にする理由です。3つの不整合以前の問題で、そもそも関係演算の対象になりません。 第91講で扱った選択・射影・結合は、どれも「列」を単位とする操作だったことを思い出してください。列が無ければ、演算の入口に立てないのです。
4-2. 第1正規形 —— 繰り返しをほどく
明細1行を1レコードにします。伝票番号だけでは行を区別できなくなるので、主キーは {伝票番号, 商品コード} の組(複合キー)になります。
CREATE TABLE 仕入1NF(
伝票番号 INTEGER NOT NULL, 発注日 TEXT, 団体コード TEXT, 団体名 TEXT, 顧問名 TEXT,
商品コード TEXT NOT NULL, 商品名 TEXT, 単価 INTEGER, 数量 INTEGER,
PRIMARY KEY(伝票番号, 商品コード));
伝票番号 | 発注日 | 団体コード | 団体名 | 顧問名 | 商品コード | 商品名 | 単価 | 数量
-----+------------+-------+-----+------+-------+------+----+----
101 | 2026-08-20 | C01 | 演劇部 | 青木先生 | G01 | 紙コップ | 30 | 200
101 | 2026-08-20 | C01 | 演劇部 | 青木先生 | G02 | 割りばし | 12 | 300
102 | 2026-08-21 | C02 | 写真部 | 伊藤先生 | G01 | 紙コップ | 30 | 150
102 | 2026-08-21 | C02 | 写真部 | 伊藤先生 | G03 | 紙皿 | 25 | 150
103 | 2026-08-22 | C01 | 演劇部 | 青木先生 | G03 | 紙皿 | 25 | 100
104 | 2026-08-22 | C03 | 茶道部 | 上田先生 | G02 | 割りばし | 12 | 500
(6行)
集計はできるようになりました。しかし、同じ事実が何度も書かれています。 数えてみます。
[重複の実測] 同じ事実が何回書かれているか
商品名 は 商品コード ごとに [2, 2, 2] 回ずつ書かれている(合計 6 回)
単価 は 商品コード ごとに [2, 2, 2] 回ずつ書かれている(合計 6 回)
顧問名 は 団体コード ごとに [3, 2, 1] 回ずつ書かれている(合計 6 回)
商品は3種類しかないのに、単価は6か所に書かれている。団体は3つしかないのに、顧問名は6か所に書かれている。第90講の3つの不整合が、ここで全部そろいます。
[更新不整合の実演] 紙コップの単価を30→35に上げる。1行だけ直すと?
伝票番号 | 商品コード | 商品名 | 単価
-----+-------+------+---
101 | G01 | 紙コップ | 35
102 | G01 | 紙コップ | 30
→ 同じ商品コード G01 に単価が 2 種類存在する(表が自分と矛盾している)
[挿入不整合] まだ発注していない商品 G04「ストロー」を登録したい
→ 拒否された:NOT NULL constraint failed: 仕入1NF.伝票番号
(伝票番号が無いと主キーが作れない=商品だけを登録できない)
[削除不整合] 茶道部の伝票104を取り消す
→ 伝票を消した結果、団体 C03(茶道部・上田先生)の情報が表から 0 行に = 消滅した
3つそろいました。 第1正規形は「表として成立させた」だけで、設計としてはまだ何も解決していません。
4-3. 第2正規形 —— 複合キーの「一部」で決まる列を外へ
主キーは {伝票番号, 商品コード} でした。この表の列を1つずつ見て、主キー全体が要るのか、一部で足りるのかを確かめます。
- 発注日・団体コード・団体名・顧問名 → 伝票番号だけで決まる。商品コードは要らない
- 商品名・単価 → 商品コードだけで決まる。伝票番号は要らない
- 数量 → {伝票番号, 商品コード} の両方が要る。これだけが本物
キーの一部だけで決まってしまうことを部分関数従属といいます(基本情報シラバスの用語例)。部分関数従属を外に出すと、第2正規形になります。
CREATE TABLE 商品2NF(商品コード TEXT PRIMARY KEY, 商品名 TEXT NOT NULL, 単価 INTEGER NOT NULL);
CREATE TABLE 伝票2NF(伝票番号 INTEGER PRIMARY KEY, 発注日 TEXT NOT NULL,
団体コード TEXT NOT NULL, 団体名 TEXT NOT NULL, 顧問名 TEXT NOT NULL);
CREATE TABLE 明細2NF(伝票番号 INTEGER NOT NULL REFERENCES 伝票2NF(伝票番号),
商品コード TEXT NOT NULL REFERENCES 商品2NF(商品コード),
数量 INTEGER NOT NULL, PRIMARY KEY(伝票番号, 商品コード));
--- 商品2NF ---
商品コード | 商品名 | 単価
------+------+---
G01 | 紙コップ | 30
G02 | 割りばし | 12
G03 | 紙皿 | 25
(3行)
--- 伝票2NF(まだ団体名・顧問名を抱えている) ---
伝票番号 | 発注日 | 団体コード | 団体名 | 顧問名
-----+------------+-------+-----+-----
101 | 2026-08-20 | C01 | 演劇部 | 青木先生
102 | 2026-08-21 | C02 | 写真部 | 伊藤先生
103 | 2026-08-22 | C01 | 演劇部 | 青木先生
104 | 2026-08-22 | C03 | 茶道部 | 上田先生
(4行)
→ 単価の重複は消えたが、顧問名はまだ C01 の伝票 2 行に重複している。
顧問が交代すると、また直し漏れが起きる
単価まわりの3つの不整合は消えました。(単価を直す場所は商品2NFの1行だけ。発注実績のない商品も登録できる。伝票を消しても商品は残る。)
しかし団体まわりの3つの不整合は残っています。 顧問名がまだ伝票ごとに重複しているからです。第2正規形は「途中の段」であって、ゴールではありません。
4-4. 第3正規形 —— キーでないものが決めている列を外へ
伝票2NFの主キーは伝票番号ひとつだけなので、部分関数従属はもう起きません。それでも重複が残っている。原因は違うところにあります。
- 伝票番号 → 団体コード(キーが決めている。正常)
- 団体コード → 団体名・顧問名(キーではない列が、別の列を決めている)
伝票番号 → 団体コード → 顧問名、と2段でつながっています。これを推移関数従属といいます(同じく基本情報シラバスの用語例)。推移関数従属を外に出すと、第3正規形になります。
CREATE TABLE 団体(団体コード TEXT PRIMARY KEY, 団体名 TEXT NOT NULL, 顧問名 TEXT NOT NULL);
CREATE TABLE 商品(商品コード TEXT PRIMARY KEY, 商品名 TEXT NOT NULL, 単価 INTEGER NOT NULL);
CREATE TABLE 伝票(伝票番号 INTEGER PRIMARY KEY, 発注日 TEXT NOT NULL,
団体コード TEXT NOT NULL REFERENCES 団体(団体コード));
CREATE TABLE 明細(伝票番号 INTEGER NOT NULL REFERENCES 伝票(伝票番号),
商品コード TEXT NOT NULL REFERENCES 商品(商品コード),
数量 INTEGER NOT NULL, PRIMARY KEY(伝票番号, 商品コード));
--- 団体表 --- --- 商品表 ---
団体コード | 団体名 | 顧問名 商品コード | 商品名 | 単価
------+-----+----- ------+------+---
C01 | 演劇部 | 青木先生 G01 | 紙コップ | 30
C02 | 写真部 | 伊藤先生 G02 | 割りばし | 12
C03 | 茶道部 | 上田先生 G03 | 紙皿 | 25
(3行) (3行)
--- 伝票表 --- --- 明細表 ---
伝票番号 | 発注日 | 団体コード 伝票番号 | 商品コード | 数量
-----+------------+------ -----+-------+----
101 | 2026-08-20 | C01 101 | G01 | 200
102 | 2026-08-21 | C02 101 | G02 | 300
103 | 2026-08-22 | C01 102 | G01 | 150
104 | 2026-08-22 | C03 102 | G03 | 150
(4行) 103 | G03 | 100
104 | G02 | 500
(6行)
1枚の6行が、4枚の16行になりました。 行数は増えています。しかし同じ事実が2回書かれている場所は1つもありません。
4-5. 3つの不整合が消えたことの確認
[3つの不整合が消えたことの確認]
更新:紙コップの単価を直す場所は 1 行だけ。直し漏れが起こりえない
挿入:発注実績のない商品 G04 を登録できた → ('G04', 'ストロー', 8)
削除:伝票104を消しても団体C03は残る → ('C03', '茶道部', '上田先生')
[参照整合性] 存在しない団体コードの伝票を入れてみる
→ 拒否された:FOREIGN KEY constraint failed
| 段 | 取り除いたもの | 消えた不整合 | まだ残る不整合 |
|---|---|---|---|
| 非正規形 → 第1正規形 | 1セル内の繰り返し | (不整合以前。集計できるようになっただけ) | 更新・挿入・削除の3つとも |
| 第1正規形 → 第2正規形 | 部分関数従属 | 商品まわりの3つ | 団体まわりの3つ |
| 第2正規形 → 第3正規形 | 推移関数従属 | 団体まわりの3つ | なし |
第2正規形と第3正規形は、同じ3つの不整合を、原因の違う場所でそれぞれ潰しています。 段が2つに分かれている理由がこれです。片方だけやっても、もう片方の不整合は残ります。
そして最後の1行——参照整合性。表を分けたということは、外部キーが指す先が実在するとは限らなくなったということです。だからDBMSに「指す先が無い行は入れさせない」と宣言させる。分けることと、つながりを保証することは、セットで初めて設計になります。
4-6. 同じ問いを SQL と pandas の両方で書く
4枚に分けたので、元の情報を取り出すには結合が要ります。同じ問いを2つの言語で書いて、結果が一致することを確かめます。
SELECT 団体.団体名, 団体.顧問名, SUM(商品.単価 * 明細.数量) AS 合計金額
FROM 明細
INNER JOIN 伝票 ON 明細.伝票番号 = 伝票.伝票番号
INNER JOIN 団体 ON 伝票.団体コード = 団体.団体コード
INNER JOIN 商品 ON 明細.商品コード = 商品.商品コード
GROUP BY 団体.団体コード
ORDER BY 合計金額 DESC;
団体名 | 顧問名 | 合計金額
----+------+------
演劇部 | 青木先生 | 12100
写真部 | 伊藤先生 | 8250
茶道部 | 上田先生 | 6000
(3行)
dan = pd.read_sql_query('SELECT * FROM 団体', con)
sho = pd.read_sql_query('SELECT * FROM 商品', con)
den = pd.read_sql_query('SELECT * FROM 伝票', con)
mei = pd.read_sql_query('SELECT * FROM 明細', con)
df = (mei.merge(den, on='伝票番号') # 結合
.merge(dan, on='団体コード')
.merge(sho, on='商品コード'))
df['金額'] = df['単価'] * df['数量'] # 列を作る
res = (df.groupby(['団体コード', '団体名', '顧問名'], as_index=False)['金額']
.sum()
.rename(columns={'金額': '合計金額'})
.sort_values('合計金額', ascending=False)
.loc[:, ['団体名', '顧問名', '合計金額']]
.reset_index(drop=True))
団体名 顧問名 合計金額
演劇部 青木先生 12100
写真部 伊藤先生 8250
茶道部 上田先生 6000
--- 一致の判定 ---
SQL : [('演劇部', '青木先生', 12100), ('写真部', '伊藤先生', 8250), ('茶道部', '上田先生', 6000)]
pandas: [('演劇部', '青木先生', 12100), ('写真部', '伊藤先生', 8250), ('茶道部', '上田先生', 6000)]
一致: True
さらに、表を1枚も使わずに手で検算します。
- 演劇部:伝票101(紙コップ 30×200=6,000/割りばし 12×300=3,600)+伝票103(紙皿 25×100=2,500)=12,100円
- 写真部:伝票102(紙コップ 30×150=4,500/紙皿 25×150=3,750)=8,250円
- 茶道部:伝票104(割りばし 12×500=6,000)=6,000円
検算と SQL の一致: True
検算と pandas の一致: True
3つの経路が同じ数字に着きました。 ここで見てほしいのは、構造がそっくりだということです。
| やること | SQL | pandas |
|---|---|---|
| 結合 | INNER JOIN … ON |
.merge(…, on=…) |
| 列を作る | 商品.単価 * 明細.数量 |
df['単価'] * df['数量'] |
| グループ化 | GROUP BY |
.groupby() |
| 集計 | SUM() |
.sum() |
| 並べ替え | ORDER BY … DESC |
.sort_values(…, ascending=False) |
| 列を選ぶ(射影) | SELECT 団体名, … |
.loc[:, [...]] |
第91講で扱った関係演算が、そのまま両方に現れています。 選択・射影・結合は、言語の機能ではなく考え方です。だから片方を覚えれば、もう片方はほとんど翻訳で済む。「SQLとpandasのどちらを勉強すべきか」という問いは、実はあまり重要ではありません。 重要なのは関係演算のほうです。
ただし1つだけ本質的な違いがあります。SQLは「何が欲しいか」だけを書き、どう計算するかはDBMSが決める。pandasは「どう計算するか」を自分で順番に書く。 上のSQLには「まず明細を読んで、次に伝票と突き合わせて…」という順序が書かれていません。書いてあるのは欲しい結果の形だけです。
4-7. どちらが速いのか —— 3つの場面で実測する
明細20万行・団体200・商品50のデータを作り、同一マシンで測りました(乱数の種を固定。各測定は複数回の最小値を取り、3回実行して数値が安定することを確認済み)。
■ 場面A:1回だけ集計する(毎回まっさらな状態から)
SQL : 0.071 秒
pandas: 0.135 秒(読み込みを含む)
→ SQL のほうが速い(1.9倍)
pandasは20万行をPythonのメモリへ運ぶ費用を先に払います。1回で終わるなら、その費用は回収できません。
■ 場面B:同じデータに20通りの集計をかける(=分析の実際)
SQL : 1.498 秒(20回とも表を読み直す)
pandas: 0.136 秒(読み込み1回+メモリ上で20回)
→ pandas のほうが速い(11.0倍)
pandasの時間が場面Aとほぼ同じ(0.135→0.136秒)ことに注目してください。20回集計しても、読み込みは1回しか払っていない。 一方SQLは20回とも表を読み直すのでほぼ20倍になる。これが「分析ではpandasのほうが高速」の正体です。
■ 場面C:20万行から1件だけ取り出す(=情報システムの実際)
SQL(索引あり): 0.0001 秒
pandas(全件読み込み): 0.1219 秒
→ SQL のほうが速い(1289.9倍)
索引を張ったSQLは、20万行を1行も読まずに目当ての行へ着きます。pandasは1件のために20万行を運ぶ。3桁違います。
この3つが、そのまま「目的が違えば道具が違う」の実測です。 どちらが優れているかではなく、AとBとCのどこにいるかが答えを決めます。
共通テストではこう出る(重要度C)
この講の内容は共通テスト「情報Ⅰ」の出題範囲外です。 情報Ⅱは共通テストの出題科目ではありません。正規化も、第1〜第3正規形も、SQLの文法も、覚える必要はありません。この節は、脅すためではなく、範囲を正しく切るために書いています。
そのうえで、情報Ⅰの範囲でデータベースがどう問われているかを、一次資料で確かめた事実として書いておきます。
データベースは出ています。ただし用語ではなく「表を扱う判断」として出ています。 大学入試センターが公開している「問題評価・分析委員会報告書」の問題作成部会の見解(自己評価)に、次の記述があります。まず令和7年度 追・再試験『情報Ⅰ』第1問について——
問3において「情報I」の学習範囲の制約内でデータベース問題を出題した点については好意的な評価が得られた。— 大学入試センター 問題評価・分析委員会報告書(追・再試験)
「学習範囲の制約内で」という言い方に注目してください。 出題側は、データベースが情報Ⅰでどこまでしか扱えないかを意識して問題を作っています。つまりSQLの文法や正規形が問われることは、構造的にありません。
次に令和8年度 追・再試験『情報Ⅰ』第1問については、こう書かれています。
「データベースの設計」という語が、共通テストの自己評価に出てきています。 ただし中身を見ると、問われているのは正規形ではありません。設問の構造だけ要約すると——10年前と今年の2つのアンケート結果の表を1つにまとめるにあたり、分析を円滑に進めるためにやるべきでないことを選ばせる、という形です。粒度のそろっていない2つの表(片方は市の町名まで・年齢は実数、もう片方は市名まで・年齢は10歳刻み)を、どうそろえて統合するか、という判断を問うています。
これは正規化の逆向きの操作です。 この講でやったのは1枚を4枚に分ける作業でしたが、共通テストで問われたのは2枚を1枚にまとめるときに何をそろえるかでした。向きは逆でも、「同じ事実が同じ形で書かれているか」を問うている点は同じです。
まとめると、情報Ⅰの範囲で問われるのはこの3つだと考えてよいでしょう。
- 表の構造の理解(レコード・フィールド、主キーにあたるものが何か)— 第90講
- 表の突き合わせ・絞り込み・列の読み取り(関係演算を作業として行う)— 第91講
- 粒度をそろえてデータを統合する判断(前処理。令和8年度 追・再試験 第1問 問4)
用語を暗記する価値は低い。表を実際に触ったことがあるかどうかが効きます。 なお、上の出題はいずれも本試験ではなく追・再試験でのものです(令和7年度・令和8年度の本試験の問題冊子には「データベース」の語が0件。私が確認した範囲)。毎年必ず出る単元ではありません。
自作の練習問題
次の表は、部活動の合宿の宿泊記録です。第3正規形になっていない箇所を指摘し、表を分けてください。
| 予約番号 | 部活コード | 部活名 | 宿コード | 宿名 | 1泊料金 | 泊数 |
|---|---|---|---|---|---|---|
| R01 | B1 | 吹奏楽部 | H1 | 山荘あおば | 6000 | 3 |
| R02 | B2 | 陸上部 | H1 | 山荘あおば | 6000 | 2 |
| R03 | B1 | 吹奏楽部 | H2 | 湖畔ロッジ | 7500 | 2 |
・予約表(予約番号、部活コード、宿コード、泊数)
・部活表(部活コード、部活名)
・宿表(宿コード、宿名、1泊料金)
これで「山荘あおばが値上げした」ときに直す場所が1か所になります(更新不整合の解消)。まだ予約の入っていない宿も登録できます(挿入不整合の解消)。R01を取り消しても吹奏楽部の情報は残ります(削除不整合の解消)。
情報Ⅱではこうなる
本講そのものが情報Ⅱの内容なので、ここでは語数調査の全体と、調べた範囲を明示します。
調べた範囲(「0件」の意味を限定するために)
「0件」は「私が調べた範囲では0件」であって、それ以上の意味を持たせてはいけません。今回当てたのは次のすべてです(2026年8月3日)。
- 学習指導要領解説 情報編(平成30年7月)全文。第1部=共通教科(情報Ⅰ・情報Ⅱ)と第2部=専門学科の教科「情報科」を分割して別々に計数しました(専門教科には「データベース」「情報デザイン」等の科目が実在し、混ぜると件数を誤ります)
- 情報Ⅰ 教員研修用教材 全6分冊(はじめに/本教材の使い方/第1章/第2章/第3章/第4章)
- 情報Ⅱ 教員研修用教材 全7分冊(序章/第1章/第2章/第3章前半/第3章後半/第4章/第5章)。第3章は前半・後半の2分冊で別PDFであり、片方だけ見て「0件」と書くと誤ります
- IPA シラバス3種:ITパスポート Ver.6.5/基本情報技術者 Ver.9.2/応用情報技術者 Ver.7.2
- 大学入試センター:令和7年度・令和8年度の本試験および追・再試験の『情報Ⅰ』問題冊子、試作問題の概要、出題方針、問題評価・分析委員会報告書
- 文部科学省 授業・研修用コンテンツ(高等学校情報科特設ページ)
計数はすべて、空白と改行を除去し、NFKC正規化をかけてから行いました。PDFのテキスト抽出は「正規(改行)化」のように語の途中で改行が入るため、素朴に検索すると系統的に少なく出ます。
限界も書いておきます。 文部科学省 授業・研修用コンテンツのスライドPDFの一部はテキスト抽出が0文字=画像化されており、全文検索の対象外です。したがって上記の「0件」は、テキスト抽出できた資料の範囲での0件です。
語数調査の全体
| 語 | 解説 (共通教科) |
解説 (専門教科) |
情報Ⅰ 教材 |
情報Ⅱ 教材 |
|---|---|---|---|---|
| 正規化 | 0 | 6 | 1 | 0 |
| 第一正規形 | 0 | 2 | 0 | 0 |
| 第二正規形 | 0 | 0 | 0 | 0 |
| 第三正規形 | 0 | 2 | 0 | 0 |
| 主キー | 0 | 0 | 0 | 0 |
| 外部キー | 0 | 0 | 0 | 0 |
| 参照整合性 | 0 | 0 | 0 | 0 |
| データベース管理システム | 1 | 14 | 0 | 0 |
| E-R図 | 0 | 1 | 0 | 0 |
| 一貫性 | 0 | 1 | 0 | 0 |
| SQL | 0 | 0 | 8 | 21 |
| SQL文の実例 | 0 | 0 | 11文 | 0 |
| スキーマ | 0 | 0 | 0 | 2 |
| RDB | 0 | 0 | 0 | 14 |
| pandas | 0 | 0 | 0 | 18 |
| データフレーム | 0 | 0 | 1 | 20 |
| NoSQL | 0 | 0 | 2 | 11 |
| インデックス | 0 | 0 | 0 | 1 (pandasの行名) |
| 索引 | 0 | 0 | 0 | 0 |
用法まで見ないと危ない行が3つあります。
- SQL 21件:うち13件は
NoSQL/Not only SQLの一部。残り8件も言語の名前としての言及で、MySQL・SQLiteという製品名を含みます - インデックス 1件:pandasのデータフレームの「行名」であって、データベースの索引ではありません
- 独立性 11件・耐久性 1件:すべて第4章のモジュールの独立性などであり、トランザクションのACID特性ではありません(ACIDが並ぶのは解説の専門教科側だけ)
3つの層が、それぞれ別のことを言っている
| 層 | データベース設計について何と言っているか |
|---|---|
| 解説(共通教科) | 情報Ⅱで「関係演算」と「データベースの管理や操作を行うプログラミング言語」に触れよ。正規化・主キー・外部キーの語は1つも無い |
| 情報Ⅰ 教員研修用教材 | 学習21 で関係演算を定義し、SQL文の実例を11個載せる。「テーブルの正規化」の語と理由も書く。ただし手順は無い |
| 情報Ⅱ 教員研修用教材 | SQL文は0行。 RDBの構造(レコード・属性・スキーマ・型)を説明したうえで、pandasを勧める。そしてNoSQLへ進む |
| 解説(専門教科「データベース」) | E-R図・第一正規形から第三正規形・トランザクション管理(原子性・一貫性・独立性・耐久性)・同時実行制御及びロック・副問い合わせ・ビュー |
縦に読むと、情報Ⅱの教員研修用教材だけが違う方向を向いています。 前後(情報Ⅰの教材と、専門教科の解説)はどちらも「SQLと表の設計」を扱っているのに、その間に挟まった情報Ⅱの教材だけが pandas と NoSQL に進む。
なぜか。情報Ⅱ(3)の題名が「情報とデータサイエンス」だからです。 この単元の目的はデータベースを作ることではなく、データを分析することです。分析のためにデータを整えるのが目的なら、道具はpandasでよい。実測したとおり、その判断は速度の面でも正しいのです。
ただし、この判断には代償があります。 情報Ⅱの教員研修用教材だけを読んだ人は、次のものに一度も出会いません。
- SQL文の書き方(
SELECTすら見ない) - 正規化の手順(第1〜第3正規形)
- 主キー・外部キー・参照整合性という語
- 索引(インデックス)という仕組み
- トランザクションとACID特性
これらは全部、情報Ⅰの教材か、専門教科の解説か、IPAのシラバスの側にあります。 情報Ⅱの教材にだけ在るのは、スキーマ(表の構造そのものに与えられた名前。解説0件・情報Ⅰ教材0件・情報Ⅱ教材2件)と、NoSQLと、pandasです。
「構造そのものに名前をつける」というのが、情報Ⅱが情報Ⅰに足している唯一の設計語です。 情報Ⅰでは表は「与えられるもの」でしたが、情報Ⅱではスキーマを自分で指定するものになる。ここだけは、確かに「設計」の側へ半歩出ています。
情報Ⅰと情報Ⅱの扱いの違い(まとめ表)
| 情報Ⅰ | 情報Ⅱ (国の教材の実際) |
その先 (専門教科・IPA) |
|
|---|---|---|---|
| 表 | 与えられた表を読む | スキーマと型を自分で指定する | E-R図で設計する |
| 分ける理由 | 「冗長を避ける」と知る | 扱われない | 正規化の必要性として扱う |
| 分ける手順 | 無い | 無い | 第一〜第三正規形 |
| 操作 | SQL文を実際に見る | pandasで書く。SQL文は載らない | SQL(副問い合わせ・ビューまで) |
| 速さの工夫 | 扱わない | 扱わない(索引0件) | 索引・非正規化 |
| 一貫性 | 扱わない | 扱わない(0件) | ACID・同時実行制御・ロック |
| 蓄え方の選択 | 扱わない | RDBとNoSQLの使い分け | データモデルの比較 |
最後から2行目が、この講のいちばんの発見です。 情報Ⅱは「情報Ⅰの続き」ではありません。RDBの中を深く掘るのではなく、RDBの外に出る方向に進んでいます。第57講で見た「大量のデータを扱う際にRDBは必ずしも効率的な方法ではなく」という一文は、まさにその宣言です。
深く掘りたい人は、情報Ⅱではなく専門教科かIPAのシラバスを見に行くこと。 これが、2026年8月時点の一次資料から言える正直な案内です。
まとめ
- 学習指導要領解説は関係演算とデータベース操作言語(SQL)を情報Ⅱに置いたが、情報Ⅱの教員研修用教材にはSQL文が1行も無い(
SELECT・FROM・WHERE・セミコロンすべて0件)。実物が載っているのは情報Ⅰの教材 第4章 学習21のほう - 情報Ⅱ教材の「SQL」21件は、13件がNoSQLの一部、残り8件も言語名としての言及。件数だけを見ると大きく誤読する
- 教材はSQLの代わりにpandasを勧める。分析の文脈ではこれは正しい判断で、実測でも「同じデータに20通りの集計」では pandas が約10〜11倍速い
- 一方で、1件だけ取り出す場面では索引付きSQLが約1,200倍速い。目的が違えば道具が違う。Not only SQL は「SQLではない」ではない
- 正規化は操作ではなく設計。 第90講の3つの不整合を、止まる場所つきの手順に形式化したもの。原理は「一事実一箇所」
- 第2正規形(部分関数従属の除去)と第3正規形(推移関数従属の除去)は、同じ3つの不整合を、原因の違う場所でそれぞれ潰している。 だから段が2つ要る
- 正規化の手順を扱えと国が書いているのは、共通教科ではなく専門学科の教科「情報科」の科目「データベース」。 ただし教科書の側は別で、日本文教出版『情報Ⅱ』(703)は「リレーショナルデータベースの設計と操作」という節を持つ
- 共通テストはこの講の内容を出題しない。ただしデータベース自体は追・再試験で出ており、令和8年度 追・再試験 第1問 問4 は「データベースの設計における基礎的な概念」を、2つの表の粒度をそろえて統合する判断として問うている
出典(すべて2026年8月3日取得)
・文部科学省「高等学校学習指導要領(平成30年告示)解説 情報編」平成30年7月 https://www.mext.go.jp/content/1407073_11_1_2.pdf
・文部科学省「高等学校情報科『情報Ⅰ』教員研修用教材」第4章 https://www.mext.go.jp/content/20200722-mxt_jogai02-100013300_006.pdf
・文部科学省「高等学校情報科『情報Ⅱ』教員研修用教材」第3章 前半 https://www.mext.go.jp/content/20200702-mxt_jogai01-000007843_004.pdf
・文部科学省「授業・研修用コンテンツ」【情報Ⅰ】 https://www.mext.go.jp/a_menu/shotou/zyouhou/detail/mext_01832.html
・IPA「ITパスポート試験 シラバス Ver.6.5」 https://www.ipa.go.jp/shiken/syllabus/omgdg50000005kn1-att/syllabus_ip_ver6_5.pdf
・IPA「基本情報技術者試験 シラバス Ver.9.2」 https://www.ipa.go.jp/shiken/syllabus/omgdg50000005kpe-att/syllabus_fe_ver9_2.pdf
・IPA「応用情報技術者試験 シラバス Ver.7.2」 https://www.ipa.go.jp/shiken/syllabus/omgdg50000005kq5-att/syllabus_ap_ver7_2.pdf
・大学入試センター「令和8年度 問題評価・分析委員会報告書(追・再試験)」 https://www.dnc.ac.jp/kyotsu/hyouka/r8_hyouka/r8_hyoukahoukokusyo_tsuisaishiken.html
・大学入試センター「過去3年分の試験問題」 https://www.dnc.ac.jp/kyotsu/kakomondai/
・日本文教出版『情報Ⅱ』(教科書番号703)目次 https://www.nichibun-g.co.jp/textbooks/joho/2023_joho02/textbook/
・一般社団法人教科書協会「高等学校 情報」 https://www.textbook.or.jp/textbook/publishing/high-info.html
実行環境は SQLite 3.51.0 / pandas 2.3.3 / Python 3.9.6。
この講は『藤原進之介の最強120講義』の第118講です。全体の目次はこちらのハブページから、関連記事はカテゴリ一覧からご覧いただけます。土台になる第90講(データベースの基礎)・第91講(関係演算)、条件式の話は第43講(論理演算)、情報Ⅱ全体の地図は第109講をご覧ください。
執筆:藤原進之介(数強塾グループ代表)
オンライン数学専門塾「数強塾」代表。累計3,500名以上の中高一貫校生を指導。東進ハイスクール・東進衛星予備校・代々木ゼミナールなど出講実績あり。情報Ⅰの参考書を複数執筆しており、KADOKAWA『ゼロから始める情報I』、Gakken『きめる!共通テスト 情報Ⅰ』などがあります。本記事は参考書『藤原進之介の最強120講義』第118講のWeb版です。
「情報Ⅰの先まで見据えて勉強したい」という方へ
数強塾では数学と情報Ⅰの両方に対応したオンライン個別指導を行っています。学習相談は無料、体験授業は3,000円(税込)でお受けしています。
