データベースの新卒研修まとめ

## 1.はじめに
はじめまして。新卒一年目のイズミと申します！
今回、Qiitaへの初投稿として私が4月に受けた**データベース研修**で学んだことや気づきについてまとめていきます。

いくつか受けた研修の中でデータベース研修を選択した理由は、**技術面**と**コミュニケーション面**の両方に通ずる大事なことに気づいた研修だったからです。

## 2.研修内容
研修は午前が用語やしくみなどについて座学を行い、午後は演習問題をメインで進める流れでした。ここでは、学んだ内容についてまとめていきます。

### 2.1.データベースとは
まず、簡単にデータベース(以下DB)とは**特定の条件に当てはまるデータをたくさん集めて、後で使いやすい形に整理した情報のかたまりの事**をいいます。その中で、主流なのが表形式で管理するリレーショナルデータベース（以下RDB）と呼ばれるものです。

使用するメリットとして
*1.複数のデータをまとめて管理することができる*
*2.目的のデータを簡単に探すことができる*
*3.編集が簡単*
などがあげられます。

今回の研修ではRDBの操作をする、SQL（Structured Query Language）という言語を使用しました。

### 2.2.基本的な用語について
ここでは研修で出てきた基本的な用語についてまとめていきます。

#### 2.2.1. スキーマ
スキーマはフォルダのようにデータベースを領域で区切ったもののことです。

#### 2.2.2. テーブル
テーブルとはデータが格納される場所のことで、行と列の表形式で構成されています。

スキーマとテーブルを図で表すとこのような形になります。

![スキーマ_テーブル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3797818/b06f4ee5-554d-4f52-81ee-b039698ba62d.png)


#### 2.2.3. カラム
カラムはテーブルの列のことです。

#### 2.2.4. レコード
レコードはテーブルの行のことです。

カラムとレコードをそれぞれ図で表すとこのようになります。

![カラム_レコード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3797818/ceedeebc-3d9b-4939-b39d-13dba9ffb2f4.png)


### 2.3. 扱ったDBとSQL文
ここでは研修内で扱ったDBやSQL文についてまとめていきます。
4月の研修ではDBから特定のデータを取得するためのSQL文を主に使用しました。

####　2.3.1. 使用したDB 
研修で使用したDBは架空の会員制ショッピングサイトを想定したDBとなっており、スキーマは一人に対して一つあります（今回はuserスキーマとします）。
また、テーブルは以下のものを使用しています（一部加工済み）。


#### 会員テーブル　
| 会員id |   姓   |   名   | 性別 |  生年月日  |  住所 | tel |
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|A0001  | Z木   | Y太   | 男   | 1998-09-17 | T県T市   | xxxx-xxx-xxxx|
|A0002  | Y田   | I郎   | 男   | 1970-02-06 | T県M市   | xxxx-xxx-xxxx|
|A0003  | T中   | H子   | 女   | 1992-11-11 | T県H市   | xxxx-xxx-xxxx|
|A0004  | Y川   | A子 | 女  | 2000-05-31 | T県H市   | xxxx-xxx-xxxx|
|A0005  | K本   | S治   | 男   | 1967-03-09 | X県M市   | xxxx-xxx-xxxx|
|A0006  | M山   | B美 | 女   | 2003-09-03 | K県Y市 | xxxx-xxx-xxxx|
|A0007  | S木   | G郎   | 男   | 1991-09-30 | T県M市   | xxxx-xxx-xxxx|


#### 商品テーブル
 |商品id |         商品名          | 単価 | カテゴリ| 
|:-:|:-:|:-:|:-:|
 |a00001 | 青島みかんL1kg          |  300 | 食品|
 |a00002 | LANケーブル             |  100 | 家電|
 |a00003 | 早生みかん1個           |   30 | 食品|
 |a00004 | 愛媛蜜柑ジュース        |  200 | 食品|
 |a00005 | 結束バンド              |  100 | 雑貨|
 |a00006 | ポテトチップス のりしお |   80 | 食品|
 |a00007 | スマホケース            | 1200 | 雑貨|

 #### 注文明細テーブル
  |  注文id     | 商品id | 個数 |
|:-:|:-:|:-:|
 |2020040100001 | a00001 |   40|
 |2020040100001 | a00002 |    5|
 |2020040100002 | a00001 |   30|
 |2020040100002 | a00003 |  100|
 |2020040100002 | a00004 |   39|
 |2020040100003 | a00001 |  500|
 |2020040100004 | a00002 |    4|
 |2020040100004 | a00004 |   12|
 |2020040100004 | a00005 |  299|



#### 2.3.2. SELECT
特定のテーブルから情報を取得する際に使用します。特定の列（カラム）に絞って取得することも可能です。

**SELECT (カラム名) FROM (スキーマ名).(テーブル名);**

のような形で使用します。

```SQL:SELECT入力例
--(1)会員テーブルからすべての情報を取得したい場合
SELECT * FROM user.会員;

--(2)会員テーブルから氏名の情報だけ取得したい場合
SELECT 姓,名 FROM user.会員;

```
```:結果
(1)会員テーブルからすべての情報を取得したい場合

会員id |   姓   |   名   | 性別 |  生年月日   |  住所    | tel 
-------+-------+--------+------+------------+----------+---------------
A0001  |  Z木   |   Y太  | 男   | 1998-09-17 | T県T市   | xxxx-xxx-xxxx
A0002  |  Y田   |   I郎  | 男   | 1970-02-06 | T県M市   | xxxx-xxx-xxxx
A0003  |  T中   |   H子  | 女   | 1992-11-11 | T県H市   | xxxx-xxx-xxxx
A0004  |  Y川   |   A子  | 女   | 2000-05-31 | T県H市   | xxxx-xxx-xxxx
A0005  |  K本   |   S治  | 男   | 1967-03-09 | X県M市   | xxxx-xxx-xxxx
A0006  |  M山   |   B美  | 女   | 2003-09-03 | K県Y市   | xxxx-xxx-xxxx
A0007  |  S木   |   G郎  | 男   | 1991-09-30 | T県M市   | xxxx-xxx-xxxx


(2)会員テーブルから氏名の情報だけ取得したい場合
   姓   |   名    
-------+--------
  Z木   |   Y太  
  Y田   |   I郎  
  T中   |   H子  
  Y川   |   A子  
  K本   |   S治  
  M山   |   B美  
  S木   |   G郎  
```

"*"は**すべてのカラム**を意味しています。
結果として、(1)ではテーブル内のすべての列の情報が表示され、(2)では氏名（姓と名の列）の情報のみ表示されます。

#### 2.3.3. WHERE
SELECTを使って情報を取得する際に、WHEREを使用することで、特定の行（レコード）の情報を取得することが可能です。

**WHERE (カラム名) (比較演算子) (任意の値)**

のような形で使用します。

```SQL:WHERE実行例
--(3)会員テーブルから男性の情報だけ取得する場合
SELECT * FROM user.会員
WHERE 性別 = '男';
```
```:結果
(3)会員テーブルから男性の情報だけ取得する場合
会員id |   姓   |   名   | 性別 |  生年月日   |  住所    | tel 
-------+-------+--------+------+------------+----------+---------------
A0001  |  Z木   |   Y太  | 男   | 1998-09-17 | T県T市   | xxxx-xxx-xxxx
A0002  |  Y田   |   I郎  | 男   | 1970-02-06 | T県M市   | xxxx-xxx-xxxx
A0005  |  K本   |   S治  | 男   | 1967-03-09 | X県M市   | xxxx-xxx-xxxx
A0007  |  S木   |   G郎  | 男   | 1991-09-30 | T県M市   | xxxx-xxx-xxxx
```

このように性別が男性の行だけが表示されます。
また、よく使用される比較演算子は以下の６つとなっています。

| 比較演算子 | 意味 |
|:-:|:-:|
| = | 等しい |
| < | 左辺の値が右辺の値より小さい |
| > | 左辺の値が右辺の値より大きい |
| <= | 左辺の値が右辺の値以下 |
| >= | 左辺の値が右辺の値以上 |
| <> | 等しくない |






#### 2.3.4. 様々な特定行の取得方法
WHEREを使用する際に複数の条件を組み合わせて特定の行を取得したり、「値に〇〇が含まれる」などの"="よりもあいまいな検索をすることも可能です。

```SQL:様々な特定行の取得方法

--(4)複数条件の指定
SELECT * FROM user.会員
WHERE 性別 = '女' AND 会員ID <= 'A0004';

--(5)複数条件のうちいずれかに合致する場合
SELECT * FROM user.会員
WHERE 性別 = '女' OR 住所 = 'X県M市';

--(6)括弧内の複数条件のうちいずれかに一致する場合
SELECT * FROM user.会員
WHERE 会員ID IN ('A0001','A0004','A0006');

--(7)あいまいな検索
SELECT * FROM user.会員
WHERE 姓 LIKE '%木%';
```
```:結果
(4)複数条件の指定
会員id |   姓   |   名   | 性別 |  生年月日   |  住所    | tel 
-------+-------+--------+------+------------+----------+---------------
A0003  |  T中   |   H子  | 女   | 1992-11-11 | T県H市   | xxxx-xxx-xxxx
A0004  |  Y川   |   A子  | 女   | 2000-05-31 | T県H市   | xxxx-xxx-xxxx

(5)複数条件のうちいずれかに合致する場合
会員id |   姓   |   名   | 性別 |  生年月日   |  住所    | tel 
-------+-------+--------+------+------------+----------+---------------
A0003  |  T中   |   H子  | 女   | 1992-11-11 | T県H市   | xxxx-xxx-xxxx
A0004  |  Y川   |   A子  | 女   | 2000-05-31 | T県H市   | xxxx-xxx-xxxx
A0005  |  K本   |   S治  | 男   | 1967-03-09 | X県M市   | xxxx-xxx-xxxx
A0006  |  M山   |   B美  | 女   | 2003-09-03 | K県Y市   | xxxx-xxx-xxxx

(6)括弧内の複数条件のうちいずれかに一致する場合
会員id |   姓   |   名   | 性別 |  生年月日   |  住所    | tel 
-------+-------+--------+------+------------+----------+---------------
A0001  |  Z木   |   Y太  | 男   | 1998-09-17 | T県T市   | xxxx-xxx-xxxx
A0004  |  Y川   |   A子  | 女   | 2000-05-31 | T県H市   | xxxx-xxx-xxxx
A0006  |  M山   |   B美  | 女   | 2003-09-03 | K県Y市   | xxxx-xxx-xxxx

(7)あいまいな検索
会員id |   姓   |   名   | 性別 |  生年月日   |  住所    | tel 
-------+-------+--------+------+------------+----------+---------------
A0001  |  Z木   |   Y太  | 男   | 1998-09-17 | T県T市   | xxxx-xxx-xxxx
A0007  |  S木   |   G郎  | 男   | 1991-09-30 | T県M市   | xxxx-xxx-xxxx

```

このようにANDを用いた(4)では**どちらの条件も満たす行**が取得され、ORを用いた(5)では、**どちらか一つでも条件を満たしている行**が取得できます。また、INを用いた(6)は**同じカラム内で条件を複数指定したいとき**などに使えます。

(7)で使われた"%"はワイルドカードと呼ばれ、**０文字以上の任意の文字列**を表しています。'%木%'のように囲うことで**文字"木"の前後にどのような文字があっても良い**という意味になります。
今回の場合、LIKEを用いることで苗字に"木"がつく会員の情報が取得できるようになります。


#### 2.3.5. 並び替え
テーブルから情報を取得する際に、特定の列を基準に並び替えをすることができます。

**ORDER BY (カラム名) ASC;**

のような形で使用します。
**ASC**は昇順で並び替えたいときに記述します。降順に並び替えたい場合はASCを**DESC**に変えます。

```SQL:並び替え
--(8)男性会員を生年月日を基準に昇順に並び替え
SELECT * FROM user.会員
WHERE 性別 = '男'
ORDER BY 生年月日 ASC;

--(9)男性会員を生年月日を基準に降順に並び替え
SELECT * FROM user.会員
WHERE 性別 = '男'
ORDER BY 生年月日 DESC;
```

```:結果
(8)男性会員を生年月日を基準に昇順に並び替え
会員id |   姓   |   名   | 性別 |  生年月日   |  住所    | tel 
-------+-------+--------+------+------------+----------+---------------
A0005  |  K本   |   S治  | 男   | 1967-03-09 | X県M市   | xxxx-xxx-xxxx
A0002  |  Y田   |   I郎  | 男   | 1970-02-06 | T県M市   | xxxx-xxx-xxxx
A0007  |  S木   |   G郎  | 男   | 1991-09-30 | T県M市   | xxxx-xxx-xxxx
A0001  |  Z木   |   Y太  | 男   | 1998-09-17 | T県T市   | xxxx-xxx-xxxx

(9)男性会員を生年月日を基準に降順に並び替え
会員id |   姓   |   名   | 性別 |  生年月日   |  住所    | tel 
-------+-------+--------+------+------------+----------+---------------
A0001  |  Z木   |   Y太  | 男   | 1998-09-17 | T県T市   | xxxx-xxx-xxxx
A0007  |  S木   |   G郎  | 男   | 1991-09-30 | T県M市   | xxxx-xxx-xxxx
A0002  |  Y田   |   I郎  | 男   | 1970-02-06 | T県M市   | xxxx-xxx-xxxx
A0005  |  K本   |   S治  | 男   | 1967-03-09 | X県M市   | xxxx-xxx-xxxx
```

このように、(8)では年齢の高い順に、(9)では年齢が若い順に並び替えされます。


#### 2.3.6. 集計関数
集計関数というものを使用することで、条件を満たす会員情報の件数や、指定したカラムの値の合計、最大値などを取得することができます。

**SELECT (集計関数) FROM (スキーマ名).(テーブル名)**

のような形で使用します。

```SQL:集計関数
--(10)女性会員の数を取得
SELECT COUNT(*) FROM user.会員
WHERE 性別 = '女';

--(11)一番若い会員の生年月日を取得
SELECT MACX(生年月日) FROM user.会員;

```
```:結果
(10)女性会員の数を取得
 count 
-------
     3

(11)一番若い会員の生年月日を取得
    max     
------------
 2003-09-03

```

このように、(10)では女性の会員の数が取得でき、(11)では一番若い会員の生年月日が取得できます。
COUNTやMAXのほかにも集計関数はあり、その中でもよくつかわれるものを下の表まとめます。

| 集計関数 | 取得するもの |
|:-:|:-:|
| COUNT(カラム名) | 指定したカラムを基準にレコードの件数 |
| MAX(カラム名) | 指定したカラムの中の最大値 |
| MIN(カラム名)| 指定したカラムの中の最小値 |
| SUM(カラム名) | 指定したカラムの内容をすべて合算 |
| AVG(カラム名) | 指定したカラムの内容の平均 |


#### 2.3.7. 結合
連動した別のテーブルの情報も同時に取得したい場合にテーブル同士の結合を行うこともできます。結合をすることで、自分のテーブルにない情報を参照することが可能となります。

**INNER JOIN (テーブル名) ON (結合条件)**

のような形で使用します。

```SQL:結合
--(12)注文明細テーブルと商品IDテーブルを結合することで注文ID,商品ID,商品名を同時に取得する
SELECT 注文明細.注文ID, 注文明細.商品ID, 商品.商品名
FROM user.注文明細
INNER JOIN user.商品 ON 注文明細.商品ID = 商品.商品ID

```

```:結果
(12)注文明細テーブルと商品IDテーブルを結合することで注文ID,商品ID,商品名を同時に取得する
    注文id     | 商品id |      商品名      
---------------+--------+------------------
 2020040100001 | a00001 | 青島みかんL1kg
 2020040100001 | a00002 | LANケーブル
 2020040100002 | a00001 | 青島みかんL1kg
 2020040100002 | a00003 | 早生みかん1個
 2020040100002 | a00004 | 愛媛蜜柑ジュース
 2020040100003 | a00001 | 青島みかんL1kg
 2020040100004 | a00002 | LANケーブル
 2020040100004 | a00004 | 愛媛蜜柑ジュース
 2020040100004 | a00005 | 結束バンド
```

このように、注文明細テーブルには存在しない商品名の情報を、商品IDテーブルとの結合により取得することができます。結合条件は**注文明細.商品ID = 商品.商品ID**のようにそれぞれのテーブルで共通となるカラムを"="でつなげることが必要です。





## 3.所感
DBに関しては大学の講義で扱った内容がほとんどであったため演習問題を早く完了させることができました。完了後は同期に教えるなどしており、ここでは、**人に教える・説明するという行為を通して得た気づき**についてまとめていきます。

### 3.1.考えたこと・気づき
私が同期に演習問題について教える中で気づいたことは**演習問題の手助けという観点において、はじめに答えを言ってから説明するのは好ましくない**という点です。
私はこれまで、このような場面では先に答えを言って、そのあとに理由を述べるタイプでした。しかし、これでは迷路に迷った人をゴールまでワープさせているようなものです。後にどうすればゴールにたどり着けるか、地図を見せながら説明されても、受け手が同じ迷路を一人で攻略するのは難しいと思います。

そこで私は、**答えまでの道案内をする工夫**ができるようになりたい考えました。

そのために実行したのが**3つ**の手順です（ほとんどビジネススキル研修で学んだことを頑張って実践しただけです...）。

 1. 自分はどのようにして答えにたどり着いたかを考える
 →自分の辿ったルートの確認をする
 2. 1.を整理、言語化する
 →どこで曲がったや、どこまで進む、どんな目印があるなどをまとめる
 3. まとめたものを相手に合った表現、語彙で説明する
→相手が一番使いやすいルートを紹介する

正直3番は全然できていないと思いますが、これをやることで、今自分が何をやっているのかや使っている技術について、より理解を深めることが出来たと思います。


## 4. まとめ
今回は、データベースの研修で扱った内容や、研修を経て気づいたことなどをまとめました。
これから仕事をしていくうえで、自分がやったことを整理して伝える能力は必須級であると考えているので、実践練習することができたのはとても良い経験となりました。