NoSQLとは?データモデル、SQLとの違いと選び方

NoSQLデータベースは、リレーショナルテーブルモデルに依存するのではなく、ドキュメント、キー・バリューペア、ワイドカラム、グラフなどのモデルを使用するデータベースのファミリーです。データの形状やアプリケーションが必要とする操作に応じて1つを選択してください。NoSQLというラベルだけでは、クエリがより高速になったり設計が簡単になることは保証されません。

SQL(Structured Query Language:構造化クエリ言語)はデータを照会・操作するための言語であり、NoSQLは複数のモデルを含むカテゴリです。「Not Only SQL」は名前の説明の一つであり、すべての製品がSQLを禁止しているという意味ではありません。AWS NoSQL概要では、異なるモデルと目的について説明しています。

4つの主要なNoSQLデータモデル

これらのカテゴリはデータの表現方法を説明しています。1つの製品が複数のモデルをサポートする場合があり、同じカテゴリの製品でも照会機能や操作に差異があります。

モデル 基本的な表現 考慮すべきワークロード 例
キー-バリュー ユニークなキーとそれに関連する値 既知のキーによるキャッシュまたはセッションの検索 Redis、Amazon DynamoDB
ドキュメント フィールド、配列、ネストされたオブジェクトを持つドキュメント 属性が異なる製品カタログ、ユーザープロファイル MongoDB
ワイドカラム キーとカラムで整理された行またはパーティション デバイスまたは期間でクエリされるイベント記録 Apache Cassandra、Bigtable
グラフ エンティティのノードと関係のエッジ 推奨、依存関係、およびパストラバーサル Neo4j

キー・バリューデータベース

キー・バリューモデルでは、session:abc123 のようなキーを使用して値を検索します。セッションをIDで取得するなどアクセスが予測可能な場合に検討してください。値の中で任意の条件を検索する場合は、特定の製品のインデックスおよびクエリ機能を確認する必要があります。

値は単なる文字列である必要はありません。Redisは文字列と並んでハッシュ、リスト、セット、ソート済みセットをサポートしており、その詳細はデータ型リファレンスに記載されています。キャッシュの場合は、正本となるデータがどこに存在するか、エントリの有効期限、およびキャッシュされたエントリが存在しない場合に何が起こるかも決定してください。

ドキュメントデータベース

ドキュメントはアイテムのフィールド、配列、ネストされたオブジェクトをまとめます。JSON(JavaScript Object Notation:JavaScriptオブジェクト表記法)はそのような構造を表現するためのテキスト形式であり、MongoDBはBSON(Binary JSON)を使用してドキュメントを保存します。異なる属性を持つアイテムや、1つの画面でよく一緒に読み込まれるデータにはドキュメントを検討してください。

アクセス頻度、サイズ、更新に応じて、関連情報を文書に埋め込むか、別の文書の識別子を参照するかを選択します。住所をすべての注文にコピーすると読み取りが簡単になりますが、そのコピーが何を意味するのか、どのように管理されるのかを決める必要があります。MongoDB モデリングガイド はアクセスパターンに基づいて設計することを推奨しています。

ワイドカラムデータベース

ワイドカラムモデルは、行またはパーティションキーとカラムを中心にデータを整理します。Bigtable は行キーでソートされたマップを使用し、関連するカラムをカラムファミリーにまとめます。その ストレージモデルのドキュメント では、行、カラム、ファミリーについて説明しています。

ワイドカラムストアは、列の値をまとめる分析用カラムストアと同じものとして扱うべきではありません。Cassandraでは、クエリ指向のテーブルおよびパーティション設計が必要であり、リレーショナルジョインはサポートされません。そのデータモデリング入門では、「この期間のこのデバイスの記録を読み取る」といった質問をまず特定すべき理由が説明されています。候補のデータベースが必要な範囲クエリおよび集計をサポートしているか確認してください。

グラフデータベース

グラフは、人、製品、サーバーなどのエンティティをノードとして表し、それらの接続をエッジとして表します。サーバーの障害によって影響を受けるサービスを特定するといった、関係を追う質問について検討してください。

グラフは属性も格納できます。Neo4jのプロパティグラフモデルでは、ノードとリレーションシップの両方にプロパティを付与することが可能です(グラフの概念ガイドで説明されています)。グラフモデルはすべてのクエリを高速にするわけではありません。トラバーサルの深さ、リレーションシップの種類、パスの条件を定義する必要があります。

NoSQLはリレーショナルデータベースとどのように異なるのでしょうか?

リレーショナルデータベース管理システム(RDBMS:Relational Database Management System)は、テーブル、キー、制約を使ってデータを構成します。関連するレコードを結合したり、共通のルールを適用したりするのに有効な基盤を提供します。NoSQL製品はそのモデルに適した操作を提供するため、既存のスキーマをそのままコピーするのではなく、それぞれの候補がアプリケーションの質問にどのように答えるかを比較してください。

意思決定領域 リレーショナルモデルで確認すべきこと NoSQLモデルで確認すべきこと
構造 カラム、型、キー、制約 ドキュメント、キー、パーティション、またはグラフ関係
クエリと関係 結合、集計、およびさまざまなフィルタ 埋め込み、参照、キー検索、またはグラフ探索
変更と検証 スキーマ変更と既存データへの影響 柔軟な構造でも必須フィールド、型、バージョン管理
トランザクションと一貫性 テーブル間の分離と更新 サポートされる範囲、展開要件、読み取り/書き込み設定
スケーリングと運用 インデックス、レプリケーション、分散、および運用の複雑さ 分散キー、レプリカ、負荷分散、コストおよびリカバリ

JSONを保存することは自動的にNoSQLを必要とするわけではありません。例えばPostgreSQLはjsonbのためのJSON型とインデックスを提供します;そのJSON型のドキュメントを参照してください。一部のデータに柔軟な属性を使用しながら、リレーショナルルールとトランザクションを保持することも設計の候補となります。

柔軟なスキーマでも設計が必要です

スキーマは、フィールド名、型、必須値などの構造とルールを定義します。ドキュメントが異なるフィールドを持っていても、アプリケーションは予測可能なデータを必要とします。この架空のJSONカタログは、異なる属性を持つ2つの製品を示しています。

[
  {
    "product_id": "book-101",
    "name": "Database Basics",
    "price_krw": 24000,
    "attributes": {
      "author": "Mina Kim",
      "pages": 320
    }
  },
  {
    "product_id": "headphones-201",
    "name": "Wireless Headphones",
    "price_krw": 79000,
    "attributes": {
      "wireless": true,
      "battery_hours": 30
    }
  }
]

両方の製品はproduct_id、name、price_krwを共有しますが、ネストされたattributesは異なります。ドキュメント構造は、その変化を自然に表現します。ただし、同じ価格フィールドで数字と文字列を混在させると、並べ替えや計算が複雑になる可能性があるため、許可される型と欠損値の処理を定義してください。

MongoDBは型や値の範囲に対するバリデーションルールをサポートしています。そのスキーマバリデーションのドキュメントでは、必要に応じてルールを適用する方法が説明されています。対照的にCassandraのCQL(Cassandra Query Language)は、テーブル作成時に列と型を定義します。これはそのテーブル定義のリファレンスに示されています。「すべてのNoSQLデータベースはスキーマレスである」というのは正確ではありません。

JSONは構造を記述するものであり、それ自体が非構造化データというわけではありません。画像や動画をデータベース内に置くか、オブジェクトストレージに置き、その場所とメタデータをデータベースで管理するかは別に判断してください。ファイルサイズ、配信要件、管理の必要性がその選択に影響します。

製品ごとのトランザクションと一貫性保証を確認してください

トランザクションのサポートと範囲

トランザクションは、変更を作業単位として扱います。ACIDは、Atomicity(原子性)、Consistency(一貫性)、Isolation(独立性)、Durability(耐久性)を意味します。注文作成や在庫減少など、一緒に成功または失敗する必要がある変更については、最初に必要な保証を確立してください。

NoSQL はトランザクションが存在しないことを意味するわけではありません。MongoDB は、レプリカセットおよびシャードクラスタ上でマルチドキュメントトランザクションをサポートしており、その保証は導入方法や読み取り/書き込み設定に影響されます。詳細は トランザクションドキュメント を参照してください。DynamoDB もトランザクション API(アプリケーションプログラミングインターフェース)を提供していますが、対象やリージョンスコープなどの制限があります。詳細は トランザクションリファレンス をご覧ください。

書き込み直後に読み取りは何を返すことができますか?

レプリケーションの動作も重要です。結果整合性の読み取りでは、最近完了した書き込みがまだ読み取り結果に現れない場合があります。ユーザー操作ごとに要件を定義してください:ユーザーが注文を保存した直後に、その注文が一時的に存在しないことは許容されますか?

DynamoDBのテーブルとローカルセカンダリインデックスでは強い整合性の読み取りを使用できますが、グローバルセカンダリインデックスやストリームからの読み取りは結果整合性となります。クエリ対象ごとの差異については読み取り一貫性のドキュメントを参照してください。トランザクション内のACID整合性とレプリカ間の読み取り整合性は異なる問題です。

水平スケーリングではパフォーマンスは保証されません

水平スケーリングは、1台のサーバーをより大きなマシンに置き換えるのではなく、サーバーを追加することです。シャーディングはデータをサーバーに分散し、レプリケーションはコピーを維持します。複数のサーバーがあるだけでは、データのバランスやクエリの高速化は保証されません。MongoDBのシャーディング概要では、分散構成が別々に説明されています。

適切に分散されていないキーは、ホットパーティションへのリクエストを集中させることがあります。例えば、すべてのイベントを1つの固定キーの下にまとめると、負荷分散に逆効果になることがあります。DynamoDBのパーティションキーのガイダンスで説明されているように、アクセスパターンとキーの分布を一緒に考慮してください。

パフォーマンスは、データサイズ、インデックス、クエリ範囲、読み書きの比率、一貫性設定、およびワークロードに依存します。平均応答時間とともに、遅いリクエストのレイテンシ、障害、および回復挙動を比較してください。コスト評価にはレプリカ、バックアップ、ネットワーク、および運用作業を含める必要があります。NoSQLカテゴリーだけではコストが低いとは限りません。

NoSQLを検討すべきのはどんな場合ですか?

  • 既知キーキャッシュやセッションアクセスの場合:有効期限、永続性、および信頼できるデータとの同期を定義しながら、キー・バリュー・ストアを検討してください。
  • 属性が異なるカタログアイテムの場合:共有フィールドの検証および検索インデックスを設計しながら、ドキュメントを検討してください。
  • 既知のキーと期間によって問い合わせされたイベント: パーティションサイズと範囲クエリを確認しつつ、ワイドカラムストレージを検討してください。
  • 複数ステップの関係トラバーサル: 接続タイプとトラバーサルの深さを定義する際に、グラフを検討してください。

さまざまなレポートが複数のテーブルを結合したり、レコード間の制約を集中して適用する必要がある場合は、リレーショナルデータベースを早期に比較する価値があります。業界ラベルやデータ量だけで決定せず、各候補で最も重要な読み取りと更新がどのように動作するかを確認してください。

異なるストアに異なる役割を割り当てることができます。例えば、リレーショナルデータベースを正本の保存先として使用し、キー・バリューストアをキャッシュとして使用するなどです。追加のストアはコピーの更新、削除の伝播、およびリカバリをより複雑にするため、実際に必要がある場合にのみ追加してください。

実践的な評価の手順

  1. 重要なクエリを書き出します。IDによる製品検索、最近のユーザー注文、またはデバイスの日次記録などのタスクのために、フィルタと並び順を指定します。
  2. 正確性の要件を定義します。必ず同時に成功させる必要のある変更、重複リクエストの処理、即時読み取り、および許容される古い値を記録します。
  3. 実際の候補モデルを設計します。データが増えるにつれて、ドキュメントサイズ、埋め込みまたは参照、インデックス、パーティションキー、クエリパスを確認します。
  4. 小規模な実装を比較します。同じデータと操作を使用して通常負荷、集中負荷、障害を再現し、製品バージョンと設定を記録します。
  5. 運用と移行を計画します。権限、バックアップと復元、監視、移行、予想コスト、および必要に応じて既存ストアへの復帰経路を確認します。

まずクエリと正確性の要件から始め、それを満たすモデルと製品を選択します。すでに使用しているデータベースがこれらの要件を満たしている場合は、別の種類のストアを導入する前にその理由を明確にします。