NoSQLとは ― キーバリュー型などの種類とRDBの違い
NoSQLは、
NoSQLとは、表で持つRDB以外のデータベースの総称
NoSQLとは、表の形でデータを持つRDB以外の、データベースの種類をまとめて指す呼び方です。キーバリュー型・ドキュメント型・列指向・グラフ型が代表で、型ごとにデータの持ち方と得意な読み方が違います。データが表に収まりにくいときや、台数を増やして大量に読み書きしたいときに、RDBの代わりに使ったり、RDBと組み合わせたりします。
AWSの解説は、NoSQLを、特定のデータの形に合わせて設計され、決まりのゆるい形でデータを持つデータベースと説明しています。データベースの基本は、データベースとはとRDBの記事で説明しています。
NoSQLの種類は4つの型で、何を1件として持つかが違う
型の違いは、データの何を1件として持つかに表れます。次の図は、会員2人と注文3件という同じデータを、RDBと4つの型で持った形を示しています。タブを切り替えて、1件の単位と得意な読み方を比べられます。
| 会員番号 | 名前 | 都市 |
|---|---|---|
| C001 | 佐藤 | 東京 |
| C002 | 鈴木 | 大阪 |
| 注文番号 | 会員番号 | 商品 | 数量 |
|---|---|---|---|
| 101 | C001 | ノート | 2 |
| 102 | C001 | ペン | 5 |
| 103 | C002 | ノート | 1 |
| キー | 値 |
|---|---|
| member:C001 | 佐藤,東京 |
| member:C002 | 鈴木,大阪 |
| orders:C001 | 101 ノート 2, 102 ペン 5 |
| orders:C002 | 103 ノート 1 |
{
"_id": "C001",
"name": "佐藤",
"city": "東京",
"orders": [
{ "no": 101, "item": "ノート", "qty": 2 },
{ "no": 102, "item": "ペン", "qty": 5 }
]
}
{
"_id": "C002",
"name": "鈴木",
"city": "大阪",
"orders": [
{ "no": 103, "item": "ノート", "qty": 1 }
]
}| 注文番号の | 101 | 102 | 103 |
|---|---|---|---|
| 会員番号の | C001 | C001 | C002 |
| 商品の | ノート | ペン | ノート |
| 数量の | 2 | 5 | 1 |
- 1件の
単位 - 表の
1行。 会員と 注文を 別の 表に 分け、 会員番号で 結び 付けます。 - 得意な
読み方 - どの
列を 条件に しても 探せます。 会員の 注文を まとめて 読む ときは、 2つの 表を 結合します。 - 向かない
読み方 - 列は
表を 作る ときに 決めます。 行ごとに 違う 項目を 持たせる ことは できません。
- 1件の
単位 - キーと
値の 組。 キーが、 その 1件を 見分ける 印です。 - 得意な
読み方 - キーが
分かっている 1件を、 すぐに 保存して 取り出せます。 例は orders:C001を 指定して、 佐藤さんの 注文を 読む 処理です。 - 向かない
読み方 - 基本の
操作は、 キーを 指定した 保存と 取り出しです。 「東京の 会員を 全員」のように、 値の 中身を 条件に した 検索には 向きません。
- 1件の
単位 - 会員1人分の
文書。 注文を、 文書の 中に 入れ子に して 持ちます。 - 得意な
読み方 - 会員1人と、
その 注文を 1回で 読めます。 文書ごとに 項目が 違ってもかまいません。 - 向かない
読み方 - 何を
1件に まとめるかは、 よく 使う 読み方に 合わせて 決めます。 会員を またいで 商品ごとに 集計する 読み方は、 この 持ち方の 得意な 形ではありません。
- 1件の
単位 - 表の
形は 同じで、 保存を 列ごとに まとめます。 数量の 列なら、 2・5・1が 並んで 置かれます。 - 得意な
読み方 - 「数量の
合計」のように、 たくさんの 行から 少しの 列だけを 読む 集計が 速くなります。 - 向かない
読み方 - 1件の
注文の 全項目を 読み書きする 処理は、 行ごとに 保存する 方式の ほうが 向きます。
- 1件の
単位 - 人や
商品を ノード、 「買った」を ノードどうしの つながりと して 持ちます。 - 得意な
読み方 - つながりを
たどる 問い合わせが 得意です。 鈴木さんから ノート、 ノートから 佐藤さん、 佐藤さんから ペンと たどると、 鈴木さんに 薦める 商品が 見つかります。 - 向かない
読み方 - 数量の
合計を 出すだけの 集計のように、 つながりを たどらない 処理では、 グラフの 形で 持つ利点が 生きません。
同じデータでも、RDBは表を分けて持ち、ドキュメント型は会員1人分を1つにまとめます。どちらが良いかは、そのデータをどう読むことが多いかで決まります。
| 型 | 1件の | 製品の |
|---|---|---|
| キー | キーと値の組 | Redis、Amazon DynamoDB |
| ドキュメント型 | JSONに似た文書1つ | MongoDB、Amazon DynamoDB |
| 列指向・ | 列ごとにまとめた値、キーで分けた行 | Apache Cassandra |
| グラフ型 | ノードと、ノードどうしのつながり | Neo4j |
Amazon DynamoDBは、キーバリュー型とドキュメント型の両方の使い方ができるサービスです。DynamoDBの仕組みはAmazon DynamoDBの記事で説明しています。
キーバリュー型・ドキュメント型・列指向・グラフ型の仕組み
キーバリュー型は、キーで値を出し入れする
キーバリュー型は、キーと値の組を集めてデータを持ちます。キーはその1件を見分ける印で、基本の操作はキーを指定した保存と取り出しです。作りが単純なため、キーが分かっている1件をすぐに読み書きできます。
代表的な製品のRedisは、データをメモリに置くデータベースです。Redisの公式資料は、メモリに置くので読み書きがとても速い一方、データ量はメモリの大きさを超えられないと説明しています。メモリの中身は、一定の間隔でディスクに保存することもできます。データを主にメモリに置くこの方式を、インメモリデータベースと呼びます。AWSでは、Amazon ElastiCacheが、キーと値の組をメモリに置いてデータベースのキャッシュに使うサービスです。
ドキュメント型は、JSONに似た文書を1件として持つ
ドキュメント型は、項目名と値の組を並べた文書を1件として持ちます。代表的な製品のMongoDBは、JSONを2進数の形にしたBSONで文書を保存します。値には、別の文書や配列も入れられます。
MongoDBの公式資料は、同じ集まりの文書でも、項目がそろっている必要はないとしています。設計の原則は、一緒に読むデータを一緒に保存することです。会員の中に注文を入れておけば、会員1人と注文を1回で読めます。MongoDBにも、別の集まりと結び付ける$lookupという操作はあります。
列指向は列ごとにまとめ、ワイドカラム型はキーで行を分ける
列指向は、同じ列の値をまとめて保存する方式です。この方式は、SQLで問い合わせるデータウェアハウスのAmazon Redshiftでも使われています。Redshiftの資料によると、分析の問い合わせは多くの行から少しの列だけを読むため、読む量が大きく減ります。たとえば100列の表で5列だけを使う問い合わせなら、読むのは表のデータの約5%で済みます。1件の全項目を読み書きする業務の処理は、行ごとに保存する方式が向きます。
列指向と並べて扱われるのが、Apache Cassandraに代表されるワイドカラム型です。Cassandraは行と列からなる表でデータを持ち、パーティションキーという値で、行を置く台を決めます。結合はできないため、問い合わせごとに表を作り、同じデータを複数の表に重ねて持ちます。列ごとに保存する列指向とは、仕組みが別のものです。
グラフ型は、つながりそのものをデータとして持つ
グラフ型は、データをノードとリレーションシップで持ちます。ノードは人や商品などの1つの物で、リレーションシップは2つのノードをつなぐ、向きと名前を持った線です。ノードとリレーションシップには、プロパティと呼ぶキーと値の組を付けられます。
代表的な製品のNeo4jの資料は、グラフデータベースは結合を使わないと説明しています。つながりがノードと一緒に保存されているため、線をたどれば次のノードにたどり着きます。「友達の友達」のように、何段もつながりをたどる問い合わせに向きます。
NoSQLとRDBの違いは、項目の決め方・結合・台数の増やし方
RDBとNoSQLの違いは、データを持つ前にどこまで形を決めるかと、規模をどう広げるかに表れます。次の表は、AWSの解説をもとに、RDBと多くのNoSQLの製品の違いをまとめたものです。
| 比べる | RDB | NoSQL |
|---|---|---|
| 項目の | 表・列・ | 決まりが |
| 結合 | 表を | 一緒に |
| 台数の | 1台の | 台数を |
| 一貫性 | ACID特性を | ACID特性の |
RDBは、表・列・表どうしの関係を先に決めておくので、どの列を条件にしても正しく探せます。NoSQLは、よく使う読み方に合わせて1件の形を決めます。その読み方には速く答えられますが、想定していない読み方には弱くなります。
規模の広げ方も違います。RDBは1台のサーバの性能を上げて対応するのが基本で、NoSQLの多くは台数を増やしてデータを分けて持ちます。1台を強くするか台数を増やすかの違いは、スケールアップとスケールアウトの記事で比べています。RDBでも、AWSのAmazon Auroraは、書き込む1台と同じストレージを読む読み取り用の台を、最大15台まで足せます。
台数を増やせるのは、キーから置き場所が決まるからです。Cassandraは、パーティションキーの値をもとに、どのノードにデータを置くかを決めます。要求はキーから決まったノードに向かうので、ノードを足せば、データと処理を分けて持てます。図では省きましたが、Cassandraは同じデータの写しを複数のノードに持つこともできます。データを複数の台に分けたり写したりする考え方は、分散データベースの記事にまとめました。
ACIDとBASEは、一貫性と使える状態のどちらを優先するか
RDBのトランザクションは、ACID特性を保証します。ACIDの4つの性質はトランザクションとACID特性の記事で説明しています。AWSの解説によると、多くのNoSQLは、このACID特性の一部をゆるめています。その代わりに、決まりのゆるいデータの形と、台数を増やして広げやすい作りを選んでいます。
ACIDと対比される考え方がBASEです。BASEは、Basically Available、Soft-state、Eventual consistencyの頭文字です。Eric Brewerが2000年の講演で、ACIDと並べて示しました。
講演のスライドによると、BASEは一貫性を弱め、使える状態を保つことを優先する考え方で、古いデータが返ってもよいとしています。BASEのEにあたる結果整合性は、更新の直後は古い値が返ることがあっても、時間がたてば新しい値が返るようになる性質です。
ただし、NoSQLなら必ずBASEというわけではありません。Brewer自身が、2つは両端の間に幅がある考え方だとスライドに書いています。MongoDBは複数の文書にまたがるACIDのトランザクションに対応し、DynamoDBにもACIDを保証するトランザクションがあります。DynamoDBで結果整合性の読み取りと強い整合性の読み取りを選ぶ方法は、DynamoDBの記事で見られます。
NoSQLの型は、データをどう読むかで選ぶ
型を選ぶ手がかりは、そのデータを何で探し、何と一緒に読むかです。次の表は、用途の例と向く型の対応です。
| 用途の | 向く | 理由 |
|---|---|---|
| ページの | キーバリュー型 | キーで1件をすぐに読み書きできる。Redisの資料は、HTMLの断片やページのキャッシュを用途に挙げる |
| 商品 | ドキュメント型 | 商品ごとに項目が違っても、同じ集まりに入れられる |
| 売上の | 列指向 | 多くの行から少しの列だけを読む集計で、読む量が減る |
| おすすめ・ | グラフ型 | つながりをたどる問い合わせを、結合なしで書ける |
どの型も、得意な読み方に合わせてデータの形を決めています。読み方がまだ決まっていないデータや、どの項目でも探したいデータは、RDBのほうが扱いやすくなります。
NoSQLとRDBは、組み合わせて使える
1つのシステムで、RDBとNoSQLのどちらか一方だけを選ぶ必要はありません。注文や在庫のように正確さが大事なデータはRDBに置き、一部のデータだけをNoSQLに置く組み合わせ方があります。
Redisの公式資料は、よくある設計として2つの使い方を挙げています。1つは、書き込みの多い小さなデータをRedisに置き、大きなデータをSQLのデータベースに置く使い方です。もう1つは、ディスクのデータベースにあるデータの一部を、写しとしてRedisのメモリに持つ使い方です。
集めたデータを分析する用途では、業務のデータベースとは別に、分析用のデータベースを持つことがあります。その役割の分け方は、データウェアハウスの記事で説明しています。
参考にした資料
- AWS「What is NoSQL?」(NoSQLの定義、RDBとの違い)
- Redis Docs「Redis FAQ」(メモリに置く仕組み、ディスクのデータベースとの組み合わせ)
- MongoDB Manual「Data Modeling」(項目のそろわない文書、一緒に読むデータを一緒に保存する原則)
- MongoDB Manual「Transactions」(複数の文書にまたがるACIDのトランザクション)
- Amazon Redshift Database Developer Guide「Columnar storage」(列ごとの保存と、読む量の違い)
- Apache Cassandra Documentation「Data Modeling: Introduction」(パーティションキー、結合を使わない設計)
- Neo4j「What is a graph database」(ノード・リレーションシップ・プロパティ)
- Amazon DynamoDB Developer Guide「Amazon DynamoDB Transactions: How it works」(DynamoDBのトランザクション)
- Amazon DynamoDB Developer Guide「DynamoDB read consistency」(結果整合性のある読み取り)
- Eric Brewer「Towards Robust Distributed Systems」PODC Keynote, 2000(ACIDとBASEの対比)
練習問題(全5問)
正解:RDB以外の
NoSQLは、
正解:キーバリュー型
キーバリュー型は、
正解:ノードと、
グラフ型は、
正解:大量の
列指向は、
正解:更新は
BASEの
選んでから「採点する」を押すと、解説つきで答え合わせができます。
関連記事
おすすめの本 PR
セキュリティとデータベースは、基本情報技術者試験の対策本でまとめて学べます。

