あなたはいくつ解けますか？データベース分野を徹底解説 【基本情報・応用情報】

この記事は[Nuco Advent Calendar 2024](https://qiita.com/advent-calendar/2024/nuco)の18日目の記事です。

# はじめに
この記事では基本情報技術者試験と応用情報技術者試験で出題されるデータベース分野についてわかりやすく説明します。
この分野は知識だけで正解できる問題と知識を前提とした上で思考を要求する問題が混在しています。特に正規形、同時制御（ロック）は後者の典型であり、思考の前提となる知識の理解も難しいため、ここで躓いてしまう人も少なくありません。
本記事では図をふんだんに取り入れて、どこよりも詳しく解説しています。
もちろん、試験対策としてだけでなく、実務にも活かせる内容になっています。
この記事が皆様のお役に立つことができれば幸いです。

:::note info
弊社Nucoでは、他にも様々なお役立ち記事を公開しています。よかったら、Organizationのページも覗いてみてください。
また、Nucoでは一緒に働く仲間も募集しています！興味をお持ちいただける方は、[こちら](https://www.recruit.nuco.co.jp/?qiita_item_id=5afaa28fc851bc7f860e)まで。
:::

 
## 同時実行制御
更新の整合性をどのように保証するか、というのはデータベース設計における重要な課題です。通販サイトで在庫が1つしかない商品について、複数人が同時に購入しようとしたらどうなるでしょうか。このような状況を防ぐために**ロック**という仕組みを使います。

この単元は試験における頻出トピックです。単なる用語の暗記だけでなく、実際の処理の流れを正確にイメージできることが求められます。
以降では、それぞれの動作を図解とともに詳しく説明していきますので、処理の流れをイメージするのにお役立てください。

### ロック
共有資源に対して複数のアクセスが同時に発生しても問題なく動作できる制御のことを**排他制御**といいます。
例えば、次のように複数の人が同時に共有資源であるファイルに書き込みを行った場合、排他制御をおこなっていれば、データの整合性が保たれます。（共有ファイルに「BBB」と「CCC」が両方追加される）
<img width="40%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/ba317982-868f-06b3-6343-8d7036e0afa3.png">
しかし、排他制御をおこなっていないと次のように整合性が保たれないデータになってしまう危険性があります。（後から更新した方のデータとなり、BBBが反映されていない）
<img width="40%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/0bdf5719-e521-bf9f-6910-f64e1e31438f.png">
このような事態を防ぐために、共有ファイルへの書き込みが行われている間は、他者の書き込みを禁止するという制御を行います。この制御のことを排他制御といいます。

排他制御の代表的な手法の1つとしてロックがあり、ロックには**共有ロック**と**占有ロック**があります。

#### 占有ロック
**占有ロック**とは、データがロックされている間は、他ユーザはデータを読むことも、書き込むこともできないロックのことです。
例えば、次のように商品番号「S001」のレコードを占有ロックします。占有ロック中は他ユーザがそのレコードに対して読み書きすることはできません。（ロック解除待ちで待機になる）
<img width="70%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/3d5e257d-1d3b-dc0b-a588-21c944e24a7f.png">
このように対象レコードを占有し、ロック中は他ユーザに読み書きさせないロックのことを**占有ロック**といいます。

#### 共有ロック
**共有ロック**とは、データがロックされている間は、他ユーザはデータを読むことはできるが、書き込むことができないロックのことです。
例えば、次のように商品番号「S001」のレコードを共有ロックします。共有ロック中でも他ユーザがそのレコードを読むことはできます。ただし書き込むことはできません。（ロック解除待ちで待機になる）
<img width="70%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/d94d1898-03bf-ddc4-925b-440108c52cbf.png">
このように対象レコードに対し、ロック中は他ユーザに書き込みさせないロックのことを**共有ロック**といいます。

#### デッドロック
**デッドロック**とは、複数のトランザクションがお互いに相手の使いたいデータをロックしてしまい、お互いがロック解除待ち状態となり、処理が止まってしまう現象のことです。
<img width="60%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/b225e958-4cfa-e3fc-6b1e-a4fe51c0538c.png">
・タスクAが資源AのDBをロック
・タスクBが資源BのDBをロック
・タスクAが資源BのDBにアクセスするも、ロック中のためロック解除待ちとなり待機
・タスクBが資源AのDBにアクセスするも、ロック中のためロック解除待ちとなり待機

上記のように、タスクA、タスクBともに「ロック解除待ちで待機」というステータスとなり、お互い処理が止まっています。この現象がデッドロックです。
デッドロックが発生した場合、いずれかのトランザクションを強制的にキャンセルする必要があります。


### 同時実行制御に関する出題

#### 基本情報
<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/03add422-1837-ee4a-8b0f-6153db5f7cd9.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<エ>になります。<br>
デッドロックとは、複数のトランザクションがお互いに相手の使いたいデータをロックしてしまい、お互いがロック解除待ち状態となり、処理が止まってしまう現象のことでした。<br>
</details>

<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/9f34b032-daae-70e8-83d0-9f495797e072.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<エ>になります。<br>
共有資源に対して複数のアクセスが同時に発生しても問題なく動作できる制御のことを排他制御というのでした。
</details>

#### 応用情報
<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/4f91a9e5-727e-76ba-3825-d69e9d4b6c3d.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<ア>になります。<br>
占有ロックになると他のユーザーは読み込みも書き込みもできなくなります。<br>
一方、占有ロックであれば他のユーザーは書き込みができなくなりますが、読み込みは可能ですので、情報を獲得することはできます。
</details>

<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/6470acfa-ae2b-ba75-a1ab-31c6192cf6be.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<ウ>になります。<br>
データa,データbの状態を順を追って見ていきましょう。<br>
①T1がデータaに共有ロックをかける<br>
②T2がデータbに占有ロックをかける<br>
③T2がデータbの占有ロックを解除する<br>
④T1がデータbに共有ロックをかける<br>
⑤T3がデータbに共有ロックをかける（④の段階ですでに共有ロック状態にある）<br>
⑥T3がデータaに占有ロックをかけようとするが、①の段階で共有ロックがかかっているので待機状態になる<br>
⑦T1がデータbに占有ロックをかけようとするが、⑤の段階で共有ロックがかかっているので待機状態になる<br>
この時点でT1はT3がデータbに対するロック解除を待機し、T3はT1のデータaに対するロック解除を待機している。つまり、デッドロックが発生しています。<br>
</details>



## データベースの種類
データベースには複数の種類があり、通常はデータを保持する形式によって分類されます。この解説ではリレーショナルデータベースに焦点を当てます。
特に試験対策として重要なポイントは、リレーショナルデータベースを「二次元表」として理解することです。NoSQLデータベースについては後の記事で詳しく説明しますので、「リレーショナルデータベース以外にもデータベースの種類があるんだな」ぐらいの認識で十分です。
出題形式としては知識問題のみになりますので、試験対策としてこの記事を読まれる方はリレーショナルデータベースの定義を確実に覚えることに集中すれば大丈夫です。


### 階層型データベース
データをヒエラルキー構造で管理するデータベースです。代表的なものに組織図や樹形図があります。

### リレーショナルデータベース
現在の主流です。この記事で解説するデータベースはこれのみです。
リレーショナルデータベースにおける「リレーション」という言葉は、「人間関係」や「国際関係」という意味合いで使われる「関係」とは意味が異なります。
ここでいう「リレーション」とは、数学で二次元表を表す時に使われる言葉なのです。
つまり、リレーショナルデータベースとは **データを、二次元表を使って管理するデータベース**をコンセプトにしたデータベースなのです。
データを二次元表で管理するというのは革新的なものでした。
CSVファイル形式のデータに対して検索や更新などの操作を行おうとすれば、何らかのプログラミング言語（Javaなど）の知識が必要になりますし、プログラムを実行できる環境も用意する必要があります。
しかし、後述するSQLによって、プログラミング言語を習得しなくとも、データ操作を行うことが可能になりました。これにより、リレーショナルデータベースは爆発的に普及しました。


### オブジェクト指向データベースとXMLデータベース
**「オブジェクト指向データベース」** と **「XMLデータベース」** は、それぞれ「オブジェクト」および「XML」という形式でデータを管理するデータベースです。

### NoSQLデータベース
**「NoSQL」** は **「Not only SQL」** を意味します。従来のリレーショナルデータベースとは異なるデータ構造を持ち、大量のデータを柔軟に扱ったり、高速なデータの読み書きを可能にします。

### データベースの種類に関する出題

#### 基本情報
<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/436db222-b1d0-7883-8bd5-e0e1fe17fef4.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<エ>になります。<br>
関係データベースというのはリレーショナルデータベースのことです。<br>
リレーショナルデータベースは二次元表の形式でデータを管理するデータベースです。
</details>

<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/9330a656-8619-56ee-cbad-2e04e24c1b73.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<イ>になります。<br>
リレーショナルデータベース＝二次元表、と認識しておけば正解することができます。
</details>

#### 応用情報
<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/8f62848f-46ee-6f75-c696-13d90a32e468.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<エ>になります。<br>
これは現時点での説明で正答することが難しいのですが、消去できる選択肢があります<br>
リレーショナルデータベースは二次元表の形式でデータを管理するデータベースであることを思い出しましょう。<br>
<イ>の説明が誤りであることと、<ウ>がリレーショナルデータベースの説明であることがわかります。<br>
あとは<ア>が誤りであることが分かれば正解できるのですが、階層モデルについてはこの記事の後半で解説します。
</details>

<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/e4081c9e-eb27-865c-56e4-6e90d0811252.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<イ>になります。<br>
選択肢はリレーショナルデータベース（関係データベース）とオブジェクト指向データベースについて説明したものなので、リレーショナルデータベースを説明している選択肢がわかれば消去法で正解を導くことができます。<br>
選択肢ウとエはリレーショナルデータベースの説明であるとわかりますが、選択肢アが迷います。これは後ほどER図のところで説明するので今の段階では「ア、イのどちらかが正解だろう」とわかればOKです。<br>
Javaなどのプログラミング言語に慣れ親しんでいる方であれば'カプセル化'という単語からイが正解であると導けるかもしれません。
</details>



## SQL
SQLは、リレーショナルデータベースでデータを操作するための共通言語です。
様々なデータベースソフトウェアで使用できる汎用的な言語であり、データベース操作に欠かせない重要な技術です。
試験としては、「このSQLの結果として表示されるものはなんでしょう？」といった風にSQL文を理解することが求められます。問題集や参考書を用いた学習よりもこの単元で紹介するサイトで実際に手を動かして覚えてしまいましょう。個人的にはSQLZooがオススメです。
習得するのにある程度の時間がかかるため、知識問題だけ出題される単元を抑えてから、この分野に取り掛かるのも戦略的にはアリです。

### SQLに関する出題

#### 基本情報
 <details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/67e88197-d3a5-fef6-258b-383fbec9ccd5.png">
</details>
 <details>
<summary>解答と解説</summary>
正解は<ウ>になります。<br>
『1教科は平均点以上かつ残りの1教科は平均点以下』と、2つの条件を『かつ』で繋いでいるので、条件を繋ぐのはANDになります。<br>
『1教科は平均点以上』というのは『国語の点数が平均点以上、数学の点数が平均点以上、国語と数学の平均点が両方とも平均点以上』ということなので、WHERE句の一方は(A OR B)となります。<br>
『残りの1教科はいずれも平均点を超えてはいけない』ので、WHERE句のもう一方は NOT (A AND B)となります。
以上より正答は<ウ>になります。
</details>

<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/59b1e6be-1018-dc74-3905-3a58bb413f13.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<イ>になります。<br>
それぞれの選択肢の結果を見ていきましょう。<br>
ア：書名が'UNIX'で終わるものしかヒットしません。<br>
イ：書名に'UNIX'が含まれるものがヒットします。よってこれが正解です。<br>
ウ：書名が'UNIX'だけの場合にヒットします。<br>
エ：書名が'UNIX'で始まるものがヒットします。
</details>


#### 応用情報
<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/ad5046f6-5a4f-ebf0-98fb-0c21547dfbd3.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<ウ>になります。<br>
WHERE句に NOT LIKE '010%' とあるので、'010'を含まないレコードが選択されます。<br>
これに該当するレコードは3つなので<ウ>が正解になります
</details>

<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/d2c410c8-4fed-204a-49e9-9ef5754925c7.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<ウ>になります。<br>
まずは以下の部分から考えてみましょう。<br>
SELECT AVG (販売単価 - 仕入単価) FROM 商品<br>
(200+200+100+900+400+200+300+500+500+300)/10=360となります。<br>
これを踏まえた上で以下の部分を考えましょう。
SELECT 仕入先コード FROM 商品<br>
 WHERE (販売単価 - 仕入単価) > 360<br>
 これに該当するレコードはD004,E005,H008,I009の4つであり、それぞれの仕入先コードはS1,S1,S4,S5になります。これにDISTINCTがかかるのでS1,S4,S5の3つが正解になります。
</details>

### 学習サイト紹介
 SQLに関しては実際に手を動かしながら覚えた方が圧倒的に効率的なので下記サイトのいずれかで練習してみましょう。
 
[SQLZoo](https://sqlzoo.net/wiki/SQL_Tutorial)
多彩な問題が用意されており、日本語にも対応しているため、初心者でも気軽に始められます。各問題には丁寧な解説があり、自力で解けなかった場合でもヒントを得られます。

[SQLBolt](https://sqlbolt.com/)
シンプルなインターフェースで、基礎的なSQL文の練習に最適です。問題の難易度が段階的に上がっていくため、着実にスキルアップできます。

[TECH PROjin](https://tech.pjin.jp/blog/developer_category/sql%e5%9f%ba%e7%a4%8e/)
SQLの基礎から応用まで、幅広いレベルの問題が用意されています。実践的なスキルを磨きたい方におすすめです。

[progate](https://prog-8.com/)
ゲーム感覚でSQLを学べるプログラミング学習サービスです。ビジュアルな教材で、初心者でも楽しみながら学習できます。

[paizaラーニング](https://paiza.jp/works/sql/primer)
動画を見ながら学習できるため、初心者でもわかりやすいです。SQLの基礎から応用まで、様々なコースがあります。

### SQLの実例
例としてSQLZooの問題を引用します。
<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/011ced87-4990-320a-2ce3-b214352c8fcc.png">
このテーブルから**ドイツ(Germany)の人口(population)を表示する**ようなSQLを考えます。

<details>
<summary>解答</summary>
<pre>
SELECT population
FROM world
WHERE name = 'Germany'
</pre>
<p>細かい文法はわからなくともなんとなく理解できるのではないでしょうか。</p>
<p>populationを選ぶ(SELECT)。</p>
<p>world（テーブルの名前）から(FROM)。</p>
<p>nameはドイツ(Germany)。</p>
このようにとっつき易い分野ですので、最初のうちはどんどん手を動かして理屈よりも体で覚えてしまいましょう。
</details>

        
## トランザクション
**トランザクション**とは複数のクエリをひとまとまりにしたものです。トランザクションは4つの特性により定義され、そのイニシャルから**ACID特性**と呼ばれます。
トランザクションによるデータベースの更新内容が有効になることを**コミット**、無効になることを**ロールバック**と言います。
 試験での出題形式は知識問題のみです。
 各用語の定義を覚えてしまえば正解を導けるのですが、ACID特性の日本語訳が試験によって異なる場合があることに注意しましょう。
 （例：Durabilityは「耐久性」や「永続性」と訳されます）。

### 原子性 (Atomicity)
トランザクションは、全てが成功するか、全てが失敗するかのどちらかです。途中で一部だけ成功する、といったことは起こりません。例えば、銀行振込の場合、送金元の口座から引き落とされて、送金先の口座に入金されるまでが一つのトランザクションとなります。途中でエラーが発生した場合、両方の口座の状態は元に戻されます。

### 一貫性 (Consistency)
トランザクションが必ず一定のルールに沿ってデータベースに変更を行う性質を表します。
「口座番号は7桁である」という条件がデータベースに設定されているとしたら、誤って8桁の口座番号が指定されてもエラーとなり、データベースの整合性が保たれるような性質です。

### 独立性 (Isolation)
複数の処理が同時に実行されても、それぞれがお互いに干渉しない性質を表します。
Bさんの口座に10万円の送金が行われるタイミングで、逆にBさんからAさんに20万円の送金があったとします。この時、Bさんの口座情報から10万円が引かれると同時に、20万円の増額処理が走ってしまうと結果の整合性が保てません。このような不整合が起きないという性質を言います。

### 永続性 (Durability)
一旦確定（コミット）したデータは、その後に障害が発生しても永遠に変わらず保持される性質のことです。

### トランザクションに関する出題

#### 基本情報
<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/be91162c-a3b4-9293-58d7-5eb87beff28f.png">
</details> 
<details>
<summary>解答と解説</summary>
正解は<イ>になります。<br>
原子性の定義を思うかべましょう。<br>
「トランザクションは、全てが成功するか、全てが失敗するかのどちらか」というのが原子性 (Atomicity)でした。
</details>
<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/d1d3c5a3-0c36-9630-213a-8a3103995c50.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<エ>になります。<br>
原子性を確保するには一度開始されたトランザクションは、コミットまたはロールバックのどちらかで終了しなければなりません。
</details> 

#### 応用情報
<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/330b2c6b-96ea-4697-191d-63871e7a9ede.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<イ>になります。<br>
ACID特性とは原子性 (Atomicity)、一貫性 (Consistency)、独立性 (Isolation)、永続性 (Durability)の4つでした。<br>
可用性は含まれません。<br>
永続性を耐久性と呼ぶこともあります。
</details>

<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/7db115f9-4502-71d5-3305-28080a05ec47.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<ア>になります。<br>
Durabilityの定義は「一旦正常終了したトランザクションの結果は、それ以降システムに障害が発生しても失われないことを保証する性質」でした。<br>
本文ではDurabilityを永続性と訳していますが、耐久性となる場合もあります。
</details>


## キー(key)
リレーショナルデータベースにおいて、キー（key）は非常に重要な概念です。
これは、**特定のレコードを一意に識別するための列の組み合わせ**という意味で使われます。
特に重要なのが**主キー**と**外部キー**です。
試験で問われる内容は、これらのキーの定義と役割です。出題形式が知識問題なので、それらを抑えておけば得点は容易な単元になります。
後に学ぶ正規形の理解に直結する重要な基礎知識でもあるので、ここでしっかりと抑えておきましょう。

### 主キー
**主キー**、または**プライマリーキー**と呼びます。
主キーはテーブルにおいて必ず一つ存在しなければならず、かつ一つしか存在しません。主キーとは、その値を指定すれば、必ず1行のレコードを特定できるような列の組み合わせのことです。この「1行に特定する」ことを**一意に識別する**という言い方をします（「一意」は「unique」の略語です）。
<img width="40%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/e622b4bc-8072-8001-5d80-bb6eed0d27aa.png">
上のテーブルでは社員IDが主キーになります。
今は社員数が2人しかいないので、氏名も所属部署も重複がありませんが、社員が増えていけばいずれは重複する値が発生するでしょう（同姓同名、同じ所属部署）。
つまり主キーとなり得るのは社員IDのみです。
というよりも社員を一意に識別するために、つまり主キーとなるべく作られた列が社員IDです。

### 外部キー
外部キー(FOREIGN KEY)とは、関連したテーブル間を結ぶために設定する列のことで、データの整合性をデータベースに保証させるために利用します。
<img width="60%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/2eb38d68-025e-a631-ac3c-6604e182c30d.png">
上の図では、社員テーブルと部署テーブルを関連づけしたいので外部キーを利用します。
外部キーを設定して参照する側は子テーブル、設定元は親テーブルと言います。
この列は、部署の一覧を保持する「部署」テーブルの「部署」列を参照しています。
この外部キーの役割は、「部署」テーブルに存在しないような部署のデータが、間違って「社員」テーブルに登録されないよう防止することです。

### キー（key）に関する出題

#### 基本情報
<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/2b8f0afc-4ffc-fb5f-ec4a-c0fa797a24c0.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<ア>です。<br>
主キーとは「その値を指定すれば、必ず1行のレコードを特定できるような列の組み合わせ」でした。<br>
nullはこの条件を満たしません。
</details>

<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/ee9f4a39-40d5-bc57-75f8-7323806ea984.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<ア>になります。<br>
外部キー(FOREIGN KEY)とは、関連したテーブル間を結ぶために設定する列のことで、データの整合性をデータベースに保証させるために利用するのでした。<br>
</details>

#### 応用情報
<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/0bbbd039-733c-f01f-5109-1846ce2215eb.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<ア>です。<br>
外部キーの説明に用いた図を思い出してみましょう。<br>
<img width="60%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/2eb38d68-025e-a631-ac3c-6604e182c30d.png"><br>
候補キーとは主キーのことです。<br>
社員テーブルの外部キー（部署ID）が部署テーブルの主キー（部署ID）を参照しています。<br>
</details>

<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/ca35fcd5-59e5-73ac-cd8c-1ed1655c467d.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<エ>になります。<br>
これは後述しますが、候補キーとはレコードを一意に特定するための属性（＝カラム）またはレコードを一意に特定するための属性の組み合わせです。<br>
ややこしいのですが、主キーではnullが許されず、候補キーではnullが許されます。<br>
候補キーにnot null制約（記事の後半で解説）を加えたものが主キー制約です。
</details>


## 正規化
正規化（英：Normalization）の最大の目的は、**データベース上で扱うデータの重複を削除し、データの更新時に発生する異常を取り除くこと**です。データベースは常に更新が発生するため、適切な正規化を行わないと、レコードの登録や更新に支障をきたす可能性があります。
基本情報・応用情報においては、最も難しい分野であり、特に第2正規形の理解が鍵となります。第1正規形は比較的理解しやすく、第3正規形も重要なポイントは限られています。
**正規化の目的は知識問題として問われる**ので、まずはここだけ頭に入れて、第2正規形の細かい理解は他の単元の学習が終わってからにする、というのも戦略的にはアリです。
理解の助けとなるよう図を多く載せたので是非活用してください。文章よりも図のほうが理解しやすい単元です。

### 正規化できていない例
<img width="70%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/647170a6-91e6-643d-0232-7f6273382c6d.png">

左側のテーブルは注文を受けたらその内容をどんどん追加していくようなテーブルで、右側のテーブルは注文した人とその内容を整理して出来上がったようなテーブルです。
一見、２つのテーブルはちゃんと利用できるように思えます。ですが、実はこのテーブルは利用しているとレコード間の不整合が発生します。
例として、このとき注文がキャンセルされてしまい、注文番号テーブルから対象のレコードを削除するとどうなるか？を考えてみたいと思います。
<img width="70%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/db496cdf-4f39-8ee7-24ce-39103630a0d0.png">
上記４つのレコード「だけ」削除してしまうと、テーブル間での矛盾が発生します。
<img width="70%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/eef80afc-4606-645e-1a6d-f8d7ad547e01.png">
「注文番号テーブル」には存在しないのに、「注文者テーブル」にはそれに対応するレコードが存在するという謎な現象が起きてしまうのです。

このように正規化されていないテーブルを扱おうとすると、テーブル間の不整合する可能性があります。

正規化の過程ではデータベースはいくつかの**正規形**を経て構築されます。
実務の上では第1正規形～第3正規形まで抑えておけばOKです。

### 第1正規形
**テーブルのセルに複合的な値を含んでいない**状態です。
ただ、これに反するテーブルを作成することは技術的に不可能なのであまり気にする必要はありません。リレーショナルデータベースのテーブルは全て第1正規形を自動的に満たしているのです。
<img width="70%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/4dad99db-d14b-17d1-527d-639a3889a308.png">
佐藤次郎さんの被扶養者には2つの値（きょうこ、さとし）が入っていますが、この状態は第1正規形に反します。

### 第2正規形
第２正規形は**テーブルの各候補キーに従属する部分関数従属性が整理された状態**です。
**候補キー**と**部分関数従属**という用語の意味を説明します。

#### 候補キー
候補キーとは**レコードを一意に特定するための属性（＝カラム）**または**レコードを一意に特定するための属性の組み合わせ**です。
以下のテーブルであれば候補キーは「出席番号」です。
<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/1d015462-5873-f2e9-d9cc-2caa53aad6c7.png">
出席番号さえ分かれば、どのレコードを指し示しているかが分かります。
したがって、上記のテーブルでは出席番号項目が候補キーであるといえます。
逆に「氏名」列や「生年月日」列は同じ値が存在する可能性もあるため、候補キーとは言えません。

では、下記テーブルの候補キーはどれになるでしょうか？
<img width="70%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/a1ddd389-3fb1-b0af-b9a8-e42c4aca4a2b.png">
この場合は、どの列も単独ではレコードを一意に特定することができません。
「注文番号」も「注文者」などが候補キーに該当しそうな気もしますが、どちらの列にも同じ値が存在します。
この場合、１つの項目が単独でレコードを特定することができないため、**候補キーは各項目の組み合わせ**を判断し特定する必要があります。
上記テーブルの場合は "注文番号" と "商品ID" が分かれば（"注文番号" と "商品ID" の組み合わせを見れば）、どのレコードを指し示しているかを特定することができます。
したがって、候補キーは "注文番号" と "商品ID" になります。
<img width="70%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/30c52e05-8b77-650d-7fe5-9341a02eb2a5.png">

また、重要なポイントの１つが「候補キーは複数存在する可能性がある」ということです。例えば、上記のテーブルでは「注文番号」と「商品名」の組み合わせも、候補キーになります。
何故なら、注文番号と商品名が分かれば、先ほどと同様にどのレコードを指し示しているかが分かるためです。
<img width="70%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/2e1da9b2-555a-0315-a3c6-460749cd12fa.png">

したがって、上記テーブルの候補キーは（注文番号,商品ID）と（注文番号,商品名）ということになります。

#### 部分関数従属
部分関数従属とは**一部の候補キーに対して関数従属する属性**です。

**関数従属**：Xの値が決まるYの値が決まる関係のこと（X→Y）
例) Y=3+X の場合 Xの値が7に決まれば Yの値は10に決定する

例えば、以下のテーブルでは注文番号が決まれば「注文日」「注文者ID」「注文者」のカラムは一意に決定することが分かります。
<img width="70%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/c5055c97-219d-c843-c63c-488570e6e7e5.png">
注文番号が「001」であれば必ず注文日は「1/1」で注文者IDは「A1」、注文者は「佐藤商事」に確定します。
このとき、注文日・注文者ID・注文者のカラムは候補キーの１つである「注文番号」に**関数従属**しているため**部分関数従属**している、ということができます。

また、同じ理由で「商品名」も商品IDに対して**部分関数従属**しているということができます。
<img width="70%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/98eaa889-c975-1c4a-3c46-6625a9e5ea11.png">

第２正規形は**テーブルの各候補キーに従属する部分関数従属性が整理された**状態です。
したがって、部分関数従属している列を切り離し別のテーブルとして整理するのが第２正規化の手順です。
<img width="70%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/221f3259-838c-a2de-222e-6e1611e6cc1f.png">

### 第3正規形
第３正規形は**候補キー以外の列に関数従属している列が整理された状態**です。
<img width="70%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/6e6c9f9d-bc3f-3749-f7cd-4a885198dd2b.png">
上記の例でいうと、候補キーではない注文者IDに関数従属している「注文者」列を別表に移すのが第３正規化で行う手順です。
{注文者番号}→{注文者ID}→{注文者}という段階的な関数従属が成立していました。
これを**推移的関数従属**といい、この状態を解消するのが第3正規化です。

これによって、候補キー以外の列に関数従属している列が存在しない状態を作り出すことができます。
<img width="70%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/9ebf4c27-004f-dc65-511a-1c6a60acaf36.png">
当初１つのテーブルに存在していたデータが正規化を行うことで、４つのテーブルに整理されました。

### 正規形に関する出題

#### 基本情報
<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/e20c51c1-d8b1-a499-a70a-f1201aadd471.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<ア>になります。<br>
第1正規形から確認していきましょう。<br>
テーブルのセルに複合的な値を含んでいなければOKです。<br>
該当するセルはないので、第1正規形はクリアしていると判断できます。<br>
次は第2正規形のチェックです。<br>
主キーとなり得るのは従業員番号だけと判断できるので第2正規形もクリアしています。<br>
最後に第3正規形のチェックです。<br>
「職位手当」は「職位」によって決定しますが、「職位」は主キーではありません。<br>
そのため、「職位」と「職位手当」の関係を切り離す（別のテーブルを作る）必要があります。<br>
よって、問題のテーブルは第2正規形まで正規化されたテーブルであると判断できます。
</details>

<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/1ddab1fa-5d2f-34b5-507e-846a58f6d6d9.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<ウ>になります。<br>
推移的従属関数などの特徴的なワードがないので一つずつ選択肢を見ていきましょう。<br>
ア：'値の重複をなくす'というワードから、これは第1正規形のことであると判断できます。<br>
イ：'関係を細かく分解する'というのはつまり、表を増やすということです。表を増やせば増やすほど様々な矛盾が発生してしまうので、それを防ぐべく整合性制約も自ずと増えていきます。つまり'整合性制約を排除'するという文言は誤りです。<br>
ウ：正規化の目的は冗長性の排除です。つまりはこれが正解なのですが、エの選択肢が誤りであると判断した上で、この選択肢を正解とする方が賢明です。<br>
エ：正規化の目的はパフォーマンスの向上ではありません。むしろ表を分割する分、パフォーマンスは悪化します。これによりエの文言が誤りであると分かり、消去法でウが正解であると導けます。
</details>

#### 応用情報
<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/e6bf590f-4db5-f26c-e3a9-042e3341a0db.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<イ>になります。<br>
文章で考えるとわかりにくいので第3正規形での図を思い浮かべましょう。<br>
<img width="40%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/789b42be-dc1c-8a5a-6d6d-a43e2826967d.png"><br>
ここでは候補キーでない「注文者ID」とそれに紐づいている「注文者」で別のテーブルを作成しました。<br>
これを文章で表したのが<イ>になります。
</details>

<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/ad7c0954-b879-6844-85f4-b38c7d56dcbd.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<ウ>になります。<br>
第1正規形は問題ないと思います。<br>
bとcの日本語がやや難しいのですが、'推移的'というワードからbが第3正規形を指していると判断できます。<br>
第1正規形＝非スカラ、というワードも覚えておいて損はありません。
</details>


## ER図
**ER図**は、データベースのテーブル間の関連性を視覚的に表現する技術です。
Entity-Relationship（ER）の略称で、**Entity（実体）はテーブル**を、**Relationship（関連）はテーブル間の関係**を意味します。
試験で問われる内容は各用語の定義がほとんどです。
問題文の中に図があるので、SQLや正規形のように理解するのに時間がかかる単元と思いがちですが、出題形式は知識問題なので、短時間で得点源にすることができる単元です。
・**ERはEntity-Relationship（ER）の略称**
・**Entity（実体）はテーブルを意味している**
・**Relationship（関連）はテーブル間の関係を意味している**
といったことを抑えておきましょう。

### エンティティについて
下の2つのテーブルを使って説明していきます。
<img width="60%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/b1602565-2277-f9bf-340d-2d101e7c6be8.png"> 
**Entity（実体）とはテーブル**である旨は先ほど説明しました。
<img width="60%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/5fdecac0-f2eb-4846-b17a-f5571a280e93.png"> 
上の図のように四角形で表します。
上半分のエリアには主キーを、下半分のエリアには「その他の列（非キー列）」を記入します。**PKはPrimary keyの略**です。
非キー列は非常に数が多くなるので、実際の業務では重要な意味を持つ列だけをピックアップして記入します。顧客企業テーブルの **FKはForeign Key（外部キー）** の略称です。
**外部キーとは他のテーブルにおいても同じ意味で使用されている列**のことです。
顧客企業テーブルの業界コードは業界テーブルの主キーでもあります。
これはつまり、業界テーブルに存在しない業界は、顧客企業テーブルには存在できない」ということを意味しています。これはテーブルを跨った制約であるため、**外部制約キー**と呼ばれます。

### リレーションシップについて
**外部キーはエンティティ同士の関係を示します**。
外部キーが存在するテーブルは、当該の列が他のテーブルの主キー列（あるいは主キーの一部の列）を参照していることを意味します。この関係をリレーションシップと呼びます。
<img width="60%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/4a2471ee-6ecf-1587-48b3-52a78dd25d03.png">
上の図は先ほど示したものと同じものです。
この例では、業界テーブルと顧客企業テーブルとの間には**1対N**の関係が成立しています。これは、業界テーブルの1行、すなわち1つの業界に対して、顧客企業テーブルの複数の企業が対応しているということです。
<img width="60%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/2d8102a4-836a-a417-5582-7522e0c67317.png">
上の図で見てきましょう。
「石油業界（D001）」には、A商事とD商事が対応しており、「バイオ業界（D003）」にはC化学とE繊維が対応しています。
つまり、1つの業界には複数の企業が所属する、という包含関係になっています。
<img width="20%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/5ac39aef-4084-39b7-e1d0-25afae8d672f.png">
この1対多の関係を表すために、**IE記法**（ER図のポピュラーな描き方）が用いられます。
[ER図のIE記法（鳥の足ってなんぞ）](https://qiita.com/findy-code/items/5b6f237ee2f9cdd65ac7)
前述した顧客企業テーブル（第3正規形）と業界テーブル（第3正規形）をER図で図示すると下記のようになります。
<img width="60%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/c9b67586-0e30-d134-a86c-a3a59277204f.png"> 

### 多対多
<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/47cde744-3046-a01f-1041-24269fde3608.png">

二つのテーブルは共通のキーとなる列を保持していないため、結合した情報を得ることができません。
この問題を解決するための方法が**関連実体**です。
<img width="60%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/ad81c328-5480-0340-2c77-0f4e8dcb2afb.png">
上の図のように2つのテーブルの間に第3のテーブルを設けます。
このようにすると、学生テーブルと受講テーブル、講義テーブルと受講テーブルはそれぞれが「1対多」の関連を持つようになります。

### ER図に関する出題

#### 基本情報
<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/3f0c7198-ecd4-d2da-d983-129ecbf4369e.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<イ>になります。<br>
ERがEntity Relationshipの略であることを思い出すことができれば容易に正答できます。
</details>

<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/8d5dedaa-d597-ba61-1324-326415678cb5.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<ア>になります。<br>
1対多（1対N）、多対多（0以上対0以上）という関係性があります。
</details>

#### 応用情報
<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/a5fd4848-7cd4-7a73-9e8e-f18151c50e72.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<ア>になります。<br>
Entityが「実体」（もっと言えば「テーブル」）であることを思い出せば容易に正答できます。
</details>

<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/041be68e-e23c-744b-5700-f512302742f4.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<ア>になります。<br>
多対多は「0以上対0以上」なので、親組織が多いケースもありえます。
</details>


## 3層スキーマ
データベースにおけるスキーマとは、データの構造、性質、関連性、およびデータベース操作のルールや表現方法を定義するもので、データベースの設計図に例えられます。
家を建てる際に設計図が必要なように、データベースも事前に必要なデータを洗い出し、その格納方法を整理する必要があります。
そして、**3層スキーマ**とはデータベースのスキーマを3つの階層に分けて定義する方式です。
試験で問われるのは3つのスキーマの定義と3層に分ける理由です。出題形式は知識問題なのでこれらを抑えておけば容易に得点することができます。

### 外部スキーマ
「ユーザーから見たデータベース」です。
ユーザやアプリケーションプログラムから見たデータベースの構造を定義します。データのビューや出力データがこのスキーマに対応します。
概念スキーマが変わった際の影響を、ユーザやアプリケーションプログラムができるだけ受けないためのものです。

### 概念スキーマ
「開発者から見たデータベース」です。
実際の物理的な表現方法とは別に、データの要素やデータ間の関係を定義します。テーブル作成のための設計図がこのスキーマに対応します。
概念スキーマの設計を「論理設計」と呼び、データベース設計の中で重要な位置を占めます。

### 内部スキーマ
「DBMSから見たデータベース」です。
データを外部記憶装置上にどのような形式で格納するか、その物理的内容を定義します。
ファイル編成やインデックスの設定やセキュリティなど、ハードウェアに関する実装がこのスキーマに対応します。内部スキーマの設計を「物理設計」と呼びます。

### スキーマを３層に分ける理由
わざわざスキーマを3つの階層に分けるのは、例え、ひとつのスキーマに変更があったとしても他の2つのスキーマは影響しないようにするためです。(そのように各スキーマが独立していることをデータ独立性と言います。)
実際の開発現場では仕様変更対応の連続です。その際、ひとつの変更がデータベース設計全体に影響を受けてしまっていては、開発工数がいくらあっても足りません。
3層スキーマの思想に従って設計していれば、変更の範囲を局所化することができるでしょう。3層スキーマは、変更対応を可能な限り少ない労力でできるようにと、先人たちが編み出した知恵というわけです。

### 3層スキーマに関する出題
#### 基本情報
<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/6ff6beaf-99b6-11da-f4e1-75d2879a7889.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<ウ>になります。<br>
スキーマを3層に分ける理由は「ひとつのスキーマに変更があったとしても他の2つのスキーマは影響しないようにするため」でした。<br>
これを言い換えた文言が<ウ>になります。
</details>

<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/cd5d6002-2db7-709d-5a0b-5981ef0516ee.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<エ>になります。<br>
データを外部記憶装置上にどのような形式で格納するかを決めるのは内部スキーマの役割でした。
</details>

#### 応用情報
<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/82de0467-fe46-d106-1291-57568461e52f.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<イ>になります。<br>
それぞれのスキーマの定義を振り返りましょう。<br>
外部スキーマ：システム利用者であるユーザー、もしくはアプリケーションから見たデータベースのデータ構造やデータの関係を定義するスキーマ<br>
概念スキーマ：開発者から見たデータベース。概念スキーマの設計を「論理設計」と呼び、データベース設計の中で重要な位置を占める。
内部スキーマ：DBMSから見たデータベース。コンピュータ上で動く以上、データベースのデータもその実体は「ファイル」であり、そのファイルをディスク上にどのように格納するかを定義する。<br>
「データの論理的関係を示すスキーマ」とは概念スキーマであり、「利用者が欲するデータの見方を示すスキーマ」は外部スキーマになります。よって正答は<イ>となります。
</details>

<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/036513ab-45fa-dc26-aea2-fef9a114480e.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<イ>になります。<br>
ユーザやアプリケーションプログラムから見たデータベースの構造を定義するのが外部スキーマの役割でした。
</details>


## 制約
主キーと外部キーに関する知識を前提としています。
この二つの理解があやふやな人は入門編のキー(key)の箇所を読み返しましょう。
試験ではそれぞれの制約の定義が問われます。まずは主キーと外部キーに関する制約の定義をきちんと抑えましょう。**なぜ外部キーが設定されるのか**というのがポイントになります。文章だけで理解することが難しければ図を覚えてしまいましょう。

### 外部キーの制約
外部キーについて振り返りましょう。
外部キー(FOREIGN KEY)とは、関連したテーブル間を結ぶために設定する列のことで、データの整合性をデータベースに保証させるために利用します。
<img width="60%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/2eb38d68-025e-a631-ac3c-6604e182c30d.png">
上の図では、社員テーブルと部署テーブルを関連づけしたいので外部キーを利用します。
外部キーを設定して参照する側は子テーブル、設定元は親テーブルと言います。
この列は、部署の一覧を保持する「部署」テーブルの「部署」列を参照しています。
この外部キーの役割は、「部署」テーブルに存在しないような部署のデータが、間違って「社員」テーブルに登録されないよう防止することです。
いわば外部キーの役割は、「社員」テーブルに対して一種の制約を課すことなのです。
この制約を**参照整合性制約**と呼びます。
例えば、先ほどの「社員」テーブルに次のようなレコードを新たに登録することはできません。
<img width="30%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/7824b9ef-37c3-4a24-128f-1bd3fab794ab.png">
なぜなら部署IDがDとなっているという部署は「部署テーブル」に存在しないからです。このレコードを登録しようとするSQL文はエラーになります。
一方で、「部署」テーブルに次のようなレコードを登録することは問題なく可能です。
<img width="30%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/5cddcd10-d20f-e872-24aa-e2b59046e9b3.png">
「部署」テーブルはいわば「社員」テーブルの「親」に当たる存在であるため、「子」の状態を気にすることなく変更が可能です。
これは人間の親子関係と同じです。子は親が存在しないと存在できませんが、子のいない親は存在しうる、ということです。
親である「部署」テーブルのレコードが更新された際の挙動はテーブル作成時の要件に応じて決まります。ただし、ベストプラクティスは、データの変更は子テーブル→親テーブルの順に行うことです。
また、キーとなる列には、コードやIDなど表記体系の定まった固定長文字列を用いることも意識しましょう。

### その他の制約
**参照整合性制約**の他にもいくつかの制約をつけることが可能です。
代表的なものは以下の3つです。
**NOT NULL 制約**
**一意制約**
**CHECK制約**

#### NOT NULL制約
あるカラムにNULL値（値が空である状態）を許容しないという制約です。
氏名、メールアドレスなど、必ず値が入力されるべき項目に設定することで、データの欠落を防ぎます。NULL値があると集計結果が不正確になる可能性がありますが、NOT NULL制約を設けることで、より正確な集計が可能になります。

#### 一意性制約
あるカラムの値が、テーブル内で重複しないことを保証する制約です。
主キーとして利用することで、各レコードを一意に識別できます。例えば、ユーザーIDやメールアドレスなど、重複を許容できない値に設定することで、データの整合性を保ちます。

#### CHECK制約
カラムの値が特定の条件を満たすことを保証する制約です。
年齢カラムに0以上の数値しか入らないように制限したり（範囲制限）、郵便番号カラムにハイフンを含む8桁の数字しか入らないように制限できます（データの形式制限）。

#### 制約に関する出題

##### 基本情報
<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/736f281c-6a33-5c30-28d4-e62a47dae1ae.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<ア>になります。<br>
外部キーの定義を思い出しましょう。<br>
外部キー(FOREIGN KEY)とは、関連したテーブル間を結ぶために設定する列のことで、データの整合性をデータベースに保証させるために利用するものでした。<br>
これに該当するのは<ア>になります。
</details>

<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/c9542ab3-6296-bab9-4b4c-2788006c226b.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<ウ>になります。<br>
主キーとして利用することで、各レコードを一意に識別できるのでした。また、これを一意性制約と言うのでしたね。
</details>

##### 応用情報
<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/88a88dbf-22fc-7315-c6d1-2a17b7764dde.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<ウ>になります。<br>
FOREIGN KEY（外部キー）とREFERENCES（参照）というワードから参照制約を連想しましょう。
「そういうSQLがあるんだ」ぐらいの認識でOKです。
</details>

<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/5dcd4b8f-c483-2b90-9b97-fd27b8132d68.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<ウ>になります。<br>
参照制約とは、この問題で言うと、製品表に存在しない製品を在庫表に登録しないようにする制約です。<br>
つまり、行の追加に対する制約です。
</details>


## インデックス
インデックスは、本の索引のように、データベースのテーブル内で特定の列の値に基づいてレコードを高速に検索するためのデータ構造です。索引を使用することで、全レコードを逐一調べることなく、目的のレコードに直接アクセスできます。
試験の出題形式は、知識問題が主です。
複雑な図を伴う問題も出題されますが、B-treeインデックスとハッシュ・インデックスの基本的な特徴、例えば**B-treeインデックスは全てのノードが同じ深さ**であることや、**ハッシュ・インデックスが範囲検索に適していない**ことなどを押さえておけば、消去法で正解を導くことができます。

### B-treeインデックス
B-treeインデックスは、データベースやファイルシステムなどで利用される木構造のデータ構造を持つインデックスです。大量のデータに対しても迅速な検索が可能となるため、ビッグデータ時代における重要な技術の１つとなっています。

![スクリーンショット 2024-12-10 6.30.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/9819dccd-b634-666c-cd0b-78fd58549e20.png)
B-treeは、全てのリーフノードが同じ深さになるように設計されています。

### ハッシュ・インデックス
<img width="60%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/2b3754a7-9669-b160-1eb5-1f4cde3b9e2f.png"> 

ハッシュ・インデックスでは，ハッシュ関数と呼ぶ関数を使って，検索に使用するキーとレコードを含むページを直接関係付けます
。例えば，従業員番号をキーとする場合，従業員番号を適当な数で割った余りを返すような関数をハッシュ関数として選び，関数の戻り値（ハッシュ値といいます）が指すページにそのキーを持つレコードを格納しておきます。
こうしておけば，ある従業員番号を持つレコードを検索する際には，ハッシュ関数で特定したページを読み込むだけで済むようになります。
B-treeインデックスより高速なアクセスが可能なのですが、範囲検索やキー値を順番に読み込んで処理を行う用途には使用できません。

### インデックスに関する出題

#### 基本情報
<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/06a3ba85-6078-6564-8648-74eccbc65a12.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<イ>になります。<br>
インデックスは本の索引のようなもの得あり、特定の列（カラム）の値に基づいてレコードを高速に検索するためのデータ構造であることを思い出しましょう。
</details>

<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/dfb08a85-0450-529a-109e-5708c3742ddc.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<エ>になります。<br>
キー値に紐づいたレコードを検索するので、ハッシュインデックスの方が適切と言えます。<br>
他の選択肢は条件検索（ア、ウ）ないし範囲検索（イ）に該当するのでハッシュインデックスには不適です。
</details>

#### 応用情報
<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/7d23d403-e990-762f-7109-facc7bedc3a2.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<エ>になります。<br>
インデックスはあらゆる列に作成することができます。<br>
ただし、インデックスを設定するのはアクセス頻度の高い列にするのが効果的であることは知識として持っておきましょう。
</details>

<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/14af9458-2578-baf7-1b44-493ea4daa45a.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<イ>になります。<br>
B-treeは、全てのリーフノードが同じ深さになるように設計されていることを思い浮かべましょう。それだけで選択肢を絞ることができます。<br>
アとエはA→C2となっておらず、全てのリーフノードの深さが同じであるという定義を満たしていません。<br>
ウに関しては「CがC1とC2に分割された」のに、C1⇄C2となっていません。<br>
消去法によりイが正解であると導けます。
</details>


## 実行計画と統計情報
**実行計画**とはどのようにテーブルに対して検索を行なうかが書かれた、**SQLの実行手順書のようなもの**です。そのため、SQLのパフォーマンスは実行計画によって大きく左右されます。
**統計情報**は例えるならば、**SQLの最適な経路を見つけるために必要な地図情報**です。
SQLには「こんなデータ」が欲しいという条件は記述されていますが、「こうやってデータを取りに行け」という情報は書かれていません。これは車のカーナビと同じです。
ドライバーは「ここに行きたい」という目的地だけを入力し、どのような道を通るべきかは、地図や渋滞情報をもとにカーナビが判断します。
DBMSも同様で、DBMSはユーザーからSQLを受け取ると、どのような経路でデータを探しに行くのが最も効率的であるかを自分で判断します。
基本情報・応用情報での出題頻度は高くありませんが、知識問題しか出題されない上に、覚えることも少ないので短時間で終わらせてしまいましょう。

### SQL実行の流れ
SQLの実行の流れは大まかに以下のようになります。
<img width="80%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/8ecaaf7d-fe5f-8d68-8320-151875bc166b.png"> 

#### パーサー
実行されたSQLの構文解析(パース)を行い、RDBMSが処理しやすい定型的な形式に変換します。これには以下2つの理由があります。

**1.SQL文の整合性チェック**
実行されたSQLが常に正しいとは限りません。例えば、SQLを書いた人がカンマを付け忘れていたり、Fromを書き忘れていたり、、、等があったりします。こういったSQLをまずはこの段階で実行エラーとする必要があります。

**2.後続処理の効率化**
実行されたSQL文を定型的な形式に変換することで、RDBMS内部の後続の処理が効率化されます。

#### オプティマイザ
無事パーサーを通過したSQL文はオプティマイザに送られます。
カタログマネージャから統計情報を受け取った後、最適なデータアクセス方法(実行計画)が決定します。
この処理がRDBMSにおけるコアとなる部分です(頭脳なんて表現のされた方をします)。
オプティマイザは、複数のアクセス経路、インデックスの有無、データの分散や偏りの度合い、RDBMSの内部パラメータなどの条件を考慮して、コストを評価し選択可能な多くの実行計画を作成します。

#### カタログマネージャー
オプティマイザが実行計画を作成するうえでオプティマイザに重要な情報を提供するのがカタログマネージャです。カタログとはRDBMSの内部情報を集めたテーブル群で、テーブルやインデックスの統計情報が格納されています。そのため、このカタログの情報を単に「統計情報」とも呼びます。

### 実行計画と統計情報に関する出題

#### 基本情報
<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/38eeff34-69f0-fb43-f2b5-ae3c698c14b5.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<ア>になります。<br>
統計情報を受け取った後に最適な実行計画を決定するのがオプティマイザの機能でした。
</details>

#### 応用情報
<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/e06ffaae-9506-93de-ce33-0d03166de923.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<イ>になります。<br>
カタログマネージャから統計情報を受け取った後、最適なデータアクセス方法(実行計画)を決定するのでしたね。
</details>


## これ以降の単元について
試験では知識問題しか出題されません。
それぞれの概念も理解が容易な上に問題文や選択肢の文章も大体同じなので、この記事で説明する箇所だけ覚えてしまえば正解を選ぶことができます。
**データウェアハウス**、**データクレンジング**、**データマイニング**といった単語を混同しないようにするのが唯一の注意点です。


## リポジトリ
**リポジトリ**(Repository)はソフトウェア開発と保守における様々な情報を一元的に管理するデータベースです。開発者が効率的に共同作業を行うための基盤を提供します。
ソースコードに加えて仕様書・設計書・マニュアルなども管理することができ、それらのバージョン管理や変更管理、コンフリクトの管理などの機能が備わっています。代表的なツールとしてGitがあります。

### リポジトリに関する出題

#### 基本情報
<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/8c2c5468-6cc4-69a1-7606-3c63bf903206.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<ウ>になります。<br>
リポジトリの役割は開発者が効率的に共同作業を行うための基盤を提供することでしたね。
</details>

#### 応用情報

<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/d61eb467-c8f0-702d-bd15-2535db268c47.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<イ>になります。<br>
ソフトウェア開発と保守における様々な情報を一元的に管理するデータベースがリポジトリでしたね。
</details>


## データウェアハウス
**データウェアハウス**とは、企業内に散在しているデータ資源を有効活用するために基幹系データベースや外部データベースを整理・統合し意思決定プロセスを支援するためのデータベースです。

データウェアハウスを構築する際に使用される元データは、仕様の異なる様々なシステムに蓄積されていた形式がバラバラなデータ群であり、このままではデータマイニングなどの解析で使用することができません。
この生データを解析で使用できるようにするために行われるのが**データクレンジング**です。この作業によりデータ形式の統一、欠損値の補完、単位の統一、などの処理がされたデータによってデータウェアハウスは構築されます。

### データウェアハウスに関する出題

#### 基本情報
<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/7e4efd6a-5af1-e263-93e7-b170483db51d.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<イ>になります。<br>
企業内に散在しているデータ資源を有効活用するために基幹系データベースや外部データベースを整理・統合し意思決定プロセスを支援するためのデータベースをデータウェアハウスと言うのでした。
</details>

<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/fd81a636-ac61-16eb-beaa-1bc4e66792d3.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<イ>になります。<br>
形式がバラバラなデータ群をデータウェアハウス構築で使えるようにする処理をデータクレンジングと言うのでしたね。
</details>


## データマイニング
**データマイニング**(Data Mining)は、データウェアハウスに蓄積されている大量のデータに対して、統計学的手法、数学的手法、機械学習を適用することで、今まで明らかになっていなかった有用な規則性や因果関係を見つけ出す手法です。
従来はデータウェアハウスに適用されることが多かったデータマイニングですが、ビッグデータ時代の到来により、ビッグデータの分析や活用にも適用されるようになっています。

### ビッグデータとデータウェアハウスの違い
**ビッグデータ**とは従来のデータ処理ソフトウェアでは処理しきれない大量で複雑なデータセットのことであり、例えばX(旧Twitter)の書き込みです。
**データウェアハウス**は企業の意思決定支援のために設計された、組織的で統合されたデータセットのことです。銀行の取引履歴がこれの一例になります。

### データマイニングに関する出題

#### 基本情報
<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/f3986efa-febf-22ff-c0c4-4585c469ea53.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<ウ>になります。<br>
大量のデータに対して、統計学的手法、数学的手法、機械学習を適用することで、今まで明らかになっていなかった有用な規則性や因果関係を見つけ出す手法をデータマイニングと言うのでしたね。
</details>

<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/df2178a2-008d-bf93-bebe-fe170f8b762d.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<イ>になります。<br>
データマイニングの定義そのものになります。
</details>

#### 応用情報

<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/5f72c4dd-ec7a-b4b3-e782-d668164e60ac.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<ア>になります。<br>
データマイニングの定義そのものになります。
</details>

<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/9ebe73c5-893c-a352-bf67-7972b9ba9721.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<エ>になります。<br>
データマイニングの定義が頭に入っていれば正解できます。<br>
データウェアハウスと混同しないように気をつけましょう
</details>


## NoSQL
**NoSQL**(Not only SQL)はデータへのアクセス方法をSQLに限定しないデータベース管理システムの総称で**関係データベース管理システム以外のDBMS**という意味で用いられます。
<img width="%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/6c60aa83-ebad-e69c-dc8f-3aa7b7153068.png">
RDBMSは長い歴史を持ち、厳密なスキーマ定義や数学的に定義されたモデル理論、トランザクションのACID特性などによって信頼性に秀でています。しかし、それゆえにデータを扱う際のコストも高くなり、ビッグデータなどの高頻度で膨大なデータを扱う場面ではパフォーマンス面での劣化が現れてきました。
NoSQLは、スキーマレスで計量なのでデータの参照や追加を低コストで実行できます。さらにスケーラビリティにも優れるため大量に蓄積されていくデータを扱うのに適しています。

### キーバリューストア
**キーバリューストア**はNoSQLで用いられるデータ型の一つです。一つのキーに一つの値を結びつけてデータを格納します。構造が単純なのでスケーラビリティや処理速度に優れていて、ビッグデータの処理に使われています。
<img width="%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/ee7b38a7-0c68-7571-ee02-5145c8fd1fe1.png">

### NoSQLに関する出題

#### 基本情報
<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/1b5be378-e876-19f7-e26d-aa518f5efe1f.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<エ>になります。<br>
キーバリューストアは一つのキーに一つの値を結びつけてデータを格納するのでしたね。
</details>

#### 応用情報
<details open>
<summary>問題</summary>
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3926197/3076d3e6-5d91-d8a3-c913-2558a21a8910.png">
</details>
<details>
<summary>解答と解説</summary>
正解は<ウ>になります。<br>
NoSQLで用いられるデータ型の一つがキーバリューストアですので、キーバリューストアの定義であるウの選択肢が正解になります。
</details>


# おわりに
最後までお読みいただき、ありがとうございます。
この記事を読んでいただいた方が1人でも多く試験に合格するよう祈っております。

:::note info
弊社Nucoでは、他にも様々なお役立ち記事を公開しています。よかったら、Organizationのページも覗いてみてください。
また、Nucoでは一緒に働く仲間も募集しています！興味をお持ちいただける方は、[こちら](https://www.recruit.nuco.co.jp/?qiita_item_id=5afaa28fc851bc7f860e)まで。
:::


# 参考書籍
[おうちで学べるデータベースのきほん](https://www.shoeisha.co.jp/book/detail/9784798135168)
[達人に学ぶDB設計　徹底指南書](https://www.shoeisha.co.jp/book/detail/9784798128931)