NoSQLについてちゃんと学ぶ

# はじめに　
先日よく使うDocker構成について記載したこちらの記事を公開しました。
[最近よく使っているDocker構成の備忘録 (NodeJS+Redis+MySQL)](https://qiita.com/riku-shiru/items/c84113cad87b3bc5ddd9)


様々な用途で、NoSQLの利用シーンがあるかと思いますが、NoSQLと分類されるものって非常に多くありますよね。
その中で上記の記事の中ではRedisをキャッシュ機構目的で利用していましたが、NoSQLの製品からどれを選択するかで悩んだ時に具体的な違いを意識したことがないと思ったので、メモの目的でこの記事を記載しています。


# NoSQLとは
NoSQLはRDBMS以外のデータベース管理システムを指すおおまかな分類語で、Not Only SQLの略です。
主な製品としては、
Redis、MongoDB、DynamoDB、Neo4j、Memcached
などがあります。

# NoSQLが必要とされた背景
NoSQLはRDBMSの弱みを補う事ができるソリューションとして用いられる事がほとんどなので、まずはRDBMSの強み弱みを整理したいと思います。

## RDBMSの強み
NoSQLが必要とされた背景の前にRDBMSについて整理したいと思います。
RDBMSの強みとしては以下のようなものがあげられるかと思います。

* データの一貫性 （トランザクション）
* 更新時のコストが少ない
* SQLによる複雑な条件での検索や集計

RDBMSを利用することの最大のメリットはデータの一貫性が保証されているということだと思います。
データの一貫性が厳しく求められるようなケースにはRDBMSを利用することがよいとおもいます。
また、RDBMSを利用する場合にはJOINすることを前提としてテーブルが正規化されているので、データの更新時にかかるコストは非常に少なくなることも強みと言えるでしょう。

## RDBMSの弱み
RDBMSの弱みは以下のようなものがあるかと思います。

* スケーラビリティ
* インデックス作成コスト

弱みの一つとしてスケーラビリティと記載しましたが、
RDBMSの場合、データの読み込み部分についてはマスタースレーブ構成にしてレプリケーションすることができるので、スレーブを増やすことで比較的簡単にスケールさせることが可能です。

しかしながら、書き込み部分をスケールさせるのは難しいです。
互いにレプリケーションし合うデュアルマスタ構成をもちいる方法も考えられますが、正しく制御できない場合、更新処理が競合する可能性があるため、導入が難しいかと思います。
特にテーブル毎にクエリの発行先を振り分けるなどの対応が必要になるため、導入するのが簡単だとは言い難いです。

他の方法としては、そもそもDB分割してサーバを分けるという選択肢も考えられます。
サーバを分けることで、ディスクIOを減らす事ができるのでインメモリで高速に処理するためにもデータサイズが減らせるDB分割は効果的です。
比較的解決策として良さそうに感じるかもしれませんが、複数台のサーバに分割する場合には他のサーバのテーブルとはJOINができないので、それを考慮してDB分割する必要があるので、正しい設計が必要になります。

また、RDBMSの場合はインデックス戦略が検索速度向上の目的で用いられるかと思います。
しかしながら、データ量が多いとインデックスの追加によってテーブルが長時間ロックされてしまう点も注意をしなければなりません。


## NoSQLが必要になった理由
RDBMSのメリット・デメリットを整理したところで、なぜNoSQLが必要になったかを記載していきます。
NoSQLが必要となった背景の一つとして、取り扱われるビッグデータの特性が重要になります。

### ビッグデータの特性
ビッグデータを取り扱うに到り５つの必要な特性があります。
それは以下の５つと言われています。

* 量  (Volume)
    * 多様かつ大量なデータを扱う必要性
* 速度 (Velocity)
    * データへのリアルタイムアクセス
    * データの意味合いの変化速度
* 多様性 (Variety)
    * 構造化データや非構造化データなどの多種多様なデータの多様性
* 正確さ (Veracity)
    * データの正確さや一貫性に関する要件
* 変動性 (Variability)
    * コンテキストによってデータの意味が変動する

つまりデータとは「大きく」「速く」「複雑」で、「変化する」ものであることがわかります。
上記五つの特性を意識した時にビッグデータを扱う上では、RDBMSだとうまく行かない理由があります。

#### 「量」と「速度」に対するRDBMSのデメリット
データ量の増加と処理速度の増加が課題となった時に、RDBMSでは「スケーラビリティ」の観点で非常に不得手になってしまいます。
といいますのも、RDBは原則として1台のサーバで実行するように設計されているからです。
RDBMS自体のスケールアップする必要がある場合には、より巨大・複雑で高価なハードウェアを購入しなくてはならないといった事態も起こり得ます。
また、スケールアウトを行うを行う場合には前述したようにRDBMSでは非常に高コストになってしまうため、向いていません。

#### 「多様性」に対するRDBMSのデメリット
非構造化データを扱うことをRDBはあまり得意としていません。
というのもRDBには以下の特性があるからです。

* 格納前に構造定義をする必要がある。
* データソースの構造が変更された場合、スキーマを変更する必要がある。
* 非構造データでは事前に構造を把握することは難しくスキーマ定義ができない。

これらの理由から非構造データを扱かうことに対してはRDBMSを選択することはあまり向いていません。

### NoSQLなら解決できる？
結論から述べるとこれらの課題を解決する事が可能です。
それはNoSQLが以下のような特性を持つからです。

* NoSQLは複数台のサーバ構成を利用した水平分散が得意。(Sharding)
* NoSQLは構造定義を必要とせずにデータを格納できる。

#### 水平分散
NoSQLはShardingにより複数のサーバにデータを分散化させています。
もともと水平分散をするように作られているため、非常に安価で構築が容易になります。
サーバを分散化させる事ができる最大のメリットはデータがメモリに乗りやすい事だと思います。
どうしても１台で賄う必要のあるRDBMSでは大量のデータを扱う場合にメモリから溢れてしまいますが、スケールアウトに富んだNoSQLであればある程度メモリ上に載せる事ができます。

ただ一貫性の観点からいうとRDBMSほど厳密には保証しません。
最終的に整合が合えば一時的に一貫性を損なってもよいという考え方になっています。

#### 構造定義が不必要
JSONやXMLのような自由度の高いドキュメントを、RDBのテーブルに変換することなくネイティブに扱う機能を持ちます。
データを取りあつかうカテゴリは大きく４つあり、それぞれの取り扱いは違うものの、構造定義が不必要という観点では同様です。

したがって、NoSQLは非構造データを取りあつかうことに長けているという事ができます

# NoSQLの種類
NoSQLには、大きく4つのカテゴリがあり、それは「ドキュメント」、「キー・バリュー」、「カラム指向」、「グラフ」に分類されます。

## ドキュメント型
###　主要製品
MongoDB, CouchDB
###　特徴
JSONやXMLなどのドキュメントを、そのまま格納することができるデータベースです。
RDBではスキーマ定義が複雑になりがちなJSONデータを、JSONの状態のまま格納できます。
読み取り・更新・削除をドキュメントの一部もしくは全体に対して行うことができます。

## キー・バリュー型
###　主要製品
Memcached, Redis,  DynamoDB

###　特徴
キーとバリューをペアにして格納する、シンプルなデータベースです。
作成や更新時には、キーとバリューのペアで作成し、キーを指定して読み取りや削除を行います。
バリューとして扱えデータには単一の値だけでなく、リストやセットなど複数の値を持つことができます。


## カラム指向型
###　主要製品
Cassandra, HBase

###　特徴
一般の行指向型DBと同様に表の構造を持ちつつ、カラム単位でデータを保持します。
RDBは行単位で処理を行いますが、逆にカラム指向型DBは列単位で処理を行います。
行を取り出すのではなく、列を取り出すといった動作をします。
行指向では苦手な列単位の大量集計、大量更新が得意なデータベースです。
列単位でまとまった処理があるシステムでは、RDBよりも高速に処理できるというメリットがあるため、
行単位で集計する処理が多い、情報分析システムなどで活用されています。

## グラフ型
###　主要製品
Neo4j

###　特徴
データをグラフ構造で格納するデータベースです。
ネットワーク状のデータを格納するのに適しています。
データ間のリレーションに重心を置いたデータベースといえるでしょう。

### sample
![1_ttbR95R4sALs5XqFACI4cw.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255007/aec382c3-69ac-96b9-374b-91c139fbc2bc.png)


# まとめ
NoSQLと言ってもいろいろな種類があり、DBごとに特性も異なることがわかります。
また、RDBと共存関係にあり、RDBを置き換えるものではありません。
取り扱うデータがどのようなものなのかを判別して、RDBMSを利用するのかNoSQLを利用するのかを選択し、
適材適所でしっかり使い分けができるようにしておきましょう。

## 参考文献
[NoSQLの必要性と主要プロダクトの比較](https://openstandia.jp/pdf/150611db_tech_showcase_tokyo_e22.pdf)
[NoSQLの時代：ドキュメントモデルの活用](https://cdn1.marklogic.com/wp-content/uploads/2018/01/jp-the-nosql-generation-140501.pdf)
[なぜ「NoSQLデータベース」なのか？](https://www.atmarkit.co.jp/ait/articles/1708/30/news009.html)