基本情報技術者試験　データベース編①

#初めに
この教本を参考に、備忘録として書いていきます。

[キタミ式イラストIT塾 基本情報技術者 令和03年 | Amazon](https://www.amazon.co.jp/%E3%82%AD%E3%82%BF%E3%83%9F%E5%BC%8F%E3%82%A4%E3%83%A9%E3%82%B9%E3%83%88IT%E5%A1%BE-%E5%9F%BA%E6%9C%AC%E6%83%85%E5%A0%B1%E6%8A%80%E8%A1%93%E8%80%85-%E4%BB%A4%E5%92%8C03%E5%B9%B4-%E3%81%8D%E3%81%9F%E3%81%BF%E3%82%8A%E3%82%85%E3%81%86%E3%81%98/dp/4297117819)

#◯データベースとDBMS
データベース(以下、DB)は様々なデータを保存したり、蓄積したり
そこから情報を取得したりと多くのデータを扱う為には欠かせないものです。

例えば、企業だと「顧客情報」や「社員情報」、「製品情報」など
色んな大量のデータを扱わないといけません。

バラバラに管理していれば、整合性が保てないのでまとめて管理しています。

特に、`複数の利用者が大量のデータを共同利用`する際に強力です。

DBにはいくつか種類があり、中でも`関係型`と呼ばれるDBが主流となっています。

###・表、行、列で出来ている
関係DBは、`表の形でデータを管理`します。
![スクリーンショット 2021-07-13 19.15.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/1676f557-a59a-b02f-3fb6-2174552bff1c.png)
「表」なのでエクセルなんかを思い浮かびますが
そもそもの役割が違うので全くの別物です。

・DB：
`データを貯め込むこと`が主な目的

・エクセル(表計算)：
表を作ることが主な目的

タイトルにもあるように`表`、`行`、`列`で関係DBは構成されており、
`データ１件が１つの行`として記録され、追加・削除・更新も行単位で行われます。

この行が複数集まることにより、表の形が出来上がっていくイメージです。

先ほどの表で確認してみましょう。

・`表(テーブル)`：
複数のデータ(行)を収容する場所のこと。
![スクリーンショット 2021-07-13 19.15.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/1676f557-a59a-b02f-3fb6-2174552bff1c.png)
・`行(レコード、組、タプル)`：
１件分のデータのこと。
![スクリーンショット 2021-07-13 19.15.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/1f5b3a61-7594-45ad-6692-0a66143c2800.png)
・`列(フィールド、属性)`：
データを構成する各項目のこと。
![スクリーンショット 2021-07-13 19.15.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/ae8ba641-c4de-9f3e-2ea9-eb74c2c9c59a.png)
なんで「`関係`」なのかというとデータの内容次第で
`複数の表を関係付けして扱うことができるから`です。

この「関係」のことを`リレーションシップ`と呼び
関係DBは、`リレーショナルデータベース(RDB)`と呼ばれます。

###・DBMS(データベース管理システム)
DBの管理を効率化する`DBMS`というソフトウェアがあります。

これはユーザーに代わって、`DBの整理やデータの検索、更新、共有など`を行ってくれます。
手動で行うようりも、データ管理の手間が大幅に削減できます。

実際にDBを操作する際には、`SQL言語`を使用して操作していきます。

この言語については次の記事で書きます。

主な製品として

・[MySQL](https://www.mysql.com/jp/)
・[Oracle Database](https://www.oracle.com/jp/database/)
・[SQLSever](https://www.microsoft.com/ja-jp/sql-server/sql-server-2016)

などがあります。

#・主キー
例えば、「松本潤」さんが退職することになったとします。
そうなった場合、DB上にある社員情報を更新しなければいけません。

しかし、営業部と開発部に「松本潤」さんがいました。

こうなった場合、どの部署の「松本潤」さんかを特定する作業が発生してしまいます。

これを回避するためにDBの表には、その中のひとつひとつを識別できるようにキーとなる情報が含まれています。

これを`主キー`と呼びます。

現実世界で例えると、マイナンバーや社員番号などがまさにそれです。

###・主キーは行を特定する
`表の中で各行を識別するために使う列のこと`を主キーと呼びます。

先ほどの表だと、
![スクリーンショット 2021-07-13 19.15.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/1676f557-a59a-b02f-3fb6-2174552bff1c.png)
「社員番号」が主キーに適しています。
![スクリーンショット 2021-07-13 19.15.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/40423798-d5fc-268e-910a-b2ce6933a75d.png)
主キーにできる条件として

・`表の中で内容が重複しないこと`
・`内容が空ではないこと`

の2点です。

###・複合キー
ちなみに、ひとつの列では重複するけど、`複数の列を組み合わせれば重複しない`という場合があります。

例えば、以下の表があったとして
![スクリーンショット 2021-07-13 19.28.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/271488d6-03dd-2cc2-22eb-a7e761724125.png)
この表から`出席番号1番の人`を取り出すと
「田中」さん、もしくは「佐藤」さんが該当してしまいます。

では、「`出席番号 + 性別`」だったらどうでしょうか？

`出席番号1番の人で男性`を取り出せば、「`田中`」さんしか該当しません。

このように「出席番号 + 性別」といった複数の列をワンセットとして
主キーとするのを`複合キー`と呼びます。

#◯正規化
関係DBでは、蓄積されているデータに`矛盾`や`重複`が生じないように
表を最適化するのがお約束となっています。

これを`正規化`と呼びます。

DBで管理する表の設計を行なっていく上で欠かす事ができません。

ちなみに正規化されていない表を`非正規形`と呼びます。

###・非正規形
例えば、以下のような表があったとします。
![スクリーンショット 2021-07-13 12.58.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/9a3628b2-6623-c7e7-a0d8-b7d869a86f6f.png)

行の長さがバラバラで見にくいですね。
このような表が`非正規形`です。

関係DBではこのような表を管理することはできず、整える必要がある訳です。

###・第1正規形
まず、非正規形から`第1正規形`にしないといけません。

素直な二次元の表にするため以下のように、切り離します。
![スクリーンショット 2021-07-13 12.58.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/2ffba795-cad4-0d86-2d6b-4516caea38ce.png)

そして、独立した行を挿入してやることで
素直な二次元の表が出来上がります。
![スクリーンショット 2021-07-13 12.57.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/7a2a2c80-b074-907a-09a8-6689041a4256.png)

###・第2正規形
次に第1正規形から`第2正規形`にしていきます。

というわけで以下のようになります。

・受注表
![スクリーンショット 2021-07-13 12.55.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/004a1355-efae-5f76-e74b-5d0e3fc21401.png)

・商品表
![スクリーンショット 2021-07-13 12.55.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/407928e8-e379-b5fd-3299-f00c945f5a78.png)

・明細表
![スクリーンショット 2021-07-13 12.55.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/4be2d05b-2185-fe03-32e0-27ed90f97033.png)

何故このように分離できるのかというと`関数従属`と`部分関数従属`というのが関わってくるからです。

###・関数従属と部分関数従属
これらは表の中における列と列との関係を表したもので
主キー(複合キー)に対して、その項目がどんな関係にあるかを表現しています。

#####○関数従属
以下は先ほど分離した表です。
![スクリーンショット 2021-07-13 12.55.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/407928e8-e379-b5fd-3299-f00c945f5a78.png)
「商品コード」が決まれば「商品名」や「単価」も決まっていきます。
このように主キーが決まれば、列の値も決まる関係を`関数従属`と呼びます。

例えば、「商品名」は「商品コード」に関数従属していると使われます。

#####○部分関数従属
行の特定は主キー(または複合キー)で行うわけですが、以下の表のように
![スクリーンショット 2021-07-13 12.57.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/7a2a2c80-b074-907a-09a8-6689041a4256.png)
`複合キー(受注No　＋　商品コード)の一部の項目だけで列の値が決まる関係`があります。

先ほど分離した以下の表です。

・受注表
![スクリーンショット 2021-07-13 12.55.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/004a1355-efae-5f76-e74b-5d0e3fc21401.png)
・商品表
![スクリーンショット 2021-07-13 12.55.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/407928e8-e379-b5fd-3299-f00c945f5a78.png)
「受注No」が決まれば、「受注日時」、「顧客コード」、「顧客名称」が決まります。
そして、「商品コード」が決まれば、「商品名」、「単価」が決まります。

このような関係を`部分関数従属`と呼びます。

そして、最後に以下の表が出来て、計３つの表に分離できました。

・明細表
![スクリーンショット 2021-07-13 12.55.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/4be2d05b-2185-fe03-32e0-27ed90f97033.png)
これが`第2正規形`になります。

###・第3正規形
最後に第2正規形から`第3正規形`にしていきます。
`主キー以外の列に関数従属している列を切り出したもの`が第3正規形となります。

以下の表が切り出せそうですね。

・受注表
![スクリーンショット 2021-07-13 12.55.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/004a1355-efae-5f76-e74b-5d0e3fc21401.png)
「顧客名称」は主キーの「受注No」ではなく
「顧客コード」を主キーとして決定されそうです。

というわけで、以下のように分離できます。

・受注表
![スクリーンショット 2021-07-13 14.30.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/a5dff59c-77e0-bb5c-c58e-5def867166ff.png)
・顧客表
![スクリーンショット 2021-07-13 14.24.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/f9569328-c4a5-a7eb-00e0-6dbb0390b015.png)

第3正規形で重要なのは`更に分離できそうな所を分離する`ということです。

ちなみに、主キー以外の列に関数従属している列のことを
`推移的関数従属`と呼びます。

ここでは「顧客名称」がそうですね。

これで計4つの表が出来ました。

・受注表
![スクリーンショット 2021-07-13 14.30.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/a5dff59c-77e0-bb5c-c58e-5def867166ff.png)
・顧客表
![スクリーンショット 2021-07-13 14.24.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/f9569328-c4a5-a7eb-00e0-6dbb0390b015.png)
・商品表
![スクリーンショット 2021-07-13 12.55.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/407928e8-e379-b5fd-3299-f00c945f5a78.png)
・明細表
![スクリーンショット 2021-07-13 12.55.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/743730/4be2d05b-2185-fe03-32e0-27ed90f97033.png)
このように正規化することによって効率的に管理できる表の構造となります。

#おわりに
とりあえず、今回はここまでです。

[次の記事](https://qiita.com/reo0612/items/aaffd13da71fcb6c77e9)ではSQLについて記事を書いています。