データベースの基礎：RDBMS、MySQLの基礎、ビッグデータ

#データベースとは

データベースは名前の通り、**データを蓄積したもの**ですが、ただ無闇矢鱈にデータを蓄積したものではなく、**「目的に応じて扱いやすいようにデータを蓄積する」**というのが重要です。

データベースというと、会社や大学のデータを管理しているお堅いものというイメージがあるかもしれませんが、そんなことはく、日常の様々な場所で使わているものです。例えば、我々が良く利用するAmazonや楽天などの**ECサイト**も立派なデータベースです。正確には、これらは**データベースアプリケーション**というものになりますが、顧客や商品の情報をデータベースで管理しています。


#データベースの利点

それでは、通常データをハードディスクやリムーバブルディスクなどの補助記憶装置に保存するのと、データベースで管理するのではどういった点が異なっているのでしょうか。主な違いには以下のようなものがあります。

- 目的のデータを発見するのが容易である
- 異なるアプリケーションや、複数人で使用することが可能である

1つ目の**目的のデータを発見するのが容易である**という点に関して、通常データをPCに保存する際、きっちりと一定の形式で後々探しやすくするために万全の体制で保存するといったことはまれです。自分が過去に保存したファイルがどこにいったか分からなくなるというようなことはしばしばあります。しかし、データベースでは、予め**目的に応じて保存するデータ構造がきっちり規定**されており、データの追加や削除、さらに、検索など様々な操作を行いやすい形でデータを管理しているのです。

2つ目の**異なるアプリケーションや、複数人で使用することが可能である**という点についてですが、通常PCでデータを保存する際は、自分の使っているアプリケーション特有の保存形式で保存することが多いです。しかし、そのデータを他人が使う際、違うアプリケーションを用いているとそのデータを使うことができないということになりかねません。次に、あるデータを複数人で扱いたいという時、そのデータを何の工夫も行わずに適当に複数人で編集を行なうと、編集後のデータに関して何の整合性もとれません。これらの問題点を解決し、異なるアプリケーションや、複数人でデータを使用できるようにするというのが、データベースの目的です。




#データベースの種類

代表的なデータベースには、以下の3種類があります。

- 階層型データベース
- ネットワーク型データベース
- リレーショナルデータベース

この中でも、特によく用いられるのは、**リレーショナルデータベース**です。下のように、**データやデータ間の関連を2次元の表**で表します。また、このデータベースを管理するシステム全体を**RDBMS(relational database management system)**といいます。

![table.png](https://qiita-image-store.s3.amazonaws.com/0/208575/59733bdd-8bd6-5c44-6b12-25607e9461ec.png)







#MySQLの基礎
前章で説明したRDBMSの1つである、**MySQL**を用いて、実際にデータベースを操作してみます。

##MySQLのインストールから起動まで

####MySQLをインストール

```
$ brew install mysql 
```

####MySQLを起動

```
$ mysql.server start
```

####MySQLの初期設定

```
$ mysql_secure_installation
```

色々な設定がありますが、とりあえずはすべてyesでOKです。パスワードを求められるのでパスワードも設定しておきます。

####MySQLに接続

```
$ mysql -u root -p
```
<br />

今はする必要はないですが、MySQLの接続を停止し、MySQLを終了する手順も確認しておきます。

####MySQLの接続を停止

```
mysql> \q
```

####MySQLを終了

```
$ mysql.server stop
```

##データベースの作成

まずは、データベースを作成します。

```
mysql> create database mydb;
```

データベースの一覧は以下のようにして確認することができます。

```
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
```
データベース「mydb」が作成されていることが分かります。ちなみに、データベースは

```
mysql> drop database [データベース名];
```

で削除することができます。今作成した「mydb」以外の3つのデータベースはシステムが利用しているデータベースなので削除しないようにしましょう。

次に、今作成したデータベースを操作対象に設定します。

```
mysql> use mydb;
Database changed
```

操作対象になっているデータベースは次のようにして確認することができます。

```
mysql> select database();
+------------+
| database() |
+------------+
| mydb       |
+------------+
```

「mydb」が操作対象になっていることが分かります。

##テーブルの作成

今回作成するテーブル(表)は次のようなものです。

|ID|名前|所属 |職種|年齢|犯罪係数|
|:--|:--|:--|:--|:--|:--|
|1001|常守朱|刑事課一係|監視官|20|36|
|1011|宜野座伸元|刑事課一係|監視官|27|60|
|1012|狡噛慎也|刑事課一係|執行官|28|282|
|2011|青柳璃彩|刑事課二係|監視官|28|53|
|2021|須郷徹平|刑事課二係|執行官|22|123|
|9001|唐之杜志恩|総合分析室|分析官|27|144|

それでは、このテーブルを作成するコードを書いていきます。

```sql:table.sql
create table users (
    ID int, 
    Name varchar(20),  
    Affiliation varchar(30),  
    Job_category varchar(20),  
    Age int,  
    Criminal_coefficient int  
);

insert into users (ID, Name, Affiliation, Job_category, Age, Criminal_coefficient) values
    (1001, "AKANE TUNEMORI", "Criminal Affairs Section 1", "Watchman", 20, 36),
    (1011, "GINOZA NOBUTIKA", "Criminal Affairs Section 1", "Watchman", 27, 60),
    (1012, "KOOGAMI SIN-YA", "Criminal Affairs Section 1", "Enforcer", 28, 282),
    (2011, "AOYANAGI RISA", "Criminal Affairs Section 2", "Watchman", 28, 53),
    (2021, "SUGOO TEPPEI", "Criminal Affairs Section 2", "Enforcer", 22, 123),
    (9001, "KARANOMORI SION", "Integrated analysis room", "Analyst", 27, 144);
```

上部でテーブルの構造を決定し、下部でデータの挿入をおこなっています。


テーブルの構造を決定する部分は、

```
create table [テーブル名] (
    [列名] [データ型]
    [列名] [データ型]
    [列名] [データ型]
);
```

と指定する必要があります。MySQLではデータ型として、主に、**数値型**、**文字列型**、**日付・時間型**などが扱えます。

####数値型
1. 整数型  ： INT, SMALLINT
2. 固定小数点型 ： DECIMAL
3. 浮動小数点型 ： FLOAT, DOUBLE

####文字列型
1. 固定長文字列型 ： CHAR
2. 可変長文字列型 ： VARCHAR

####日付・時間型
1. 日付型 ： DATE
2. 時間型 ： TIME


それでは、これを実行してテーブルを作成してみます。

```
mysql> \. ./table.sql
Query OK, 0 rows affected (0.01 sec)

Query OK, 0 rows affected (0.03 sec)

Query OK, 6 rows affected (0.01 sec)
Records: 6  Duplicates: 0  Warnings: 0
```

これでテーブルが作成されました。テーブルの中身がどうなっているか見てみます。

```
mysql> select * from `users`;
+------+-----------------+----------------------------+--------------+------+----------------------+
| ID   | Name            | Affiliation                | Job_category | Age  | Criminal_coefficient |
+------+-----------------+----------------------------+--------------+------+----------------------+
| 1001 | AKANE TUNEMORI  | Criminal Affairs Section 1 | Watchman     |   20 |                   36 |
| 1011 | GINOZA NOBUTIKA | Criminal Affairs Section 1 | Watchman     |   27 |                   60 |
| 1012 | KOOGAMI SIN-YA  | Criminal Affairs Section 1 | Enforcer     |   28 |                  282 |
| 2011 | AOYANAGI RISA   | Criminal Affairs Section 2 | Watchman     |   28 |                   53 |
| 2021 | SUGOO TEPPEI    | Criminal Affairs Section 2 | Enforcer     |   22 |                  123 |
| 9001 | KARANOMORI SION | Integrated analysis room   | Analyst      |   27 |                  144 |
+------+-----------------+----------------------------+--------------+------+----------------------+
```

指定通りのテーブルが作成されていることが分かります。テーブルを表示するには

```
select [列名] from `[テーブル名]`;
```

で行います。列名に*を指定することですべての列、すなわち、表全体を表示することができます。



##テーブルの編集

###行の挿入、削除

テーブルを作成することができたので、次にテーブルの編集をやってみます。まずは、**行の挿入と削除**を行います。例として、

|ID|名前|所属 |職種|年齢|犯罪係数|
|:--|:--|:--|:--|:--|:--|
|1012|狡噛慎也|刑事課一係|執行官|28|282|

の1行を削除し、

|ID|名前|所属 |職種|年齢|犯罪係数|
|:--|:--|:--|:--|:--|:--|
|1013|征陸智己|刑事課一係|執行官|54|127|

を挿入してみます。まずは、削除から、

```
mysql> delete from `users` where ID = 1012;
```
続いて挿入します。

```
mysql> insert into users (ID, Name, Affiliation, Job_category, Age, Criminal_coefficient) values (1013, "MASAOKA TOMOMI", "Criminal Affairs Section 1", "Enforcer", 54, 127);
```

テーブルを表示してみます。

```
mysql> select * from `users`;
+------+-----------------+----------------------------+--------------+------+----------------------+
| ID   | Name            | Affiliation                | Job_category | Age  | Criminal_coefficient |
+------+-----------------+----------------------------+--------------+------+----------------------+
| 1001 | AKANE TUNEMORI  | Criminal Affairs Section 1 | Watchman     |   20 |                   36 |
| 1011 | GINOZA NOBUTIKA | Criminal Affairs Section 1 | Watchman     |   27 |                   60 |
| 2011 | AOYANAGI RISA   | Criminal Affairs Section 2 | Watchman     |   28 |                   53 |
| 2021 | SUGOO TEPPEI    | Criminal Affairs Section 2 | Enforcer     |   22 |                  123 |
| 9001 | KARANOMORI SION | Integrated analysis room   | Analyst      |   27 |                  144 |
| 1013 | MASAOKA TOMOMI  | Criminal Affairs Section 1 | Enforcer     |   54 |                  127 |
+------+-----------------+----------------------------+--------------+------+----------------------+
```

ID1012の行が削除され、ID1013の行が追加されていることが分かります。行の**挿入**、**削除**にくわえて、行の**更新**の3つについてSQL文をまとめておきます。

####行の挿入
```
INSERT INTO [表名] ([列名], …)
VALUES ([値], …);
```

####行の削除
```
DELETE FROM [表名]
WHERE [条件];
```

####行の更新
```
DELETE FROM [表名]
WHERE [条件];
```

###ORDER BY, GROUP BY


今、テーブルは次のようになっています。

|ID|名前|所属 |職種|年齢|犯罪係数|
|:--|:--|:--|:--|:--|:--|
|1001|常守朱|刑事課一係|監視官|20|36|
|1011|宜野座伸元|刑事課一係|監視官|27|60|
|2011|青柳璃彩|刑事課二係|監視官|28|53|
|2021|須郷徹平|刑事課二係|執行官|22|123|
|9001|唐之杜志恩|総合分析室|分析官|27|144|
|1013|征陸智己|刑事課一係|執行官|54|127|

この状態ではIDの並びが不自然なので、IDが昇順になるよう**並び替え**てみます。

```
mysql> select * from users order by ID;
+------+-----------------+----------------------------+--------------+------+----------------------+
| ID   | Name            | Affiliation                | Job_category | Age  | Criminal_coefficient |
+------+-----------------+----------------------------+--------------+------+----------------------+
| 1001 | AKANE TUNEMORI  | Criminal Affairs Section 1 | Watchman     |   20 |                   36 |
| 1011 | GINOZA NOBUTIKA | Criminal Affairs Section 1 | Watchman     |   27 |                   60 |
| 1013 | MASAOKA TOMOMI  | Criminal Affairs Section 1 | Enforcer     |   54 |                  127 |
| 2011 | AOYANAGI RISA   | Criminal Affairs Section 2 | Watchman     |   28 |                   53 |
| 2021 | SUGOO TEPPEI    | Criminal Affairs Section 2 | Enforcer     |   22 |                  123 |
| 9001 | KARANOMORI SION | Integrated analysis room   | Analyst      |   27 |                  144 |
+------+-----------------+----------------------------+--------------+------+----------------------+
```

IDが昇順になりました。次は、**職種ごと**の**犯罪係数を合計**したものを表示してみます。「どの列名でグループ化するか」を**group by**で指定し、「合計を求める」のに**sum**を使います。ここで、分析官(Analyst)は一人しかいないので除いておきます。分析官はIDが9000番台なので、「IDが3000より小さい」という条件を付加してやります。このように条件を付けるときには**where**句を用います。

```
mysql> select sum(Criminal_coefficient), Job_category from users where ID < 3000 group by Job_category;
+---------------------------+--------------+
| sum(Criminal_coefficient) | Job_category |
+---------------------------+--------------+
|                       250 | Enforcer     |
|                       149 | Watchman     |
+---------------------------+--------------+
```

執行官の犯罪係数の合計が250、監視官の合計が149というデータが得られました。



#ビッグデータ
##ビッグデータとNoSQL
ビッグデータはただ単純に**大容量のデータ**というだけではなく、**多様で複雑なデータ構造を持つデータ**というのが重要です。

インターネット上のデータ量は膨大で、そのデータには欠損値が含まれることが常であり、さらには、データ構造もバラバラなので、これまでのようにきっちりデータ構造を設計して用いるRDBMSでは扱いにくいということになります。そこで、登場したのが、**NoSQL**です。これは、**「Not only SQL」**の略で、**「扱うデータによってはSQL(RDBMS)を用いるよりも、他のデータベースを使った方が良いかもしれない」**というような解釈になります。

##NoSQLの利点
NoSQLの利点は以下のようなものがあります。

- 欠損値を含むデータを扱いやすい
- データ構造を柔軟に変更できる
- 分散してデータを処理できる

##NoSQLの種類

NoSQLにも様々な種類のものがありますが、主なものを挙げると次のようになります。

<dl>
  <dt>列指向型データベース</dt>
  <dd>膨大なデータを効率よく管理することを追求したデータベース</dd>
</dl>

<dl>
  <dt>キーバリュー型データベース</dt>
  <dd>データ構造を簡単にすることにより、高速性に特化したデータベース</dd>
</dl>

<dl>
  <dt>ドキュメント指向型データベース</dt>
  <dd>XMLやJSONなどのドキュメントを単位としてデータを管理するデータベース</dd>
</dl>