100日後にエンジニアになるキミ - 36日目 - データベース - データベースについて

昨日まではプログラム言語についてを学びました。

本日はデータベースについてです。

## データベースとは

データベースとは何でしょうか?
ざっくり言うと、データを効率良く貯める仕組みです。

データの検索や蓄積が容易にできるように
整理する事ができるソフトウェアの事を主に指します。

プログラミングで取り扱われるデータベースは主に２つです。

・リレーショナルデータベース(RDB)
・NoSQL


## リレーショナルデータベース(RDB)について

一般的に一番良く用いられているデータベースは
このリレーショナルデータベース(RDB)かと思います。

**リレーショナルデータベースの特徴**

データは表構造で管理され
`テーブル(表)`と言う単位でデータを保存します。

relational databaseと綴り、その名の通り
relational(関係)と言う概念でモデル化され
表同士が交わり複雑な計算を行う事が出来ます。

テーブルは`カラム(列)`と`ロウ(行)`があり
`ロウ(行)`のことを`レコード`とも言っています。

テーブル単位で色々な`制約`を付け加える事ができ
`カラム(列)`には名前とデータ型、カラム制約などを
付け加える事ができます。

またリレーショナルデータベースは`SQL`と呼ばれる
データベース用の言語を用いて様々な操作をする事ができます。

**RDBの用途**

表構造なので管理しやすく、ECサイトなど会員制のサイトのデータ管理
スマートフォン向けアプリ内のデータ管理などに向いています。

**主な製品**

`Oracle Database(Oracle)`
`SQLServer(Microsoft)`
`MySQL(Oracle)`
`PostgreSQL`
`SQLite`

などがあり、有償、無償様々な形で提供されています。

**データの完全性**

データの完全性とは、データの完結性、正確性、一貫性などを意味します。

リレーショナルデータベースでは、一連の`制約`を使用する事で完全性が保たれます。

`制約`は`プライマリキー`、`外部キー`、`Not NULL制約`、`Unique制約`
`Default制約`、`Check制約`などが含まれます。

**トランザクション**

トランザクションは日本語だと`処理`と言う意味合いです。
トランザクションは`目的をもつ業務処理のひとまとまり`のことを指します。

いくつかの作業を一連の作業単位として形成し
データベースの操作を行う事でデータの一貫性を保ちます。

トランザクション中では`コミット`,`ロールバック`など
一連の処理の結果によって最終的なデータベースの操作結果が変わってきます。

**ACID特性**

データベースではトランザクションを適切に処理する必要があります。
そのためにトランザクションは特性に基づいて処理されます。
主に4つの特性があります。

|スペル|特性|意味|
|:--:|:--:|:--:|
|A|atomicity|原子性|
|C|consistency|一貫性|
|I|isolation|独立性|
|D|durability|永続性|

それぞれがどう言うものかと言うと

***atomicity(原子性)***

トランザクションの途中で処理が止まったりしないこと
トランザクション内の操作が全て実行されるか or されないかを保証します。

たとえ話で良く銀行の例が出てきますが
預金と出金が同時に行われたらどうなるか？

預金だけ、出金だけ、と言う結果になると最終的な
預金額がおかしなことになってしまいますよね。
それを保証するのがトランザクションの原子性の部分です。

処理は`COMMIT`ですべて実行
`ROLLBACK`ですべて実行しない（巻き戻し）となります。


***consistency(一貫性)***

これは整合性とも言いますが、DB内のデータに矛盾のない事を常に保証します。
口座に120円しか入っていないのに10000円のものを買おうとするとか
そう言った矛盾を起こさないようにする仕組みです。

***isolation(独立性)***

トランザクション中に行われる操作は
他のトランザクションに影響を与えない事を保証します。

処理は時間がかかるので、その処理中に他の処理が割り込んだ際に
他の処理に影響を与える処理をしてしまうのは好ましくありません。

そのため処理中にイジっているデータを他の処理からは
見えなくするなどの排他制御の機能が備わっています。

`トランザクション分離レベル`という概念を
ANCIが定義しているものがあります。

| 分離レベル | ダーティーリード | ファジーリード | ファントムリード | ロストアップデート | 処理速度 |
|:--|:--|:--|:--|:--|:--|
| read uncommitted | 発生 | 発生 | 発生 | 発生 | 速い |
| read committed | 起きない | 発生 | 発生 | 発生 | ↓ |
| repeatable read | 起きない | 起きない | 発生 | 発生 | ↓ |
| serializable | 起きない | 起きない | 起きない | 起きない | 遅い |

ここら辺はデータベースの製品により異なってくるので
システムの要件に合うデータベースの選定をする際に
重要になってくるポイントです。



***durability(永続性)***

トランザクション処理結果は永続的であることを保証します。

トランザクションが完了したら、その結果は記録され
システム障害などが生じても失われることがないという性質です。

データ操作の時系列の`記録（ログ）`をストレージなどに保存しておき
データ記録中に障害などで中断したら記録を元に
更新を反映させるといった処理を行う事ができます。

## SQLについて

SQLはリレーショナルデータベースを操作するための言語になりますが
SQLそのものはプログラム言語ではありません。

ただしプログラム内ではSQLを作成して
データベースにアクセスするのに利用されます。

SQLには沢山の亜種も存在しますが、一応標準規格があるようで
ここで主に取り扱うのは`標準SQL`の話になります。

SQLは操作用の`文`を書いてコマンドラインなどで実行することにより
データベースの様々な操作を執り行う事が出来るようになっています。

SQLの文法の種別は主に3つの系統に別れています。
`DDL`データ定義言語 (data definition language)
`DML`データ操作言語 (data manipulation language)
`DCL`データ制御言語 (data control language)

**データ定義言語(DDL)**

データベースそのものを定義するために最初に行うもので
主に下記のような`文`があります。
`CREATE` データベースオブジェクト（表、インデックス、制約など）の定義
`DROP` データベースオブジェクトの削除
`ALTER` データベースオブジェクトの定義変更

**データ操作言語(DML)**

おそらく一番用いられる文法はDMLで
主に下記のような`文`があります。

`INSERT`行データもしくは表データの挿入
`UPDATE`表を更新
`DELETE`表から特定行の削除
`SELECT`表データの検索、結果集合の取り出し

**データ制御言語(DCL)**

データベースの利用に様々な制限をつけるための文法で
主に下記のような`文`があります。

`GRANT`特定のデータベース利用者に特定の作業を行う権限を与える
`REVOKE`特定のデータベース利用者からすでに与えた権限を剥奪する
`SET TRANSACTION`トランザクションモードの設定
`BEGIN`トランザクションの開始
`COMMIT`トランザクションの確定
`ROLLBACK`トランザクションの取り消し
`SAVEPOINT`任意にロールバック地点を設定する
`LOCK`表などの資源を占有する

## NoSQLについて

NoSQLはその名の通り`SQL`を用いる事ができません。

NoSQLとは、リレーショナルデータベース以外のデータベースを指し
リレーショナルデータベースが苦手な分野で数多く使われるようになっています。

**NoSQLの特徴**

主な特徴としては
・容易にスケールアウトできる
・結果整合性の保証
・トランザクション処理に不向き
などが挙げられます。

NoSQLをデータモデルで分類すると
`キーバリュー型`,`カラム型`,`ドキュメント型`に分類できます。

***キーバリュー型***
・キーとバリューを関連付けて、データを保管する
・データを高速で読み書きすることは可能だが、複雑な処理には適していない

***カラム型***
・カラム単位でデータを保管する
・大規模なデータの読み込みなどはRDMSよりも高速で処理できるので
データウェアハウスとして用いられることが多い

***ドキュメント型***
・JSONやXMLなどの構造を持ったドキュメントを保管する
・構造が複雑なデータを格納するのに適している


**NoSQLの用途**

大規模なデータ処理を行うシステムに適しています。

**主な製品**

`memchaed`
`Redis`

上記は`KVS（Key-Value Store）`とも呼ばれ
KeyとValueを組み合わせる単純な構造からなるデータストアです。

KVSはKeyとValueの関係だけのデータベースなので
複数のサーバーにデータを分散させて格納する
分散データストアとしての利用が増えています。

分散データストアは負荷の分散や高可用性を低コストで実現できるために
大規模なデータを扱うWEBアプリケーションなどで利用されます。

## データベース関連用語について

**データウェアハウス(DWH)**

データの貯蔵と分析を主目的としたデータ保存場所と言う意味合いです。
データ分析システムのデータ貯蔵庫として使われる事が多いです。

**データセット**

データをまとめたものと言う意味合いになります。
データベースの中では`テーブルをまとめたもの`と言う意味で使われているものもあります。


**ストレージ**

一般的には`記憶媒体`のことを指します。
データベースでが`データを貯める場所`のことになりますが
最近ではクラウド上のストレージサービスもこの意味合いになります。

**スキーマ**

データベースの構造の定義のことです。
リレーショナルデータベースでは表と列単位での定義となります。

**クエリ**

`クエリ(query)`はデータベースに対する問い合わせのことです。
SQL文の実行などがこれに当たります。
Google検索なども Googleのデータベースに対する問い合わせのため
検索クエリなどと呼ばれます。

**主キー（primary key）**

`主キー（primary key）`はリレーショナルデータベースでは
列単位で一意に識別するための仕組みです。
主キー設定された列は、同じ値を2行以上持つ事ができなくなります。

`KVS（Key-Value Store）`はキー単位で操作を行うので同じキーが2つは存在しません。

**インデックス**

データベースにおいてテーブルなどに格納されたデータをすばやく検索・抽出するための
識別データ・索引データなどのことを`インデックス`といいます。

`インデックス`は、SQL文を実行する際のパフォーマンスに大きな影響を及ぼします。
それぞれのSQL文に対して必要なパフォーマンス要件を満たすように
`インデックス`を定義する必要があります。

日付などでインデックスを構築する事が多いです。

## まとめ

データベースの概念や種類用語などを押さえておこう。


君がエンジニアになるまであと64日

## 作者の情報
乙pyのHP：
http://www.otupy.net/

Youtube：
https://www.youtube.com/channel/UCaT7xpeq8n1G_HcJKKSOXMw

Twitter：
https://twitter.com/otupython