DDIA 第2章:データモデルとクエリ言語
Tony Duong
3月 12, 2026 · 1 分
概要
第2章では、データをどのようにモデル化し、どのようにクエリするかを探求します。データモデルの選択は、解決しようとしている問題の考え方に大きな影響を与えます。各モデルにはデータの使われ方に関する前提があり、その前提によって、ある操作は簡単になり、別の操作は扱いにくくなります。
リレーショナルモデル vs ドキュメントモデル
リレーショナルモデル(SQL)は、データを行のテーブルとして整理します。1970年にEdgar Coddによって提案され、1980年代半ばまでに主流となり、現在もほとんどのアプリケーションの標準です。
ドキュメントモデル(NoSQL)は2010年代に登場し、以下の要因によって推進されました:
- より高いスケーラビリティの必要性(大規模データセット、高い書き込みスループット)
- フリー・オープンソースソフトウェアへの志向
- リレーショナルモデルでは十分にサポートされない特殊なクエリ操作
- 制約の多いリレーショナルスキーマへの不満 — より動的で表現力のあるデータモデルへの要望
オブジェクト-リレーショナル・ミスマッチ
ほとんどのアプリケーションコードはオブジェクトや構造体を使用しますが、リレーショナルテーブルには厄介な変換レイヤー(インピーダンスミスマッチと呼ばれることがある)が必要です。ORMは助けになりますが、違いを完全に隠すことはできません。
履歴書が良い例です。リレーショナルデータベースでは、複数のテーブル(学歴、職歴、連絡先)をユーザーに結合する必要があります。ドキュメントモデルでは、全体を1つのJSONドキュメントとして表現できます — アプリケーションの見方にはるかに近い形です。
リレーショナル vs ドキュメントデータベースの現状
| 観点 | リレーショナル | ドキュメント |
|---|---|---|
| スキーマ | スキーマ・オン・ライト(強制) | スキーマ・オン・リード(柔軟) |
| 結合 | 自然で、十分にサポートされている | 弱く、アプリケーションレベルの結合が必要なことが多い |
| 多対一 | 外部キーで容易 | 非正規化またはアプリレベルの結合が必要 |
| データの局所性 | テーブル間に分散 | ドキュメント全体がまとめて保存される |
| 最適な用途 | 高度に相互接続されたデータ | 自己完結型のドキュメント、一対多のツリー構造 |
収束:リレーショナルデータベースはJSON/XMLカラムをサポートするようになり、ドキュメントデータベースは結合のような機能を追加しています。モデルは時間とともにより類似してきています。
多対一と多対多の関係
「Greater Seattle Area」のような平文の値をIDの代わりに保存すると、情報が重複します。正規な記録を参照するIDを使用すること(正規化)には、以下の利点があります:
- 一貫した綴り・書式
- 簡単な更新(一箇所の変更で済む)
- ローカライゼーションのサポート
- より良い検索
これには結合が必要です。ドキュメントデータベースは歴史的に結合を十分にサポートしておらず、結合をアプリケーションコードに押しやっていました — これはより遅く、より複雑です。
アプリケーションが成長するにつれて、データはより相互接続される傾向があり、結合サポートの欠如がますます問題になります。
データのためのクエリ言語
宣言型 vs 命令型
- 命令型(ほとんどのプログラミング言語):マシンに実行する手順を指示する
- 宣言型(SQL、CSS):欲しい結果のパターンを記述し、データベースオプティマイザがその取得方法を決定する
宣言型言語がデータベースに適している理由:
- クエリを変更せずにオプティマイザを改善できる
- 並列化が容易
- 実装の詳細を隠蔽する
MapReduce
多数のマシンにまたがって大量のデータを処理するためのプログラミングモデルです。完全に宣言型でも完全に命令型でもありません — map関数とreduce関数(純粋関数でなければならない)を書き、フレームワークが分散処理を担当します。
MongoDBはMapReduce的なクエリAPIをサポートしていますが、より宣言的な代替手段として集約パイプラインも導入しました。
グラフ型データモデル
多対多の関係がデータの大部分を占める場合、グラフとしてモデル化するのが自然です:頂点(ノード)が辺(関係)で接続されます。
例:ソーシャルネットワーク、ウェブリンク、道路ネットワーク、不正検出。
プロパティグラフ(Neo4jなど)
- 各頂点は一意のID、出入りする辺の集合、プロパティ(キーと値のペア)のコレクションを持つ
- 各辺は一意のID、末尾の頂点、先頭の頂点、関係を表すラベル、プロパティを持つ
- 任意の頂点を他の任意の頂点に接続できる — どの種類のものを接続できるかを制限するスキーマはない
クエリ言語:Cypher — プロパティグラフのための宣言型言語。
MATCH (person)-[:BORN_IN]->(place)-[:WITHIN*0..]->(usa:Location {name: 'United States'})
RETURN person.name
トリプルストア(RDF)
すべての情報は**(主語、述語、目的語)**のトリプルとして保存されます。主語は頂点で、目的語はプリミティブ値(プロパティ)または別の頂点(辺)です。
クエリ言語:SPARQL — Cypherに似ていますが、トリプルストア用です。
Datalog
3つの中で最も古く、後のクエリ言語の基礎となっています。組み合わせて再利用できるルールのセットを使用し、複雑なクエリに対して強力です。
重要なポイント
- すべてに最適な単一のデータモデルはない — アクセスパターンに基づいて選択する
- ドキュメントデータベースは、データが自己完結型で、関係がほとんど一対多の場合に優れている
- リレーショナルデータベースは、相互接続されたデータを持つほとんどのアプリケーションにとって最良のデフォルトのまま
- グラフデータベースは、あらゆるものが他のあらゆるものと関連し得る場合に理想的
- 宣言型クエリ言語は、最適化を可能にするため、データベースでは命令型より優れている
- データモデルは収束しつつある — リレーショナルデータベースはドキュメント機能を追加し、ドキュメントデータベースはリレーショナル機能を追加している
Claudeによる翻訳