掲載内容は正確性・最新性の確保に努めていますが、一次情報をご確認ください。
shindanshi中小企業診断士 wiki

データベースとSQL

RDB、3層スキーマ、E-R図、正規化、SQL、トランザクション、バックアップの基礎を整理する

このページの役割

このページの役割

このページは、企業システムの「データの保管庫」となるデータベースを理解するページです。営業が受注を記録し、在庫を更新し、決算データを集計する─これらすべてがデータベースの上で動いています。表の設計から、データ取り出しの命令、そして障害時の復旧まで、一連の実務を支える考え方をていねいに解説します。

学習のポイント

  • まず体験する:「顧客情報が複数の受注に繰り返している」という問題から、表を分割する必要性を感じる
  • キーで「誰が誰とつながるか」を追う:主キーと外部キーの対応を見ると、複雑な表の関係も一本の流れとして理解できる
  • 正規化は「整理」:データの重複を見つけ、表を分割する思考プロセスを身につける
  • SQLは「日本語に訳す」:実行順序(FROM → WHERE → GROUP BY)を常に意識しながら読む
  • トランザクションは「複数操作をセット」:銀行振込の例で、途中で止まると困る理由を理解する
  • バックアップは「取得と復旧」のセット:取得だけでは意味がないことを押さえる

試験で何が問われるか

  • 主キーと外部キー:「行を識別するか」「表をつなぐか」の違いを言えるか。複合キーが現れても対応できるか
  • 正規化の段階:非正規形、第1〜第3正規形の境界がどこか、各段階で排除するものが何か
  • 更新異常:なぜ「顧客名を複数の受注レコードに持つ」と困るのか。その理由を説明できるか
  • SQL の読み取り:SELECT文の記述順序と実行順序の違いを理解し、WHERE と HAVING、GROUP BY と集約関数の関係を見分けられるか
  • JOIN の種類:LEFT OUTER JOIN でなぜ「受注がない顧客も表示」されるのか、その仕組みが言えるか
  • ACID 特性:トランザクションの4つの特性が実装上どう保証されるか(コミット、ロック、ログなど)
  • バックアップとリカバリ:フル、差分、増分の使い分けと、復旧の手順(ロールバック、ロールフォワード)

データベースの基本概念

データベースとは何か

データベースは、企業の経営活動に必要な情報を、体系的に保存・管理・取り出す 仕組みです。

たとえば、商品を売った時を想像してください。「誰に」「何を」「いくらで」「いつ」売ったかが、あちこちに散らばっていると、後で「この顧客の売上合計は?」と聞かれた時に、すべてを手作業で足す羽目になります。データベースがあれば、その質問に秒単位で答えられます。

データベースがもたらす効果は三つです:

  1. データの保持:記録を失わない。停電やシステム障害があってもデータは残る
  2. データの整合性:同じ情報が二度と矛盾しない。顧客の住所を変えたら、それが一度だけ変わる
  3. データの取り出し:必要な情報を必要な形で、高速に引き出せる

これらを実現するために、データベースには 構造ルール があります。

データベースの種類

データベースにはいくつかの形式があります。試験では リレーショナルデータベース(RDB) が主役ですが、他の種類も背景として理解すると理解が深まります。

種類構造特徴用途
RDB行と列の表キーで表をつなぐ、ACID特性対応会計、受発注、顧客管理
キーバリュー型キーと値のペア高速アクセス、メモリ中心キャッシュ、セッション管理
ドキュメント型JSON/XML形式柔軟なスキーマ、階層構造ログ管理、ユーザー設定
カラムナー型列単位での圧縮保存分析・集計が高速ビッグデータ分析
グラフ型ノードとエッジのグラフ関連性の検索が効率的SNS、推奨エンジン

RDB が「表」という最も単純な形式を使いながら、なぜ 50年以上、ほぼすべての企業システムで使われ続けているのか。それは、ルール(正規化)に従うと、データの矛盾が自動的に防げる からです。試験でも、この RDB の構造と仕組みが重点です。

リレーショナルデータベース(RDB)─なぜ「表」か

RDB は、関係(relation)を で表す仕組みです。「関係」とは聞き慣れないかもしれませんが、これは単に「表」を意味します。「顧客」と「受注」の関係を、別々の表で管理し、キーでつなぐ。これが RDB の核です。

なぜ「1 つの大きな表に全てを詰め込まない」のでしょう?答えは、同じ情報が何度も繰り返される問題 を防ぐためです。

例えば、「顧客」と「受注」を 1 つの表に詰め込むと:

顧客ID | 顧客名 | 受注ID    | 商品
101    | A社   | R001, R002 | P001, P002

こうなると、A社の住所を変えた時に、A社のすべての受注レコードを探して更新しなければなりません。1 つ忘れると、データが矛盾します(更新異常)。

逆に表を分ければ:

【顧客表】
顧客ID | 顧客名
101    | A社

【受注表】
受注ID | 顧客ID | 商品
R001   | 101    | P001
R002   | 101    | P002

A社の情報は 1 ヶ所だけなので、変更は一度で済み、矛盾が生まれません。

RDB の基本

表(テーブル)は、行(レコード)と列(フィールド)の組み合わせです。各行は一意に識別され、列は意味を持つデータ項目です。複数の表を一つのデータベースにまとめ、キー で結び付けることで、データの重複を最小化し、矛盾を防ぎます。


3 層スキーマとデータ独立性

スキーマとは何か

スキーマ(schema)は、「設計図」「構造の約束」という意味です。データベースの設計図は、3 つの階層に分かれています。この 3 層構造により、変更の影響を最小限に抑える「データ独立性」が実現されます。

3 層の構成と意味

役割対象具体例
外部スキーマ利用者が見えるビューアプリケーション、ユーザー営業スタッフは顧客名と売上だけ見て、給与情報は見えない
概念スキーマ全体の論理構造エンティティ、属性、リレーションシップ「顧客表」「受注表」「商品表」の定義と、それらの関連
内部スキーマ物理的な保存構造インデックス、ファイル、磁盤配置「顧客ID にインデックスを張る」「このファイルを SSD に置く」

データ独立性の実務的意味

スキーマが 3 層に分かれていると、何が得られるでしょう。それは、変更の波紋を限定する ことです。

例:営業管理システムを新しく作る

古い時代:営業スタッフが見ていた帳票形式(「顧客No、顧客名、売上」)が、データベース層の表構造そのものだった。営業管理システムを新しく作る時、新しい形式に対応させようとすると、データベースの表そのものまで変えなければならず、既存システムが全部壊れてしまった。

3 層スキーマなら:

  1. 外部スキーマ(営業管理システムが見る形) → 新しいシステム用に書き直す
  2. 概念スキーマ → 変わらない(「顧客」と「受注」の関係は変わらないから)
  3. 内部スキーマ → 変わらない(データを磁盤のどこに置くかは、業務ロジックに影響しない)

つまり、「新しい営業管理システムを追加」するだけで、既存の他のシステムには一切影響がない。これが データ独立性 です。

データ独立性の定義

  • 論理的独立性:外部スキーマと概念スキーマが分離。概念スキーマの変更がアプリケーション層(外部スキーマ)に影響しない
  • 物理的独立性:概念スキーマと内部スキーマが分離。データベースファイルの配置や圧縮方式の変更が、上位のアプリケーションに影響しない

この 2 つが実現されると、「昨年作ったシステムを新しい要件に対応させる」が、実装コストを最小にできます。


E-R図(エンティティ・リレーションシップ図)

E-R図の役割

データベースの設計は、いきなり表を作ることから始まりません。まず、「どんなもの(エンティティ)があって、どう関連するのか」を図で整理 します。この図が E-R 図です。

プログラマーが実装を始める前に、要件を整理する段階で「顧客」と「受注」の関係は「1人の顧客が複数の受注を出す(1:N)」ことを確認します。この確認をせずに実装を始めると、後で「やはり 1 人の顧客が複数の部門の受注を同時に進められるようにしたい」という要件変更に対応できず、全部修正することになります。

主要な要素

要素説明図記号
エンティティ実体、「ものごと」四角形顧客、商品、受注
属性エンティティが持つ性質、データ項目楕円顧客ID、顧客名、住所
リレーションシップエンティティ間の関連、つながり菱形「顧客が受注を出す」
カーディナリティ関連の強さ(何対何か)線の端の記号1 個の顧客が複数の受注

カーディナリティ(リレーションシップの種類)

データベース設計で最も大事な判断の一つが「この 2 つのエンティティの関係は何対何か」です。

表記説明実例RDB での実装
1:1一対一A は B と最大 1 つ結合従業員 1 人 - 社員証 1 枚A の表に B の主キーを外部キーとして持つ
1:N一対多A は複数の B と結合顧客 1 社 - 受注複数件B の表に A の主キーを外部キーとして持つ
M:N多対多A と B が相互に複数結合受注 - 商品(1 受注に複数商品、1 商品が複数受注に)中間表を作成

M:N リレーションシップの処理

ここが E-R 図から RDB の実装への「ギャップ」です。理解しておきましょう。

問題:「受注」と「商品」の関係は何か?

  • 1 つの受注には複数の商品が含まれます(例:受注 R001 に「商品 P001」と「商品 P002」)
  • 1 つの商品は複数の受注に含まれます(例:商品 P001 は「受注 R001」と「受注 R003」)

つまり M:N(多対多)です。

RDB での実装の困難:表では、1 つのセルに複数の値を入れられません。だから、「受注」表に「商品 P001, P002」と書くことはできません。

解決方法:中間表(関連表)を作ります。

【受注表】
受注ID | 顧客ID
R001   | C001
R002   | C001

【受注明細表】← 中間表
受注ID | 商品ID | 数量
R001   | P001   | 10
R001   | P002   | 5
R002   | P001   | 3

【商品表】
商品ID | 商品名
P001   | パーツA
P002   | パーツB

受注明細表により、「受注 R001」と「商品 P001」の関係は、「受注 R001 行」と「受注明細表で受注ID=R001 の行」と「商品 P001 行」をつなぐことで表現できます。

M:N を中間表で実装する理由

RDB は「単一値」の表を前提にしています。M:N を直接表現することはできません。中間表を作ることで、M:N を 2 つの 1:N に分解します。この分解こそが、RDB が単純で堅牢である理由です。


リレーショナルデータベース基本概念

用語の整理

RDB では、「表」という日常的な言葉で、数学的な「関係」を管理します。用語を正確に押さえておくと、技術的な会話がスムーズになります。

日本語英語説明
Table1 つのエンティティに対応する行・列の集合。顧客表、受注表など
Tuple(数学)/ Record(実務)1 個のエンティティ、データ 1 件。顧客 1 社、受注 1 件
Attribute(数学)/ Field(実務)1 つの性質・項目。顧客ID、顧客名、住所など
セルCell1 行と 1 列の交点。具体的な 1 つの値

キーの概念と役割

キー(key)は、RDB で最も重要な概念です。「どの行のことを言っているのか特定する」あるいは「どの表とどの表をつなぐのか指定する」ために使われます。

キーの種類

キーの種類意味制約
主キー(Primary Key, PK)この行を一意に識別する属性重複不可、NULL不可、1表に最低1個顧客ID、受注ID
候補キー主キーになる資格がある属性一意性あり、複数あり得る顧客ID、顧客の社会保険番号
複合キー複数の属性の組み合わせで一意属性それぞれには重複があっても、組み合わせは一意受注明細表の(受注ID, 商品ID)
外部キー(Foreign Key, FK)別表の主キーを参照する属性参照先表に存在する値のみ受注表の顧客ID(顧客表の主キーを参照)

主キーと外部キーの関係

主キーと外部キーは、RDB の「双子」です。この関係を理解することが、データベース設計と SQL の読み取りの両方の基礎になります。

例:顧客表と受注表

【顧客表】
顧客ID (PK) | 顧客名  | 住所
101         | A社    | 東京都
102         | B社    | 大阪府

【受注表】
受注ID (PK) | 顧客ID (FK) | 売上
R001        | 101        | 100000
R002        | 101        | 50000
R003        | 102        | 80000
  • 顧客表の顧客ID:主キー。顧客を一意に識別
  • 受注表の顧客ID:外部キー。「この受注は顧客表のどの行か」を指す矢印

この関係により、「顧客101(A社)の全受注を取得する」という操作が可能になります。

キーの役割を同じ例で比較

主キー:「個」を識別する

  • 顧客101は A社、顧客102は B社。それぞれ異なるから、顧客IDで区別できる

外部キー:「つながり」を表現する

  • 受注R001の顧客IDが101 → この受注は顧客101(A社)のもの
  • 受注R002の顧客IDも101 → この受注も同じA社のもの

外部キーがあることで、「同じ顧客の複数受注」という関係が自動的に保証される


関係演算(関係代数)

なぜ「関係演算」を学ぶのか

SQL を読む時、実は関係演算の 8 つの基本操作が組み合わさっています。「SELECT WHERE をしたら行が絞られた」というのは、選択演算 を行っているのです。「SELECT で列を指定したら列が減った」というのは、射影演算 です。

この対応を意識すると、複雑な SQL でも「あ、これは選択と射影の組み合わせなんだ」と理解できるようになります。

8 つの基本演算

演算記号説明入力出力SQL の対応
選択(制限)σ条件を満たす行を抽出1 表行の部分集合WHERE 句
射影π指定列だけを抽出1 表列の部分集合SELECT 句
結合⊳⊲共通属性で表をつなぐ2 表つながった 1 表JOIN 句
直積×全ての組み合わせ2 表m × n 行の表CROSS JOIN
重複を除いて統合2 表(同一スキーマ)統合表UNION
一方にあり、他方にない行2 表(同一スキーマ)差分表EXCEPT
積(交差)両方に含まれる行2 表(同一スキーマ)共通部分INTERSECT
除算÷「全てのものに対応する」行を抽出2 表除算結果(複雑な WHERE で表現)

関係演算と SQL の対応

SQL の SELECT 文を読む時、「これは何の演算をしているのか」を意識することで、複雑なクエリが単純に見えます。

例1:基本的な SELECT

SELECT 顧客ID, 顧客名
FROM 顧客表
WHERE 売上 > 100000

→ 顧客表から(元の表)→ 売上 > 100000 の行を選択(選択演算)→ 顧客ID と顧客名の列だけを射影(射影演算)

例2:JOIN

SELECT 受注表.受注ID, 顧客表.顧客名
FROM 受注表 JOIN 顧客表 ON 受注表.顧客ID = 顧客表.顧客ID

→ 受注表と顧客表を結合(結合演算)→ 受注ID と顧客名の列を射影

関係演算を意識する利点

「WHERE は選択」「SELECT は射影」「JOIN は結合」と意識すると、複雑な SQL でも順序立てて理解できます。また、性能最適化時に「この選択は早くできるか」を判断する根拠にもなります。


正規化

正規化とは何か

正規化(normalization)は、データベース設計のプロセスです。目的は一つ:同じ情報が複数の場所に存在することを減らし、更新時の矛盾を防ぐ こと。

なぜこれが必要でしょう。営業管理システムで顧客 A の住所を変えたとします。その顧客の過去の 100 件の受注レコードにも同じ住所が記録されていたら、100 ヶ所すべてを更新しなければなりません。1 つ忘れると、古い住所と新しい住所が混在する矛盾が生まれます。これが 更新異常 です。

正規化は、このような「同じ情報の繰り返し」を見つけて、表を分割することで防ぎます。

正規化の段階と異常の種類

試験では「第 1 正規形から第 3 正規形」と 3 段階覚える傾向がありますが、まず「何が困るのか」を理解することが重要です。

3 つの異常(更新異常、挿入異常、削除異常)

異常発生の原因具体例
更新異常同じ情報が複数の行に繰り返される顧客 A の住所を 100 件の受注レコードで変更し、1 件忘れる → 古い住所と新しい住所が混在
挿入異常主キーの一部だけに従属する情報がある「部門に属する従業員」の表で、まだ従業員がいない部門を登録できない(従業員IDが NULL では主キーが成立しない)
削除異常行を削除した時、他の情報も失われる唯一の受注者が辞めたので受注レコードを削除 → その顧客情報も消える

正規化の進行

段階排除対象具体的な問題ビフォー・アフター
非正規形なし(出発点)繰り返し項目(1 行に複数値)顧客ID, 受注ID(R001, R002), 売上(100, 50)
第1正規形(1NF)繰り返し項目同じ情報の繰り返し1 行 = 1 受注 へ分割
第2正規形(2NF)部分関数従属主キーの一部だけで決まる情報商品名が商品IDだけで決まる(受注IDは不要)
第3正規形(3NF)推移関数従属主キーでない属性同士の依存部門名が部門IDで決まる(従業員IDは不要)

正規化の本質

正規化は「表を増やすこと」ではなく、「依存関係をはっきりさせること」です。その副作用として表が増えるだけです。

具体例:正規化のステップ

実務で遭遇する例で、段階を追って説明します。「顧客が受注を何度も出す」シナリオです。

出発地点:非正規形

営業管理システムを始めた時、こんな表から出発しました。

【顧客受注表(非正規形)】
顧客ID | 顧客名 | 顧客住所   | 受注ID    | 商品ID    | 数量
101    | A社   | 東京都    | R001, R002 | P001, P002 | 10, 5
102    | B社   | 大阪府    | R003      | P001      | 3

何が問題か

  1. 繰り返し項目:「受注ID」「商品ID」「数量」に複数値が入っている(1 行に複数件の受注)
  2. 同じ情報の繰り返し:顧客 A の情報が 2 行あれば 2 回繰り返される
  3. 更新異常の危険:A社の住所を変える時、その行の「東京都」だけを「神奈川県」に変えて、本当は 2 行あるのに 1 行だけ更新する危険

第1段階:第1正規形へ(繰り返し項目を排除)

まず、1 行に複数値が入っている部分をばらします。

【受注明細表(第1正規形)】
受注ID | 顧客ID | 顧客名 | 顧客住所 | 商品ID | 数量
R001   | 101    | A社   | 東京都  | P001   | 10
R002   | 101    | A社   | 東京都  | P002   | 5
R003   | 102    | B社   | 大阪府  | P001   | 3

改善:繰り返し項目がなくなり、各セルが単一値 ✓

新しい問題:顧客 A の情報(ID、名前、住所)が 2 行に繰り返されている。

第2段階:第2正規形へ(部分関数従属を排除)

「顧客名と顧客住所は、顧客ID だけで決まる。受注ID は不要」に気づきます(部分関数従属)。

表を分割します:

【顧客表】
顧客ID | 顧客名 | 顧客住所
101    | A社   | 東京都
102    | B社   | 大阪府

【受注明細表(第2正規形)】
受注ID | 顧客ID | 商品ID | 数量
R001   | 101    | P001   | 10
R002   | 101    | P002   | 5
R003   | 102    | P001   | 3

改善

  • 顧客 A の住所は「顧客表」に 1 ヶ所だけ。変更は 1 ヶ所で済み、更新異常がない ✓
  • 受注明細表は「何の受注に、どの商品が何個」かだけ記録

第3段階:第3正規形へ(推移関数従属を排除)

実は、顧客表に「部門ID」があって、「部門ID」には「部門名」が決まっているとします(推移関数従属)。

【不完全な設計】
顧客ID | 顧客名 | 部門ID | 部門名
101    | A社   | D01    | 営業
102    | A社   | D01    | 営業   ← 同じ部門情報が繰り返される

「部門」の概念を独立させます:

【部門表】
部門ID | 部門名
D01    | 営業
D02    | 企画

【顧客表(第3正規形)】
顧客ID | 顧客名 | 部門ID
101    | A社   | D01
102    | B社   | D02

【受注明細表】
受注ID | 顧客ID | 商品ID | 数量
R001   | 101    | P001   | 10
R002   | 101    | P002   | 5
R003   | 102    | P001   | 3

最終改善:営業部門の名前を「営業」から「営業・企画統合部」に変えても、「部門表」の 1 行を変えるだけ。複数の場所を更新する心配がない ✓

正規化の段階を判定するコツ

  • 非正規形か?:1 つのセルに複数値(例:「R001, R002」)が入っているか
  • 第1正規形か?:繰り返し項目はないが、主キーの一部だけで決まる属性があるか(例:顧客ID だけで顧客名が決まるのに、受注テーブルに顧客名がある)
  • 第2正規形か?:主キー以外の属性間に依存関係があるか(例:部門ID から部門名が決まる)
  • 第3正規形?:矛盾がない「正規形」の完成

SQL(Structured Query Language)

SQL とは何か

SQL(Structured Query Language)は、RDB に対する「統一的な問い合わせ言語」です。Oracle、MySQL、PostgreSQL などどの DBMS を使っていても、基本的な SQL の文法は同じです。

試験で「SQL を読みこなせるか」「簡単な SQL を書けるか」は、情報通信技術の中で最も点数に直結する能力の一つです。なぜなら、実務でシステムが「どのような計算をしているのか」の大半は SQL で記述されているから。

SQL の 3 つの領域

SQL は目的別に 3 つに分かれます。試験では DML(SELECT など)が中心ですが、体系的に押さえておくと理解が深まります。

領域分類主要な命令役割試験での頻度
DDLデータ定義言語CREATE, ALTER, DROPテーブルやスキーマを定義・変更・削除低(選択肢に出現)
DMLデータ操作言語SELECT, INSERT, UPDATE, DELETEデータを取得・追加・更新・削除高(計算問題の中心)
DCLデータ制御言語GRANT, REVOKEアクセス権限を付与・剥奪低(概念問題)

このページでは DML の SELECT を中心に解説します。SELECT は、データベースから「誰の、どのデータを、どのように取り出すか」を表現する最も重要な命令です。

SELECT 文の処理順序

SQL 書く順番 ≠ 実行順番

これは多くの初学者が躓く点です。SQL を「記述する順番」と「実行される順番」が異なるのです。

SQL を書く順番】
SELECT 列名
FROM テーブル名
WHERE 条件
GROUP BY グループ列
HAVING グループ条件
ORDER BY ソート列

【実際に実行される順番】
1. FROM       -- どのテーブルから読むか
2. WHERE      -- 読んだ全行から、条件に合う行だけを残す
3. GROUP BY   -- 残った行をグループ化
4. HAVING     -- グループの条件で、さらに絞る
5. SELECT     -- 必要な列だけを選ぶ(集約関数を計算)
6. ORDER BY   -- ソート

なぜこの順番か?

RDB が物理的にデータを処理する流れを想像してください。

  1. FROM:まずテーブルを読みます。メモリに 100万行のデータが乗っていると想像してください。
  2. WHERE:全 100万行から「売上 > 100000」など条件に合う行だけを残します。1万行に減ったとします。
  3. GROUP BY:その 1万行を「顧客ID」でグループ化します。100グループになったとします。
  4. HAVING:グループの条件で絞ります。「各グループの受注件数が 2 件以上」なら、20グループが残ります。
  5. SELECT:最後に「表示する列」を決めます。元々は 50列あっても、SELECT で 3列だけ指定されていれば 3列だけになります。
  6. ORDER BY:その 20グループを売上順に並べます。

この流れをイメージできると、複雑な SELECT 文でも一行ずつ「何をしているのか」が見えます。

WHERE と HAVING の違い

ここが最重要です。

タイミング条件対象
WHEREグループ化(個別行)各行 1 つずつWHERE 売上 > 100000 → 売上 > 100000 の行だけを読み込む段階で残す
HAVINGグループ化(集計後)グループ全体HAVING COUNT(*) >= 2 → グループ化した後、受注件数が 2 件以上のグループだけを残す

具体例:顧客ごとの受注件数が 2 件以上で、かつ売上合計が 50万以上のグループを求める場合

SELECT
  顧客ID,
  COUNT(*) AS 受注件数,
  SUM(売上) AS 売上合計
FROM 受注表
WHERE 売上 > 0              -- WHERE:個別行。売上がプラスの受注だけを読み込む
GROUP BY 顧客ID
HAVING COUNT(*) >= 2        -- HAVING:グループ。受注件数が 2件以上
  AND SUM(売上) >= 500000   -- グループの合計売上が 50万以上
ORDER BY 売上合計 DESC;

処理の流れ:

  1. 売上 > 0 の受注行を読み込む(WHERE)
  2. 顧客ごとにグループ化
  3. 各グループが「受注件数 >= 2 かつ売上合計 >= 50万」なら残す(HAVING)
  4. 顧客ID、受注件数、売上合計を表示(SELECT)
  5. 売上合計の大きい順(ORDER BY)
役割処理のイメージ
FROM読み込むテーブルメモリにデータを乗せるFROM 受注表
WHERE行をフィルタメモリ上で、条件に合わない行を捨てるWHERE 売上 > 100000
GROUP BYグループ化残った行を「顧客ID」ごとにまとめるGROUP BY 顧客ID
HAVINGグループをフィルタグループの中から、条件に合わないグループを捨てるHAVING COUNT(*) >= 2
SELECT列を選択グループから表示する列を決めるSELECT 顧客ID, 売上合計
ORDER BYソート結果を売上順などに並べ替えるORDER BY 売上合計 DESC

WHERE 句で使う演算子と関数

WHERE 句の条件は、複数組み合わせることもできます。

演算子説明注記
=完全一致WHERE 顧客ID = 101数値でもテキストでも使える
<> or !=不一致WHERE 顧客ID <> 101<> が標準的(!= は非標準)
> / < / >= / <=大小比較WHERE 売上 >= 50000数値の範囲指定に使う
LIKE部分一致(ワイルドカード)WHERE 顧客名 LIKE 'A%'% = 任意の文字。'A%' = A で始まる
IN複数値のいずれかWHERE 顧客ID IN (101, 102, 103)OR を複数書く代わりに使える
BETWEEN範囲指定(両端含む)WHERE 売上 BETWEEN 10000 AND 50000>= 10000 AND <= 50000 と同じ
ANDかつWHERE 売上 > 50000 AND 顧客ID = 101複数条件の全てが満たす
ORまたはWHERE 売上 > 100000 OR 売上 < 10000複数条件の一つ以上が満たす
NOT否定WHERE NOT (顧客ID = 101)条件を反転
IS NULLNULL チェックWHERE 部門ID IS NULLNULL は = で比較できない(IS NULL を使う)
IS NOT NULLNULL でないWHERE 部門ID IS NOT NULLNULL 以外の値

集約関数

集約関数は、複数の行(グループ)の値を 1 つにまとめて計算します。試験では「何が対象か」を正確に理解することが重要です。

主要な集約関数

関数説明戻り値注記
COUNT()行数をカウント整数COUNT(*) = すべての行。COUNT(売上) = NULL を除いた行数NULL は数えない
SUM()合計を計算数値SUM(売上)NULL 値は 0 として扱わず、計算から除外
AVG()平均を計算数値AVG(売上)NULL は除外して計算
MAX()最大値を取得単一値MAX(売上)数値だけでなくテキストの最大(Z に近い)も可能
MIN()最小値を取得単一値MIN(売上)数値だけでなくテキストの最小(A に近い)も可能

GROUP BY と集約関数の組み合わせ

集約関数が本領を発揮するのは、GROUP BY と組み合わせた時です。

例:顧客ごとの売上合計を求める

SELECT
  顧客ID,
  SUM(売上) AS 売上合計
FROM 受注表
GROUP BY 顧客ID;

【結果イメージ】
顧客ID | 売上合計
101    | 150000
102    | 200000
103    | 80000

処理の流れ:

  1. 受注表のすべての行を読む
  2. 顧客ID でグループ化(顧客101 の行、102 の行、103 の行に分ける)
  3. 各グループの売上を合計(SUM)
  4. 顧客ごとに 1 行(計 3 行)の結果

GROUP BY なしで集約関数を使った場合

SELECT SUM(売上)
FROM 受注表;

【結果】
SUM(売上)
430000  ← 全行の合計

グループ化しないので、結果は 1 行だけになります。

集約関数と NULL の処理

NULL 値は、COUNT(*)には含まれますが、COUNT(列名)SUM()AVG() などには含まれません。 例:COUNT(売上) が 8 で、テーブルに 10 行あれば、2 行は売上 = NULL

SQL 計算例:WHERE、GROUP BY、HAVING の全パターン

-- 売上 > 10000 の受注で、顧客ごとに受注件数と売上合計を求める
-- ただし、受注件数が 2件以上の顧客だけを表示
-- 結果は売上合計の大きい順

SELECT
  顧客ID,
  COUNT(*) AS 受注件数,
  SUM(売上) AS 売上合計
FROM 受注表
WHERE 売上 > 10000              -- WHERE:個別行の条件
GROUP BY 顧客ID                 -- GROUP BY:顧客ごとに集計
HAVING COUNT(*) >= 2            -- HAVING:グループの条件
ORDER BY 売上合計 DESC;

処理の流れ(重要):

  1. FROM で受注表全体を読む(10 件あると仮定)
  2. WHERE 売上 > 10000 で条件に合う行だけを残す(5 件に減ったと仮定)
  3. GROUP BY 顧客ID で 5 件を顧客ごとにグループ化(顧客101=2件、102=2件、103=1件)
  4. HAVING COUNT(*) >= 2 で「受注件数 >= 2」のグループだけ残す(顧客101と102)
  5. SELECT で顧客ID、受注件数、売上合計の 3 列を表示
  6. ORDER BY で売上合計の大きい順にソート

データ例で追跡

【受注表(元データ)】
受注ID | 顧客ID | 売上
R001   | 101    | 20000   ← WHERE で残す
R002   | 101    | 15000   ← WHERE で残す
R003   | 101    | 5000    ← WHERE で削除(売上 <= 10000)
R004   | 102    | 30000   ← WHERE で残す
R005   | 102    | 25000   ← WHERE で残す
R006   | 103    | 40000   ← WHERE で残す
R007   | 103    | 8000    ← WHERE で削除

【WHERE 後】
受注ID | 顧客ID | 売上
R001   | 101    | 20000
R002   | 101    | 15000
R004   | 102    | 30000
R005   | 102    | 25000
R006   | 103    | 40000

【GROUP BY で集計、HAVING で絞った後】
顧客ID | 受注件数 | 売上合計
101    | 2       | 35000    ← HAVING で残す(2件以上)
102    | 2       | 55000    ← HAVING で残す(2件以上)
(103    | 1       | 40000) ← HAVING で削除(1件のみ)

【ORDER BY で結果ソート】
顧客ID | 受注件数 | 売上合計
102    | 2       | 55000    ← 売上合計が大きい
101    | 2       | 35000

このクエリで試験されるポイント

  • WHERE は「グループ化前」に「個別行」を絞る
  • HAVING は「グループ化後」に「グループ」を絞る
  • COUNT(*) と COUNT(列) の違い(NULL の扱い)
  • ORDER BY DESC は「大きい順」

JOIN の種類

JOIN は、複数の表を「関連キー」で結合する操作です。正規化された RDB では、表を分割しているため、必ず JOIN が出てきます。試験では INNER JOIN と LEFT OUTER JOIN が中心です。

JOIN の種類と結果行数

JOIN 種類説明結果行数使用場面出力の特徴
INNER JOIN両方の表に存在するペアのみ少ない確実に関連データがある行だけが必要NULL がない
LEFT OUTER JOIN左表全て + 右表と共通の行左表の行数左表のすべてのデータを残したい右表に対応なし → NULL
RIGHT OUTER JOIN右表全て + 左表と共通の行右表の行数右表のすべてのデータを残したい左表に対応なし → NULL
FULL OUTER JOIN両表全て最多全データを漏らさず取得(DBMS 非互換)両側で NULL あり得る
CROSS JOIN全ての組み合わせm × n直積。通常は不要すべての組み合わせ

JOIN の仕組み

理解しやすいように、図で表現します。

【顧客表】          【受注表】
顧客ID 顧客名      受注ID 顧客ID 売上
101   A社        R001   101    100000
102   B社        R002   101    50000
103   C社        R003   102    80000
                 R004   104    60000 ← 顧客ID 104 は顧客表にない

【INNER JOIN の結果】← 両方の表に存在する行だけ
顧客ID 顧客名 受注ID 売上
101   A社   R001   100000
101   A社   R002   50000
102   B社   R003   80000

→ R004(顧客104)と顧客103(受注なし)は消える

【LEFT OUTER JOIN の結果】← 左表全て + 右表の共通行
顧客ID 顧客名 受注ID 売上
101   A社   R001   100000
101   A社   R002   50000
102   B社   R003   80000
103   C社   NULL   NULL    ← 顧客103は受注がないので右側が NULL

→ 顧客103は残る。顧客104(受注側だけ)は消える

LEFT OUTER JOIN で重要なポイント

FROM 顧客表 LEFT JOIN 受注表 とすると、顧客表がベースになります。 結果として「受注がない顧客も含めて全顧客が表示される」ことになります。

反対に FROM 受注表 LEFT JOIN 顧客表 とすると、受注表がベースなので「顧客がない受注」も含まれます(あれば)。

JOIN の具体例:INNER JOIN vs LEFT OUTER JOIN

データセット:

【顧客表】          【受注表】
顧客ID 顧客名      受注ID 顧客ID 売上
101   A社        R001   101    100000
102   B社        R002   101    50000
103   C社        R003   102    80000

例1:INNER JOIN(受注がある顧客だけを表示)

SELECT
  顧客表.顧客ID,
  顧客表.顧客名,
  受注表.受注ID,
  受注表.売上
FROM 顧客表
INNER JOIN 受注表 ON 顧客表.顧客ID = 受注表.顧客ID
ORDER BY 顧客表.顧客ID;

【結果】
顧客ID | 顧客名 | 受注ID | 売上
101    | A社   | R001   | 100000
101    | A社   | R002   | 50000
102    | B社   | R003   | 80000
← 顧客103(C社)は受注がないので出現しない

実務イメージ:「受注があった顧客だけのリスト」が必要な時(請求書作成など)

例2:LEFT OUTER JOIN(全顧客を表示、受注がなければ NULL)

SELECT
  顧客表.顧客ID,
  顧客表.顧客名,
  受注表.受注ID,
  受注表.売上
FROM 顧客表
LEFT OUTER JOIN 受注表 ON 顧客表.顧客ID = 受注表.顧客ID
ORDER BY 顧客表.顧客ID;

【結果】
顧客ID | 顧客名 | 受注ID | 売上
101    | A社   | R001   | 100000
101    | A社   | R002   | 50000
102    | B社   | R003   | 80000
103    | C社   | NULL   | NULL   ← 顧客103も表示(受注なし)

実務イメージ:「すべての顧客をリストアップし、受注実績があれば表示、なければ『未受注』と表示」

どちらを使うか

  • 「受注と関連する顧客」→ INNER JOIN
  • 「すべての顧客(受注の有無を問わず)」→ LEFT OUTER JOIN

サブクエリと相関サブクエリ

種類説明実行パターン
非相関サブクエリ独立したクエリを内側で実行内側を 1 回実行、その結果を外側で使うWHERE 顧客ID IN (SELECT 顧客ID FROM ...)
相関サブクエリ外側の値を参照しながら実行外側の各行に対し内側を毎回実行WHERE 売上 > (SELECT AVG(売上) FROM ... WHERE 同じ顧客)

トランザクション

トランザクションとは何か

トランザクション(transaction)は、「複数の操作をセットで扱い、『全て成功するか全て失敗するか』のいずれかにする」仕組みです。

最もわかりやすい例が「銀行振込」です:

  1. あなたの口座から 100万円を出金
  2. 相手の口座に 100万円を入金

この 2 つの操作を想像してください。もし途中で停電が起きて、「出金は成功したが入金は失敗」という状態になったら、あなたの 100万円が消えます。

トランザクションは、この問題を防ぎます。「出金と入金は 1 つの仕事(トランザクション)。途中で止まったら、両方リセット」という約束になります。

ACID 特性

トランザクション処理が安全であるためには、4 つの特性が必要です。試験ではこれらを「何を保証するのか」を理解することが重要です。

特性日本語意味実例違反時の問題
A原子性操作は「全て成功」か「全て失敗」か。中途半端はない出金と入金の両方が成功するか、両方失敗するか出金だけ成功、入金失敗 → 金額消失
C一貫性トランザクション前後でデータ整合が保たれる出金前の総残高 = 出金後の総残高(個人間での移動だから)1 回の操作で残高が 2 倍に減る
I独立性同時に複数のトランザクションが走ってても干渉しないAさんとBさんが同時に振込しても、結果に矛盾がないAさんの未確定値を読んでBさんが計算(ダーティリード)
D永続性コミット(確定)したら、障害があってもデータは残る「振込完了」と表示したら、電源が切れてもお金は移動しているコミット直後にクラッシュで反映消失

ACID 特性と実装技術の対応

「ACID 特性」は理想。それを実現するのが実装技術です。

特性実装方法具体例
原子性コミット/ロールバックトランザクション開始 → 複数操作 → コミット(全て記録)or ロールバック(全て破棄)
一貫性制約チェック外部キー制約(親行がないのに子行は作らない)、CHECK 制約(売上が負数でない)
独立性排他制御(ロック)トランザクションA が口座データを「独占ロック」→ トランザクションB は待機 → A がコミット/ロールバック → B が実行
永続性ログファイル + ディスクフラッシュすべてのコミット済み操作をログに記録。定期的にディスクに永続化

ACID 特性の本質

ACID は「トランザクション処理が何を約束するか」です。データベースが「複数の操作を確実に扱える」ことを保証します。

排他制御(ロック)

トランザクション間の干渉を防ぐため、ロックを使用します。ロックは「データに対する独占権」のようなものです。

ロックの 2 つの種類

ロック種類日本語説明複数トランザクションでの共有使用場面
共有ロック(S ロック)読み取りロック読み取り専用。複数トランザクションで同時に取得可能複数 OK(全て読み取り)SELECT 時。複数のトランザクションが同時に読んでも矛盾しない
占有ロック(X ロック)書き込みロック書き込み・削除用。他のすべての操作を排除1つだけ(排他的)UPDATE / DELETE 時。この操作の途中で他がデータを読んだり変更したりできない

ロック競合の実例

タイムライン:
トランザクション A                     トランザクション B
1. 顧客ID=101 の残高を読む(S ロック取得)
   (読み取り開始。この間、他も読める)
2. 残高 = 100万 を確認
3.                                  顧客ID=101 の残高を更新したい(X ロック必須)
4.                                  → X ロックを要求
5.                                  → 待機(A が S ロックを持ってるから取得できない)
6. トランザクション A がコミット
   (S ロック解放)
7.                                  X ロック取得可能に
8.                                  残高を 50万に更新
9.                                  コミット
   (X ロック解放)

この流れにより、A のコミット前の未確定な値を B が使ってしまう問題が防止されます。

ロックの直感的理解

  • S ロック:「本を読む」→複数人が同時に読める
  • X ロック:「本を編集する」→1人だけ。編集中に他人は読んだり編集したりできない

デッドロック

相互に相手のロック解放を待つ状態が「デッドロック」です。データベースは自動的に検出して解決します。

トランザクション A        トランザクション B
1. 顧客テーブル1 を X ロック取得
2.                       商品テーブル2 を X ロック取得
3. 商品テーブル2 の X ロックを要求
4.                       → テーブル2 は B が持ってる(待機)
5.                       顧客テーブル1 の X ロックを要求
6.                       → テーブル1 は A が持ってる(待機)
7. 互いに待機状態 ← デッドロック発生

DBMS がタイムアウトで検出 → 一方を強制中止 → ロック解放 → 他方が再開

対策

  • ロック取得順序を統一する(常に「顧客テーブル」→「商品テーブル」)
  • トランザクション時間を短くする
  • タイムアウト値を設定する

コミットとロールバック

トランザクションは開始から終了まで、以下のいずれかで完結します:

命令役割実際の効果タイミング
COMMITトランザクション確定変更がディスクに永続化。ログに記録。ロック解放。以降の読み取りに反映トランザクション成功時
ROLLBACKトランザクション取消すべての変更を破棄して初期状態に戻す。ロック解放。他のトランザクションは待機解除エラー発生時や明示的取消

実例

BEGIN TRANSACTION;
  UPDATE 顧客表 SET 残高 = 残高 - 100 WHERE 顧客ID = 1;
  UPDATE 顧客表 SET 残高 = 残高 + 100 WHERE 顧客ID = 2;
-- ここまでのすべての操作は「未確定」。他のトランザクションには見えない
COMMIT;  -- または ROLLBACK;
  • COMMIT を実行 → 両方の UPDATE が確定。他のトランザクションから見える
  • ROLLBACK を実行 → 両方の UPDATE が破棄。顧客の残高は変わらない

バックアップとリカバリ

背景:なぜバックアップが必要か

企業システムのデータベースには、毎日膨大な重要データが記録されます。売上、顧客情報、在庫、給与データなど。これらが消えたら企業は機能しません。

障害は必ず起きます。ハードディスク故障、停電、ウイルス感染、誤削除。だから、バックアップ(データのコピー)を定期的に取得し、問題が起きた時に復旧できるようにしておくのです。

しかし、バックアップを取るだけでは不十分。実際に「取得したバックアップから本当に復旧できるか」をテストするまで含めて初めて有効です。

バックアップの 3 つの種類

容量と時間のトレードオフで、3 つを組み合わせます。

種類説明対象ファイル容量リカバリ速度用途頻度
フルバックアップデータベース全体をコピーすべてのデータ最大(例:500GB)最速(1回復元)定期的な確実な保存週1回など
差分バックアップ前回フルバックアップ以降の変更分だけコピー変更されたデータのみ中程度中程度(フル+差分)毎日の更新を記録毎日
増分バックアップ前回のバックアップ(フル or 増分)以降の変更分だけコピー最小限の変更データ最小(例:1GB)最遅(フル+増分×N)高頻度で更新を記録毎時間

バックアップ戦略の典型例

【時系列】
日曜 23:00 フルバックアップ取得(500GB)
月曜 23:00 差分バックアップ(日曜フル以降の累積変更分:50GB)
火曜 23:00 差分バックアップ(日曜フル以降の累積変更分:100GB)
水曜 23:00 差分バックアップ(150GB)
木曜 23:00 差分バックアップ(200GB)
金曜 12:00 増分バックアップ(前回バックアップ以降の変更分、10GB)
金曜 13:00 増分バックアップ(10GB)
...

【金曜 15:00 に障害が発生した場合】
1. 日曜のフルバックアップから復元(500GB 復旧、データは日曜時点)
2. 木曜の差分バックアップを適用(データは木曜 23:00 時点)← 差分は最新の1つだけでよい
3. 金曜の 14:00 の増分バックアップまで時系列に適用(データは金曜 14:00 時点)
→ ほぼ全データが復旧。損失は 14:00〜15:00 の 1 時間分だけ

容量と速度のトレードオフ

  • 毎回フルを取れば「復旧は速い」が「容量とコストが膨大」
  • 増分だけを取れば「容量は小さい」が「復旧に時間がかかる」
  • だから「フル + 差分 + 増分」の組み合わせが実務的

リカバリの方法

バックアップから復旧する際の 3 つの操作:

方法タイミング説明具体例
ロールバック障害直後トランザクションログを使って、未確定の途中操作を取り消すシステムクラッシュ時に「最後のコミット」まで戻す
ロールフォワードバックアップ復元後トランザクションログを再実行して、バックアップ以降の確定済み操作を復元フルバックアップ(日曜)から復元した後、月〜金の操作を再実行
チェックポイント定期的(計画)DBMS が定期的に「今この瞬間、整合性が取れた状態」を記録毎時間ごとにチェックポイントを作成。リカバリ開始点を減らす

リカバリの実際の流れ

【トランザクションログ記録】
コミット済み操作1(売上確定)
コミット済み操作2(在庫更新)
コミット済み操作3(入金記録)
途中の操作4(給与計算中→クラッシュで未確定)
...

【復旧手順】
1. 最後のバックアップから復元
2. ロールバック:途中の操作4を取り消す
3. ロールフォワード:操作1, 2, 3 をもう一度実行
→ データベースが「クラッシュ直前の確定状態」に復元

バックアップの落とし穴

「毎週金曜夜にバックアップを取っている」と安心していても、実は取得に失敗していた。あるいは取得されたファイルが破損していた。 → 「バックアップの取得」だけでなく「復旧テスト」を定期的に実施する必要がある。


ビューとインデックス

ビュー(View)

ビューは、「複数の表から必要なデータだけを取り出す『仮想的な表』」です。物理的には存在せず、定義(SELECT 文)だけが保存されます。

ビューの仕組み

【元データ:受注表】
受注ID | 顧客ID | 社員ID | 売上 | 売上日
R001   | C001   | E01    | 100000 | 04-15
R002   | C001   | E02    | 50000  | 04-15
R003   | C002   | E01    | 80000  | 04-16
...(数百万行)

【ビュー定義】
CREATE VIEW 営業成績 AS
SELECT
  社員ID,
  COUNT(*) AS 受注件数,
  SUM(売上) AS 売上合計
FROM 受注表
GROUP BY 社員ID;

【営業成績ビューを SELECT
SELECT * FROM 営業成績
WHERE 売上合計 > 100000;

【内部的な処理】
→ 定義されたSELECT文を実行
→ 結果が返される
(毎回、もとのテーブルから計算される)

ビューの特性

特性説明活用例
実体なしディスク上にデータを持たない。定義(SQL)だけ保存容量節約
遅延評価ビューを SELECT するたびに、定義のSELECT が実行される常に最新データが見える
更新可能性単純なビュー(1 表のみ)は更新可能。複雑なビューは読み取り専用複雑な計算結果は修正できない
セキュリティ不要な列を隠せる。営業部門には「売上」だけ見せて「原価」は非表示データ保護

インデックス(Index)

インデックスは、「データベース検索を高速化するための補助構造」です。本の「索引」に似ています。

インデックスの仕組み

「顧客ID で受注を検索」する場合を想像してください。

インデックスなし(線形探索):

受注表:R001, R002, R003, R004, ..., R1000000
顧客ID = C001 を探す
→ 最初から全部見て、C001 を見つけるまで探索
→ 運が悪いと 500万行確認(時間がかかる)

インデックスあり(B+ ツリー)

【インデックス】
A | B | C | D | ...  ← アルファベット順

顧客C の行の位置へ直接ジャンプ
→ 数十行の確認で発見(高速)

インデックスの選択基準

指標判定
検索頻度高い列WHERE 句でよく使われる顧客ID
更新頻度低い列ほぼ変わらないID。逆に「日次更新」される「残高」にインデックスを張るとムダ
カーディナリティ高い(重複少ない)列顧客ID(複数) vs 性別(男女だけ) → 前者が効果的

インデックスの誤解

「インデックスを多く張れば検索が早くなる」は間違い。

  • INSERT / UPDATE / DELETE のたびにインデックスも更新が必要 → コスト増
  • インデックス自体もメモリ・ディスク消費 → 「このインデックスは本当に必要か」を問い直す必要あり

現実的な方針:主キー と外部キー は必須。WHERE で頻出の列を厳選。

-- インデックス作成
CREATE INDEX idx_顧客ID ON 受注表(顧客ID);

-- 複合インデックス(複数列)
CREATE INDEX idx_顧客日付 ON 受注表(顧客ID, 売上日);

-- インデックス削除
DROP INDEX idx_顧客ID;

過去問で戻りやすい補助論点

マスタデータ、トランザクションデータ、参照整合性

実務の業務システムでは、データを大きく マスタデータトランザクションデータ に分けて考えます。この区別ができると、どの表を先に作るかどの入力欄が自由入力かどこに外部キーが入るか が見えやすくなります。

種類役割代表例特徴典型的な関係
マスタデータ基準となる台帳顧客マスタ、商品マスタ、部門マスタ比較的安定。コード体系を持つ参照される側
トランザクションデータ日々発生する事実受注、出荷、入金、仕訳件数が多く、時系列で増える参照する側

受注システムなら、商品コード顧客コード はマスタに登録されており、受注入力画面ではそのコードを参照してトランザクションを記録します。

【商品マスタ】
商品ID | 商品名 | 標準単価
P001   | 部品A | 1200
P002   | 部品B | 800

【受注トランザクション】
受注ID | 商品ID | 数量 | 受注日
R001   | P001   | 10   | 04-01
R002   | P002   |  5   | 04-02

このとき 受注トランザクション.商品ID は、商品マスタ.商品ID を参照する外部キーです。参照整合性があるので、存在しない商品コード P999 を誤って入力することを防げます。

ヘッダ、明細、マスタで正規化を読む

正規化問題では、どの列を別表へ追い出すか を感覚で決めるのではなく、受注全体で1回決まるか行ごとに変わるか安定した基準データか で切り分けます。特に過去問では、主キー全体への従属 を見落とすと正誤判断を誤りやすいです。

置き場所何が入るか典型例判断のコツ
ヘッダ1 件の取引全体で 1 回決まる情報受注番号、受注日、顧客ID明細行が増えても値が変わらない
明細行ごとに変わる情報商品ID、数量、行番号受注番号 + 行番号 のような複合キーになりやすい
マスタ他表から繰り返し参照される基準情報商品名、標準単価、顧客名、部門名コードが決まれば安定して決まる

たとえば主キーが 受注番号 + 行番号 のとき、数量 は主キー全体に従属しますが、商品名標準単価商品ID だけで決まります。このような列は明細に持たせ続けるより、商品マスタへ置いた方が重複や更新異常を防ぎやすくなります。

条件式の組み立て:AND / OR / NOT、括弧、IF / CASE

試験では、SQL の WHERE 句だけでなく、表計算ソフトの IF 関数や SQL の CASE 式のような条件分岐も、条件をどう束ねるか という同じ考え方で問われます。重要なのは、どの条件が先に評価されるか を明示することです。

優先順位演算子意味
1NOT否定
2ANDすべて満たす
3ORどれかを満たす

たとえば、A または B かつ C をそのまま書くと、B かつ C が先に評価されます。

-- この式は A OR (B AND C) と同じ
WHERE= '赤'
   OR= '青' AND 数量 >= 10

(A または B) かつ C にしたいなら、括弧が必要です。

WHERE (色 = '赤' OR= '青')
  AND 数量 >= 10

条件分岐を文章で読むときは、次の順に整理すると混乱しにくくなります。

  1. まず何を満たせば Yes 側に入るか
  2. それが複数条件の AND か OR か
  3. 例外条件を NOT で除外しているか

IF 関数や CASE 式での考え方 も同じです。

CASE
  WHEN 売上 >= 100000 AND 利益率 >= 0.2 THEN 'A'
  WHEN 売上 >= 100000 THEN 'B'
  ELSE 'C'
END

これは、「上から順に判定し、最初に当てはまった枝で確定する」条件分岐です。表計算ソフトのネストした IF も、実質的には同じ構造だと理解してください。

入力画面とデータベース設計のつながり

入力画面の部品は、何を入力させたいかその値がどこから来るか で選びます。試験では、マスタデータを選ばせるのか、自由入力させるのかを見抜けるかがポイントです。

UI 部品使いどころ背後のデータ
テキストボックス自由に文字や数値を入力トランザクション値や名称顧客名、数量、備考
ドロップダウン候補が少なく、1つ選ばせるマスタデータ参照部門、都道府県、商品分類
リストボックス候補が多く、一覧から選ばせるマスタデータ参照仕入先一覧、担当者一覧
ラジオボタン候補が少なく、選択肢を常時見せたい固定コード性別、支払方法
チェックボックスYes / No や複数選択真偽値や複数属性同意、通知設定

判断の軸は次の 3 つです。

  1. 候補が固定されているか
  2. 候補数が少ないか多いか
  3. マスタから選ぶのか、その場で新規入力するのか

たとえば 商品区分 のように候補が固定されているなら、テキストボックスで自由入力させると表記ゆれが起きやすくなります。マスタを用意し、ドロップダウンやリストボックスから選ばせる方が設計として自然です。

JOIN と GROUP BY は「残す行」と「1行の単位」で考える

SQL の選択肢問題では、どの結合を使うかどの列でまとめるか が一緒に問われることがあります。このときは、まずどの行を残すか次に結果1行の単位を何にするか の順で考えると崩れません。

論点最初に見ること典型的な読み方
INNER JOIN両方に存在する行だけでよいか購入実績がある会員だけを出す
LEFT OUTER JOIN左側の表をすべて残したいか購入がない会員も含める
GROUP BY結果 1 行を何の単位にするか顧客別なら 顧客ID、商品別なら 商品ID

購入回数を会員ごとに表示 なら、まず 会員を全部残すか / 購入実績がある人だけでよいか を決め、その後で 会員IDごとに集約 します。COUNT(*)SUM(売上) のような集約結果そのものは GROUP BY に入れません。1 行をどの単位で作るか を表す列だけを置きます。

否定条件と重複除去の読み方

過去問では <> や自己結合を使って、ある条件を満たさない行同じ組合せの重複 を除く問題が出ます。ここは演算子を記号のまま追うより、日本語へ戻す方が安全です。

書き方日本語での意味よくある誤り
A <> 'g'A が g ではないA = g の逆と意識できず読み飛ばす
NOT (A AND B)A と B を同時には満たさないNOT A AND B と同一視する
A.商品ID < B.商品ID同じ組合せを 1 回だけ数えるA-BB-A を二重計上する

自己結合で 商品A と商品B の組合せ を求めると、条件がないと A-BB-A が両方出ます。そこで A.商品ID < B.商品ID のように大小条件を付けて、片方だけ残します。不等号は大小比較 であると同時に、重複除去のためのルール として使われることも押さえてください。

分析用データ基盤:DWH、データマート、データレイク、データクレンジング

日々の受注や会計処理を行う 業務DB(OLTP) と、分析のためにデータをためる基盤は役割が違います。ここを混同すると、DWH とデータレイク の設問で落としやすくなります。

用語主目的主なデータスキーマの考え方典型用途
業務DB(OLTP)日々の更新処理受注、入金、在庫更新先に厳密に定義受発注、会計、在庫管理
データウェアハウス(DWH)分析用に統合・蓄積複数システムの構造化データ先に定義してから格納経営分析、BI
データマートDWH の部門別サブセット営業用、財務用などの分析データDWH を用途別に切り出す部門別レポート
データレイク元データを広くためる構造化・半構造化・非構造化後で読み方を決めるIoT、ログ、画像、SNS
データクレンジング分析前の品質改善重複、欠損、表記ゆれの修正データそのものを整える処理顧客名の表記統一

覚える軸は、先に形を決めるか何のためにためるか です。

  • DWH分析しやすい形に整えてから ためる
  • データレイク元の形式のまま広く集めて、後で読む
  • データマートDWH の一部を目的別に切り出したもの
  • データクレンジング置き場ではなく、データ品質を整える処理

DWH とデータレイクの切り分け

スキーマを先に決めて、分析しやすい表で持つ なら DWH、まず集めてから必要なときに読み方を決める ならデータレイクです。試験ではこの schema-on-writeschema-on-read の違いが本質です。

SQL の集合演算:UNION、UNION ALL、INTERSECT、EXCEPT

JOIN は 列をつなぐ 操作ですが、集合演算は 行の集合どうしを比べる 操作です。ここを混同しないことが大切です。

演算役割重複の扱い典型的な使い方
UNION2つの結果を統合重複を除く東京店の顧客一覧 ∪ 大阪店の顧客一覧
UNION ALL2つの結果をそのまま連結重複を残す売上明細を月別に単純連結
INTERSECT両方にある行だけ残す共通部分だけ両キャンペーン対象の顧客
EXCEPT前者にだけある行を残す差集合会員だが購入実績がない顧客

前提として、集合演算では 列数列の意味 がそろっている必要があります。顧客ID, 顧客名商品ID, 商品名 を UNION するのは不適切です。

-- 列をつなぐ JOIN
SELECT c.顧客名, o.売上
FROM 顧客表 c
JOIN 受注表 o ON c.顧客ID = o.顧客ID;

-- 行を統合する UNION
SELECT 顧客ID FROM 東京店会員
UNION
SELECT 顧客ID FROM 大阪店会員;

JOIN は 顧客表に売上列を付ける 発想、UNION は 同じ意味の顧客ID集合を縦にまとめる 発想です。


典型的なつまずき

つまずき 1:主キーと外部キーの役割の混同

誤り:「どちらも表をつなぐもの」と思う

正解

  • 主キー:「この行を識別するユニークな属性」。顧客101は A社、顧客102は B社。個を区別
  • 外部キー:「別の表の主キーを参照する属性」。受注の顧客ID = 101 という「このレコードは顧客101のもの」という指標

試験対策:表の構造図を見た時、「PK は何か」「FK は何の FK か」を最初に確認

つまずき 2:正規化を「表を増やすこと」と勘違い

誤り:「正規化すると表が増える」→「表を増やせば正規化」

正解:「同じ情報の重複を減らすこと」が目的。副作用として表が増える

実例

  • 正規化前:受注テーブルに顧客名が繰り返される
  • 正規化後:顧客テーブルを独立させる → 表は 1 → 2 に増えたが、目的は「顧客名の繰り返し削減」

試験対策:「この異常は何か(更新異常か、削除異常か)」を聞かれたら、「重複による矛盾」を思い出す

つまずき 3:SQL を「記述順に実行」と思う

誤り

SELECT 列名             ← これが最初に実行
FROM テーブル          ← これが 2 番目
WHERE 条件             ← これが 3 番目

正解:FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY

具体的な混同:「SELECT で列を絞ったから、WHERE で NULL は参照できない」と思うが、WHERE は SELECT より前に実行されるので、SELECT されてない列でも WHERE では参照可能

試験対策:「処理順序を書け」という問題では、FROM から始めることを刻み込む

つまずき 4:JOIN の方向が逆

誤りFROM 受注表 LEFT OUTER JOIN 顧客表 で「受注がない顧客を見たい」

正解FROM 顧客表 LEFT OUTER JOIN 受注表 で「全顧客 + 受注がない顧客も含める」

理由:LEFT は左側(FROM)の表をすべて残す

試験対策:「何をすべて残したいのか」を決めてから、その表を LEFT 側に置く

つまずき 5:WHERE と HAVING の使い分け

誤り:「どちらも条件を絞る句だから同じ」

正解

  • WHERE:グループ化「前」の個別行を絞る
  • HAVING:グループ化「後」のグループを絞る

具体例:「受注件数が 2 件以上で、かつ最近の受注は 1 月以降」

SELECT 顧客ID
FROM 受注表
WHERE 受注日 >= '04-01'WHERE:行レベル
GROUP BY 顧客ID
HAVING COUNT(*) >= 2HAVING:グループレベル

つまずき 6:トランザクションを「1 行の UPDATE」と混同

誤り:「UPDATE 1 行 = トランザクション 1 件」

正解:「複数の操作をセットで扱う」仕組み

具体例:振込は「出金 + 入金」の 2 操作で 1 トランザクション

つまずき 7:バックアップを取得しただけで安心

誤り:「毎週木曜に自動バックアップを取っているから大丈夫」

正解:「本当に復旧できるか」のテストを含めて初めて有効

現実的な問題

  • バックアップファイルが破損していた
  • 取得に失敗していた
  • 取得ファイルが別の場所に保存されて、災害で失った

試験対策:「バックアップとリカバリテストはセット」と覚える

つまずき 8:マスタとトランザクションを逆に考える

誤り:「受注データがマスタで、商品一覧がトランザクション」

正解

  • マスタ は基準となる台帳
  • トランザクション は日々発生する事実

見分け方更新頻度が低く、他の表から参照されるか を見る

つまずき 9:AND と OR の優先順位を読み違える

誤りA OR B AND C(A OR B) AND C だと思う

正解:括弧がなければ AND が先。つまり A OR (B AND C) と読む

試験対策:条件が 3 つ以上あるときは、必ず括弧付きの論理式に書き直す

つまずき 10:JOIN と UNION を同じ「表をまとめる操作」だと思う

誤り:「顧客表と受注表を UNION でまとめる」

正解

  • JOIN:キーで結び、列を横に増やす
  • UNION:同じ意味の列集合を縦に積む

試験対策横に広げるか、縦に積むか を最初に決める

つまずき 11:DWH とデータレイクを同じ「大きい保存場所」だと思う

誤り:「どちらも大量データをためる場所だから同じ」

正解:DWH は分析しやすい形に整えてから蓄積、データレイクは元データを広く蓄積して後で読む

試験対策スキーマを先に決めるか後に決めるか を判断軸にする

つまずき 12:複合キーを見落として、主キー全体への従属を判定できない

誤り:「受注番号があるから、この表は受注単位で決まる」と見てしまう

正解受注番号 + 行番号 のような複合キーなら、数量 は主キー全体に従属し、受注日 は受注番号だけに従属し、商品名 は商品IDだけに従属します。まず主キーを確定させ、その次に ヘッダ / 明細 / マスタ で列の置き場所を判定します。

つまずき 13:JOIN で残す行の範囲と GROUP BY の粒度を混同する

誤り:「会員ごとに購入回数を出す」問題で、COUNT(*)GROUP BY に入れる、あるいは LEFT OUTER JOININNER JOIN を気分で選ぶ

正解:JOIN は どの行を残すか、GROUP BY は 1 行を何の単位にするか を決めるものです。購入がない会員も含める なら LEFT OUTER JOIN購入した会員だけ なら INNER JOIN会員ごとの件数 なら GROUP BY 会員ID です。

つまずき 14:<> や自己結合の大小条件を読み飛ばす

誤りA <> 'g' を軽く流したり、A.商品ID < B.商品ID の意味を理解しないまま選ぶ

正解<> は否定条件、大小条件は重複除去のために使われることがあります。条件式は日本語へ戻し、何を除外したいのか を先に言い換えると読み違えにくくなります。


問題を解くときの観点

試験問題には「パターン」があります。問題の種類を見分けることが、迷わない解法の第一歩です。

問題のパターン判定

見た瞬間、以下のいずれかを確認:

パターン見分け方解法の第一歩
表の構造問題テーブル定義が示されている。「何正規形か」「異常は何か」が問われる重複している属性を探す。何がなぜ繰り返されるか
SQL 読み取りSQL 文が示されて、結果を推測させられるFROM → WHERE → GROUP BY の実行順を追う
条件式・UI 設計IF / CASE、入力部品、マスタ参照が問われる候補が固定か、自由入力か、条件の優先順位は何かを見る
トランザクション複数操作が並行に起きている。「矛盾は何か」「ロックは何か」が問われる途中で止まったら困ることは何か
データ基盤比較DWH、データマート、データレイク、クレンジングが並ぶ目的、スキーマ時点、扱うデータの種類を比べる
バックアップ障害状況が説明される。「何を取得」「どう復旧」が問われるバックアップの時点と復旧のポイントを時間軸で整理

SQL 読み取り問題のステップ

【問題:このクエリの結果は?】
SELECT 顧客ID, COUNT(*) AS 件数
FROM 受注表
WHERE 売上 > 50000
GROUP BY 顧客ID
HAVING COUNT(*) >= 2
ORDER BY 件数 DESC;

【解法ステップ】
1. 「処理順序は FROM → WHERE → ... ORDER BY」を思い出す
2. FROM:受注表全体を読む(例:10万行)
3. WHERE 売上 > 50000:絞る(例:5万行に減る)
4. GROUP BY 顧客ID:顧客ごとにグループ化(100グループ)
5. HAVING COUNT(*) >= 2:受注件数が 2件以上のグループだけ(50グループ)
6. SELECT:顧客IDと件数を表示
7. ORDER BY:件数の大きい順
→ 答え:受注が 2件以上で売上 > 50000 のグループ

正規化問題のステップ

【問題:この表は何正規形か。何が問題か】
社員ID | 社員名 | 部門ID | 部門名 | スキルID
E001   | 田中   | D01    | 営業   | S001, S002
E002   | 佐藤   | D01    | 営業   | S001

【解法ステップ】
1. 繰り返し項目があるか? → スキルID が複数値 → 非正規形
2. 主キーは何か? → `社員ID` だけか、`社員ID + スキルID` の複合キーかを先に確定
3. 主キー全体に依存しない属性があるか? → 部門名は部門ID だけで決まる(社員ID は不要) → 第2正規形未満
4. `ヘッダ / 明細 / マスタ` のどこへ置くべきか → 部門名は部門マスタ側
5. 起きる異常は? → 「営業部門の名前を変えると、全社員レコードを更新が必要」 → 更新異常
→ 答え:非正規形。繰り返し項目を削除して第1正規形へ。次に部門名を分割して第2正規形へ

トランザクション問題のステップ

【問題:A と B が同時に同じ口座に入金する場合、何が起きるか】

【解法ステップ】
1. 「ACID の何に関係するか」を問う → 独立性(Isolation)
2. 「具体的に何が困るか」を説明 → 両方が最新残高を読んで計算すると、片方の入金が反映されない
3. 「対策は」 → 排他制御。1 人が書き込みロック(X)を取得 → 他方は待機 → ロック解放
→ 答え:独立性違反。更新競合やロストアップデートの危険がある。ロックで対策

条件式・集合演算問題のステップ

【問題:この条件式はどのデータを返すか】

【解法ステップ】
1. AND / OR / NOT を、括弧つきの論理式へ書き直す
2. `<>` や `NOT` があれば、日本語で「何を除外する条件か」を先に言い換える
3. 条件が「個別行の判定」か「表どうしの統合」かを判定する
4. 横に広げるなら JOIN、縦に積むなら UNION 系を選ぶ
5. 自己結合なら、`A-B` と `B-A` の重複をどう防ぐかを見る
6. UNION なら、列数と列の意味がそろっているかを確認する
→ 答え:条件の優先順位と、JOIN / UNION の役割差から決める

データ基盤・入力設計問題のステップ

【問題:DWH、データレイク、データマート、入力部品のどれが適切か】

【解法ステップ】
1. 目的が「日々の更新」か「分析」かを判定する
2. スキーマを先に決めるか、後で決めるかを見る
3. 入力欄なら、候補が固定か自由入力かを確認する
4. マスタを参照するならドロップダウン / リスト、自由入力ならテキストを基本に考える
→ 答え:役割とデータ源の違いで切り分ける

確実な得点の心がけ

  • 「表の構造」を見た時:キーの位置を確認。FK が指す先を追跡
  • 「SQL 文」を見た時:実行順序(FROM 最初!)を書く
  • 「条件式」を見た時:AND と OR を括弧付きに書き直す
  • 「分析基盤」を見た時:業務処理か分析か、スキーマをいつ決めるかを見る
  • 「複数操作」を見た時:「途中で止まると困るか」を判定
  • 「日付」が出た時:バックアップはいつ。復旧はどの時点か

確認問題

確認問題 1:正規化の段階判定

下の表は何正規形ですか。また、どの異常が起きやすいか答えよ。

表:社員表

社員ID | 社員名 | 部門ID | 部門名 | プロジェクトID
E001  | 田中  | D01   | 営業   | P001, P002
E002  | 佐藤  | D01   | 営業   | P001

解答

  • 非正規形。プロジェクトIDに繰り返し項目がある。
  • 正規化すると:まず繰り返し項目を排除して第1正規形(社員-プロジェクト関連を独立表へ)。
  • 次に部門名が部門ID に従属していることに気づき、部門表を独立させて第3正規形へ。
  • この例では「営業部門の名前を変更する時、複数の社員レコードを更新しなければならない(更新異常)」が起きやすい。

確認問題 2:SQL 結果の読み取り

以下のクエリを実行した結果を示せ。(WHERE と HAVING の違いを理解しているか確認)

SELECT
  顧客ID,
  COUNT(*) AS 受注件数,
  SUM(売上) AS 売上合計
FROM 受注表
WHERE 売上 >= 50000
GROUP BY 顧客ID
HAVING COUNT(*) >= 2
ORDER BY 売上合計 DESC;

受注表のデータ:

受注ID | 顧客ID | 売上
R001  | C001  | 100000
R002  | C001  | 40000
R003  | C001  | 30000
R004  | C002  | 60000
R005  | C002  | 50000
R006  | C003  | 55000

解答

顧客ID | 受注件数 | 売上合計
C002  | 2      | 110000

理由:

  1. WHERE 売上 >= 50000 で絞る:R001, R004, R005, R006
  2. GROUP BY 顧客ID でグループ化:C001(1件), C002(2件), C003(1件)
  3. HAVING COUNT(*) >= 2 で絞る:C002 だけ(2件以上)

重要な確認ポイント

  • WHERE(行レベルの条件)でまず絞った後に GROUP BY
  • HAVING(グループレベル)で再度絞った
  • 最終結果は C002 の 1 グループだけ

確認問題 3:ACID 特性と排他制御

以下の状況を説明しなさい。

状況:顧客A の口座残高 100万円から 50万円を出金し、顧客B の口座に入金するトランザクション。

  1. 原子性(Atomicity) が違反したらどうなるか。その対策は
  2. 独立性(Isolation) が違反したらどうなるか。その対策は
  3. この処理中、どのロックが必要で、どう機能するか

解答

  1. 原子性違反の例

    • 「出金だけ成功、入金が失敗」→ A さんの 50万が消える
    • 「入金だけ成功、出金が失敗」→ お金が増える(不整合)
    • 対策:COMMIT(全て記録)かROLLBACK(全て破棄)で、中途半端を防止
  2. 独立性違反の例

    • トランザクションA が「出金 → 入金」の途中で、トランザクションB がA の残高を読む
    • B が読んだ値が確定値か未確定値か不明
    • 例:A が出金を記録したが入金失敗 → B が古い残高を読む → 矛盾
    • 対策:A が X ロック(占有ロック)を取得。B は A が完了するまで待機 → 確定値だけを読む
  3. ロック

    • A 口座:X ロック(書き込み)。出金操作を独占
    • B 口座:X ロック(書き込み)。入金操作を独占
    • 処理完了(コミット/ロールバック)→ ロック解放
    • 他のトランザクションはロック解放まで待機

確認問題 4:バックアップとリカバリ

金曜 15:00 にシステム障害が発生。以下のバックアップがある。復旧方法は。

【バックアップ履歴】
日曜 23:00  フルバックアップ取得
月曜 23:00  差分バックアップ取得
...
木曜 23:00  差分バックアップ取得
金曜 12:00  増分バックアップ取得
金曜 13:00  増分バックアップ取得
金曜 14:00  増分バックアップ取得
(14:00 以降のトランザクションログ記録あり)

【質問】

  1. 復旧の手順は
  2. 復旧できるデータはいつ時点か
  3. 失われるデータはいつ〜いつか

解答

  1. 復旧手順

    • ステップ1:日曜のフルバックアップからデータベース全体を復元
    • ステップ2:月曜〜木曜の差分バックアップをすべて適用(木曜 23:00 時点)
    • ステップ3:金曜の増分バックアップ(12:00, 13:00, 14:00)をすべて適用(金曜 14:00 時点)
    • ステップ4:14:00 以降のトランザクションログを確認(確定済み操作だけ再実行)
  2. 復旧できるデータ

    • コミット済みのトランザクション:金曜 14:00 までのすべて
    • 金曜 14:00 〜 15:00 のコミット済み操作も復旧可能(ログから)
    • 結果:ほぼ障害直前まで復旧可能
  3. 失われるデータ

    • 「トランザクション開始後、14:00 以降に変更したが、15:00 までにコミットされなかった」操作
    • 例:15:00 に「取引開始」した顧客操作で、15:00 内に完了しなかったもの
    • 一般的には数分単位の最小限の損失

確認問題 5:マスタ、トランザクション、入力部品

商品マスタ、受注入力画面、受注トランザクション表がある。次の対応として最も適切なものを答えよ。

  1. 商品コードはどの表で管理するか
  2. 商品コード入力欄はテキストボックスとドロップダウンのどちらが基本か
  3. 数量入力欄は何が基本か

解答

  1. 商品コードは 商品マスタ
  2. 商品コードはマスタ参照なので ドロップダウン が基本
  3. 数量は取引ごとに入力するので テキストボックス

理由:

  • 商品コードは基準データで、受注のたびに自由入力させると表記ゆれや誤入力が起きやすい
  • 数量は取引ごとに変わる値なので、トランザクション入力として扱う

確認問題 6:DWH とデータレイクの判定

次の説明に最も近い用語を答えよ。

  1. 複数の基幹システムから抽出した構造化データを、分析しやすい形で統合して蓄積する
  2. IoT センサログ、画像、SNS 投稿などを元の形式のまま広くためておき、後で分析方法を決める
  3. DWH から営業部門向けだけを切り出した分析用データ集合
  4. 重複顧客や住所表記ゆれを修正する処理

解答

  1. データウェアハウス
  2. データレイク
  3. データマート
  4. データクレンジング

確認問題 7:条件式と集合演算

次の 2 問に答えよ。

  1. A OR B AND C は、括弧を補うとどうなるか
  2. 東京店会員大阪店会員 の顧客ID一覧を、重複を除いて 1 つにまとめたい。JOIN と UNION のどちらを使うべきか

解答

  1. A OR (B AND C)AND が先に評価される
  2. UNION。同じ意味の列集合を縦に統合する問題だから

確認問題 8:ヘッダ・明細・マスタの切り分け

次の属性を、受注ヘッダ受注明細商品マスタ のどこへ置くのが基本か答えよ。

  1. 受注日
  2. 顧客ID
  3. 商品ID
  4. 数量
  5. 商品名
  6. 標準単価

解答

  1. 受注ヘッダ
  2. 受注ヘッダ
  3. 受注明細
  4. 受注明細
  5. 商品マスタ
  6. 商品マスタ

ポイント1件の受注で1回だけ決まるか行ごとに変わるか基準データとして安定しているか で置き場所を決めます。

確認問題 9:JOIN と GROUP BY の粒度を選ぶ

会員ごとの購入回数 を表示したい。購入が 1 回もない会員も結果に含めたい場合、JOINGROUP BY はどう考えるべきか答えよ。

解答

  • JOIN は LEFT OUTER JOIN
  • GROUP BY は 会員ID(必要なら会員名も)

ポイント:まず 会員を全員残したい ので会員表を左側に置いた LEFT OUTER JOIN を選びます。そのうえで、結果 1 行を 会員ごと にしたいので GROUP BY 会員ID にします。JOIN は残す行、GROUP BY は 1 行の単位です。


関連ページ

このページは役に立ちましたか?

評価とひとことを残してもらえると、内容と導線の改善に使えます。

Last updated on

On this page

このページの役割学習のポイント試験で何が問われるかデータベースの基本概念データベースとは何かデータベースの種類リレーショナルデータベース(RDB)─なぜ「表」か3 層スキーマとデータ独立性スキーマとは何か3 層の構成と意味データ独立性の実務的意味E-R図(エンティティ・リレーションシップ図)E-R図の役割主要な要素カーディナリティ(リレーションシップの種類)M:N リレーションシップの処理リレーショナルデータベース基本概念用語の整理キーの概念と役割キーの種類主キーと外部キーの関係関係演算(関係代数)なぜ「関係演算」を学ぶのか8 つの基本演算関係演算と SQL の対応正規化正規化とは何か正規化の段階と異常の種類3 つの異常(更新異常、挿入異常、削除異常)正規化の進行具体例:正規化のステップ出発地点:非正規形第1段階:第1正規形へ(繰り返し項目を排除)第2段階:第2正規形へ(部分関数従属を排除)第3段階:第3正規形へ(推移関数従属を排除)SQL(Structured Query Language)SQL とは何かSQL の 3 つの領域SELECT 文の処理順序SQL 書く順番 ≠ 実行順番なぜこの順番か?WHERE と HAVING の違いWHERE 句で使う演算子と関数集約関数主要な集約関数GROUP BY と集約関数の組み合わせSQL 計算例:WHERE、GROUP BY、HAVING の全パターンJOIN の種類JOIN の種類と結果行数JOIN の仕組みJOIN の具体例:INNER JOIN vs LEFT OUTER JOINサブクエリと相関サブクエリトランザクショントランザクションとは何かACID 特性ACID 特性と実装技術の対応排他制御(ロック)ロックの 2 つの種類デッドロックコミットとロールバックバックアップとリカバリ背景:なぜバックアップが必要かバックアップの 3 つの種類バックアップ戦略の典型例リカバリの方法リカバリの実際の流れビューとインデックスビュー(View)ビューの仕組みビューの特性インデックス(Index)インデックスの仕組みインデックスの選択基準過去問で戻りやすい補助論点マスタデータ、トランザクションデータ、参照整合性ヘッダ、明細、マスタで正規化を読む条件式の組み立て:AND / OR / NOT、括弧、IF / CASE入力画面とデータベース設計のつながりJOIN と GROUP BY は「残す行」と「1行の単位」で考える否定条件と重複除去の読み方分析用データ基盤:DWH、データマート、データレイク、データクレンジングSQL の集合演算:UNION、UNION ALL、INTERSECT、EXCEPT典型的なつまずきつまずき 1:主キーと外部キーの役割の混同つまずき 2:正規化を「表を増やすこと」と勘違いつまずき 3:SQL を「記述順に実行」と思うつまずき 4:JOIN の方向が逆つまずき 5:WHERE と HAVING の使い分けつまずき 6:トランザクションを「1 行の UPDATE」と混同つまずき 7:バックアップを取得しただけで安心つまずき 8:マスタとトランザクションを逆に考えるつまずき 9:AND と OR の優先順位を読み違えるつまずき 10:JOIN と UNION を同じ「表をまとめる操作」だと思うつまずき 11:DWH とデータレイクを同じ「大きい保存場所」だと思うつまずき 12:複合キーを見落として、主キー全体への従属を判定できないつまずき 13:JOIN で残す行の範囲と GROUP BY の粒度を混同するつまずき 14:<> や自己結合の大小条件を読み飛ばす問題を解くときの観点問題のパターン判定SQL 読み取り問題のステップ正規化問題のステップトランザクション問題のステップ条件式・集合演算問題のステップデータ基盤・入力設計問題のステップ確実な得点の心がけ確認問題関連ページ