データストアの選択基準　（いろんなデータストアを触ってみる前に...)

この記事は、[色んなデータストア触ってみる Advent Calendar 2019](https://qiita.com/advent-calendar/2019/datastores)のための記事となります。
__本情報の内容（添付文書、リンク先などを含む）は、作成日時点でのものであり、予告なく変更される場合があります。__
一般的なミドルウェア製品例を含めての記載を心がけていますが、不勉強な部分もたくさんございますので網羅性を問うドキュメントではございませんのでご承知おきください。

# はじめに
データストアを選択する際はその用途を踏まえた要件から選択することになります。しかしながら本来の目的とは逆にミドルウェアの製品やサービスありきで選択されるケースも散見されます。製品やサービスを決め打ちでデータストアを選択すると、そもそもの用途に最適なのは別のテクノロジーであった場合に大幅な手戻りが発生するということもあります。
この記事では、一度基本に立ち返り要件や特性を踏まえてデータストアを選択するためにはどのような内容を考慮すべきかということに特化しています。
読み物記事ですので、Advent Calendarの本来の趣旨とズレてしまっていたらすみません。


# 要件の精査をしよう
## データストアの選択にかかわる要件
データストアを必要とするシステムの要件は主に、機能要件と非機能要件にわけられます。具体的にはそれぞれ、下記のものが挙げられます。用途から機能要件を落とし込むためには、その用途にふさわしいデータがどのようなものなのかというところからアプローチします。

| 機能要件 | 具体的な例 |
|:-:|:--|
|データ形式|どのような種類のデータを格納するのか。構造化データなのか、非構造化データなのか。|
|データサイズ|どれくらいのデータのサイズなのか。1レコードあたりと全体での容量。|
|スケールと構造|どのようにスケールするのか。スケールする場合、書き込みと読み取りのワークロードはどこからどのような種類で発生するのか。|
|整合性モデル|データの整合性モデルをどうするのか。データの特性によって、厳密な整合性モデルが必要な場合とそうでない場合がある。|
|データの可搬性|データがどこからきて、ETL/ELTの処理をどこで行うのか。|
|データライフサイクル|データ自身のライフサイクル。全期間のデータを単一のデータストアに保管するのか、アーカイブしていくのか。|

機能要件はデータストアを選択するうえで最も優先順位が高い項目です。システムの特性やデータの特性を踏まえてそれぞれデザインしていくものとなります。

|非機能要件|具体的な例|
|:-:|:--|
|パフォーマンスとスケーラビリティ|どれくらいのパフォーマンス性能が必要とされるのか。リージョンを跨ぐようなスケーラビリティが必要なのかどうか。スケールアップ、アウト、どちらが多いのか。|
|信頼性|データストアの信頼性。可用性。バックアップ/リストア要件。|
|運用管理性|マネージドサービスを使用するかどうか。保守性。OSSは無償ではないので、保守性をどう考慮するか。|
|コスト|イニシャルコスト。ランニングコスト。OSSベースで自分で環境構築する場合はその工数や保守性を含めて。|
|セキュリティ|ユーザーとアクセス・管理権限。暗号化要件。データのマスキングやユーザー制御。攻撃を受けた場合の検出など。|

非機能要件は機能要件ほどではありませんが、最終的にどのデータストアを選択するかの判断材料となる項目です。

## データ形式ごとの選択基準
データ形式には様々なものがあります。下記の表にデータ形式ごとの特性や用途、ミドルウェア・製品・サービス例について簡単にまとめました。なお、筆者のテクノロジーバックグラウンドによって OSS のプロジェクトの場合はプロジェクト名を。クラウドサービスの場合は Microsoft Azure のものを主に紹介しています。

|データ形式|特性|用途|ミドルウェア・製品・サービス例|
|:-:|:--|:--|:--|
|リレーショナルデータベース管理システム|ACID (原子性、一貫性、独立性、永続性) 特性に基づく、トランザクションの一貫性がある。|ERPパッケージなど|SQL Server (SQL Server 及び Azure SQL Database ファミリ）Oracle Database, DB2, MySQL, PostgreSQL, MariaDB （Azure Database for シリーズ）など|
|キー/値のストア|データ値を一意のキーに関連付けて分散格納する。CAP定理により__一貫性(Consistency),可用性(Availability),分断耐性(Partition-tolerance)__を同時にすべて備えることができないことが多い。|Web キャッシュデータ|[Memcached](https://memcached.org/), Redis ([Azure Cache for Redis](https://azure.microsoft.com/services/cache/)), [Azure Cosmos DB](https://azure.microsoft.com/services/cosmos-db/) |
|ドキュメント データベース|キー/値のデータストアと基本的に特性は似ているが、値が XML、YAML、JSON、BSON などのドキュメントとなる。|IoTのログデータ、カタログデータ|MongoDB, [Azure Cosmos DB](https://azure.microsoft.com/services/cosmos-db/) |
|グラフ データベース|関係性を表すデータを表現するのにつかわれています。Node-Edgeの関係で表現します。|人物相関図。路線図と所要時間など。|Gremlin, Neo4j, [Azure Cosmos DB](https://azure.microsoft.com/services/cosmos-db/), SQL Server (2017, 2019)|
|列ファミリのデータベース|リレーショナルデータベースやドキュメントデータベースによく似た行と列の組み合わせ。キーで分散せず順番に格納されることが多い。列のデータ構成の変更が容易。|Facebookのメッセージングサービスなど|HBase ([HD Insight](https://docs.microsoft.com/ja-jp/azure/hdinsight/hdinsight-hbase-overview)), [Azure Table Storage](https://docs.microsoft.com/ja-jp/azure/cosmos-db/table-storage-overview) |
|データ分析|データの取り込み、保存、および分析のための大規模な並列処理が可能。|データ分析（データレイク）|HDFS, [Azure Synapse Analytics](https://azure.microsoft.com/services/sql-data-warehouse/), [Azure Data Lake](https://azure.microsoft.com/solutions/data-lake/), [Azure Data Explorer](https://azure.microsoft.com/services/data-explorer/)|
|検索エンジンのデータベース|外部データ ストアおよびサービスで保持されている情報のインデックス情報を格納。|検索システム。ファイルサーバ。|[Azure Search](https://azure.microsoft.com/services/search/), Elasticsearch|
|オブジェクト ストレージ|大規模な非構造化データのバイナリ(例えば、イメージ、ビデオ、オーディオ ストリーム、仮想マシンイメージ) の格納に向いています。|コンテンツ配信システムなど|[Blob Storage](https://azure.microsoft.com/services/storage/blobs/)|
|時系列データベース|多数のソースからリアルタイムで大量のデータを収集するため、きわめて大量の書き込みに対応。更新はほとんど行われない。|IoTのセンサーデータ。パフォーマンスデータなど|[Time Series Insights](https://azure.microsoft.com/services/time-series-insights/)|
|共有ファイル|上記の特性と異なりフラットなファイルを複数のクライアントからアクセスするのが最適な場合。|部門間でやり取りするリストなど|Microsoft Excel、Microsoft Accessなど|

# まとめ
用途に応じてデータ形式をはじめとした様々な要件が決まり、それに合わせた形でデータストアを選択することになります。特定の製品やサービスありきではなく、用途や要件、アーキテクチャを踏まえた選択をおこなうことで少しでも楽にシステムを実装するとよいでしょう。

最後に、ご紹介している参考資料の一部（[アーキテクチャセンターのドキュメント](https://aka.ms/mspnp)）は実事例に基づいたリファレンスアーキテクチャ（みんな大好きな__事例構成__ってやつです。利用している企業や団体を特定できる情報が省かれている形で少しだけ標準化されています。）を多く含むとても参考になる資料です。また、一般的な内容も多く含まれています。この記事をきっかけに、公式ドキュメントもお時間のある時にご一読いただけると幸いです。

# 参考資料
- [データ ストアの選択条件](https://docs.microsoft.com/ja-jp/azure/architecture/guide/technology-choices/data-store-comparison)
- [適切なデータ ストアの選択](https://docs.microsoft.com/ja-jp/azure/architecture/guide/technology-choices/data-store-overview)
- [CAP定理を見直す。“CAPの3つから2つを選ぶ”という説明はミスリーディングだった](https://www.publickey1.jp/blog/13/capcap32.html)
- [SQL Server](https://docs.microsoft.com/ja-jp/sql/sql-server/?view=sql-server-ver15)
- [Azure SQL で適切なデプロイ オプションを選択する](https://docs.microsoft.com/ja-jp/azure/sql-database/sql-database-paas-vs-sql-server-iaas)
- [Azure Database for PostgreSQL のドキュメント](https://docs.microsoft.com/ja-jp/azure/postgresql/)
- [Azure Database for MySQL のドキュメント](https://docs.microsoft.com/ja-jp/azure/mysql/)
- [Azure Database for MariaDB のドキュメント](https://docs.microsoft.com/ja-jp/azure/mariadb/)
- [Memcached](https://memcached.org/)
- [Azure Cosmos DB](https://azure.microsoft.com/services/cosmos-db/)
- [Azure Cosmos DB の Cassandra API の概要](https://docs.microsoft.com/ja-jp/azure/cosmos-db/cassandra-introduction)
- [Azure Cache for Redis](https://azure.microsoft.com/services/cache/)
- [Azure Cosmos DB の概要: Gremlin API](https://docs.microsoft.com/ja-jp/azure/cosmos-db/graph-introduction)
- [Azure Cosmos DB の MongoDB 用 API](https://docs.microsoft.com/ja-jp/azure/cosmos-db/mongodb-introduction)
- [Azure Cosmos DB の概要:テーブル API](https://docs.microsoft.com/ja-jp/azure/cosmos-db/table-introduction)
- [Azure Synapse Analytics](https://azure.microsoft.com/services/sql-data-warehouse/)
- [HD Insight](https://docs.microsoft.com/ja-jp/azure/hdinsight/hdinsight-hbase-overview)
- [Azure Table Storage](https://docs.microsoft.com/ja-jp/azure/cosmos-db/table-storage-overview) 
- [Azure Search](https://azure.microsoft.com/services/search/)
- [Time Series Insights](https://azure.microsoft.com/services/time-series-insights/)
- [Blob Storage](https://azure.microsoft.com/services/storage/blobs/)