NoSQLは、表と行で管理するリレーショナルデータベース(RDB)以外のデータベースをまとめて指す呼び名です。読み方は「ノーエスキューエル」で、「Not Only SQL」の略として説明されることが多い呼び名です。中身はキーバリュー型・ドキュメント型・ワイドカラム型・グラフ型の4つに大別され、データの持ち方も得意な問い合わせもそれぞれ違います。この記事では、4つの型をDockerで起動して実際にデータを出し入れしながら、RDBとの違い、クエリから逆算する設計の順番、整合性とトランザクションの設定値、採用すべき処理と見送るべき処理までを順に示します。
まとめ:NoSQLは引き方が決まった処理に絞り、正本はRDBに残す判断
NoSQLを選ぶ理由は「SQLが嫌だから」でも「新しいから」でもなく、問い合わせの形が少数に決まっていて、その引き方を速く安く大量にさばきたいときです。セッション、ログやイベント、商品カタログ、関係のたどり込みがこれに当たります。
逆に、会計や在庫のように複数の表をまたいで整合性を保つ処理、集計軸があとから増える帳票は、RDBに置いたままにします。実務ではRDBを正本にし、特定の読み取りだけをNoSQLへ逃がす併用が一番失敗しにくい構成です。
NoSQLの定義と読み方、RDBとの違いをスキーマ・結合・整合性で比べる基礎
データベース全体の分類やDBMSの役割は親記事のデータベースとは?RDBとNoSQLの違い・種類と選び方を実測で解説で扱っています。ここではNoSQLに絞って、RDBと何が違うのかを実装上の差で押さえます。
Not Only SQLの由来とRDB以外のDBを総称する呼び名としての範囲
NoSQLは製品名でも規格名でもありません。RDBが苦手とする「1台に収まらない書き込み量」「列が行ごとに変わるデータ」「関係を何段もたどる検索」に向けて作られたデータベース群を、あとからまとめて呼んだ名前です。共通の仕様書は存在しないため、整合性の強さもクエリ言語も製品ごとに違います。
「SQLを使わない」という意味でもありません。CassandraはCQL(Cassandra Query Language)というSQLに似た言語を持ち、DynamoDBもPartiQLというSQL互換の言語で読み書きできます。見た目がSQLでも、結合や任意の条件検索はできない点が違いです。
RDBとNoSQLの違いをスキーマ・結合・整合性・拡張方法で比べた比較表
選定の場面で効いてくる差は次の5項目です。
| 観点 | RDB | NoSQL(一般的な傾向) |
|---|---|---|
| スキーマ | 表の定義が先に必要 | 項目ごとに形が違ってよい |
| 結合 | JOINで自由に組み合わせる | 原則なし、事前に1か所へ寄せる |
| 問い合わせ | 条件をあとから自由に足せる | キーで決めた引き方が速い |
| 整合性 | ACIDトランザクションが標準 | 製品と設定で強さを選ぶ |
| 拡張方法 | 主にサーバーを大きくする | ノードを足して分散させる |
最初に見るべきは「問い合わせ」の行です。DynamoDBの設計ガイドは、RDBは柔軟に問い合わせられる代わりに高トラフィックで伸びにくく、NoSQLは限られた引き方なら効率よく読める一方、それ以外の問い合わせは遅く高くつくと整理しています。スキーマの自由さは、この制約と引き換えに得ているものです。
NoSQLの4つの種類をDockerで起動しデータの持ち方を手で確かめる手順
4つの型の違いは、同じ「注文」や「ユーザー」を入れてみると一番よく分かります。以下はすべて公式のDockerイメージ(redis・mongo・cassandra・neo4j)で、手元のPCだけで試せます。
キーバリュー型:Redis 8でSETとHSETを打ちキーだけで引く読み方
キーバリュー型は、キーを渡すと値が1つ返るだけの最も単純な型です。値の中身で検索する機能は基本的に持ちません。Redisのデータ型一覧にあるとおり、値には文字列のほかHash・List・Set・Sorted Setなどの構造を持たせられます。
docker run -d --name redis -p 6379:6379 redis:8
docker exec -it redis redis-cli
SET session:abc123 '{"user_id":1001}' EX 1800 # 30分で消えるセッション
GET session:abc123
TTL session:abc123 # 残り秒数
HSET user:1001 name "佐藤" plan "pro"
HGET user:1001 plan # "pro"
「planがproのユーザーを全員出す」という問い合わせは、この形のままでは書けません。必要なら別のキーに一覧を持たせる設計を自分でします。キャッシュやセッション、回数制限での具体的な使い方はKVS(キーバリューストア)とはで掘り下げています。
ドキュメント型:MongoDB 9.0で入れ子のJSONを保存しフィールドで検索
ドキュメント型は、JSONに近い形の1件(ドキュメント)をそのまま保存し、中のフィールドで検索できる型です。注文と明細を別々の表に分けず、1件の中に入れ子で持てます。MongoDBの上限値では、1ドキュメントの大きさは16MiBまでと定められています。
docker run -d --name mongo -p 127.0.0.1:27017:27017 mongo:9.0
docker exec -it mongo mongosh
use shop
db.orders.insertOne({
customer: { id: 1001, name: "佐藤" },
items: [ { sku: "A-1", qty: 2, price: 1200 }, { sku: "B-7", qty: 1, price: 800 } ],
status: "paid",
createdAt: new Date()
})
db.orders.find({ "customer.id": 1001, status: "paid" }) // 入れ子のフィールドで検索
db.orders.find({ "items.sku": "A-1" }) // 配列の中も検索できる
RDBなら注文表と明細表をJOINする場面が、1回の読み取りで済みます。ただし、別の注文から同じ顧客名を参照していると、名前を変更する際は、全件の書き換えが必要です。ドキュメント構造のルールと埋め込み・参照の使い分けはMongoDBとは?ドキュメント指向データベースの仕組みにまとめています。
ワイドカラム型:Cassandra 5.0のCQLでパーティションキーを設計する
ワイドカラム型は、パーティションキーでデータを複数ノードに振り分け、同じパーティション内をクラスタリングキーの順に並べて持つ型です。書き込みが多く、ノードを足して伸ばしたい用途に向きます。起動には1分前後かかるため、cqlshがつながるまで待ちます。
docker run -d --name cassandra -p 9042:9042 cassandra:5.0
docker exec -it cassandra cqlsh
CREATE KEYSPACE shop WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1};
CREATE TABLE shop.orders_by_customer (
customer_id int, order_date date, order_id timeuuid, total int,
PRIMARY KEY ((customer_id), order_date, order_id)
) WITH CLUSTERING ORDER BY (order_date DESC, order_id DESC);
INSERT INTO shop.orders_by_customer (customer_id, order_date, order_id, total)
VALUES (1001, '2026-11-01', now(), 3600);
-- パーティションキーを指定するので速い
SELECT * FROM shop.orders_by_customer WHERE customer_id = 1001 AND order_date >= '2026-10-01';
-- キー以外の条件だけだとエラーになり、ALLOW FILTERING を求められる
SELECT * FROM shop.orders_by_customer WHERE total > 3000;
テーブル名がorders_by_customerなのは、「顧客ごとに注文を新しい順で出す」という1つの問い合わせのためだけに作った表だからです。SimpleStrategyは公式ドキュメントでテスト用途に限るとされており、本番ではデータセンター単位で複製数を決めるNetworkTopologyStrategyを使います。運用面はCassandraとは?分散NoSQLの仕組み・データモデル・採用判断で扱っています。
グラフ型:Neo4jのCypherで関係をたどる友人の友人検索を書く
グラフ型は、データをノード(点)とリレーションシップ(線)で持ち、つながりをたどる検索に特化した型です。Cypherマニュアルは、Cypherを宣言型の問い合わせ言語と位置づけています。2026年11月時点のマニュアルはCypher 25が対象です。パスワードは8文字以上にしないと起動に失敗します。
docker run -d --name neo4j -p 7474:7474 -p 7687:7687 -e NEO4J_AUTH=neo4j/password123 neo4j:2026
docker exec -it neo4j cypher-shell -u neo4j -p password123
CREATE (a:Person {name: '佐藤'})-[:FOLLOWS]->(b:Person {name: '鈴木'})-[:FOLLOWS]->(c:Person {name: '高橋'});
// 佐藤さんがまだフォローしていない「フォローのフォロー」を出す
MATCH (me:Person {name: '佐藤'})-[:FOLLOWS]->()-[:FOLLOWS]->(fof)
WHERE fof <> me AND NOT EXISTS { (me)-[:FOLLOWS]->(fof) }
RETURN DISTINCT fof.name;
RDBで同じことを書くと、フォロー表の自己結合を段数ぶん重ねることになり、3段・4段と深くなるほど遅くなります。グラフ型は段数が増えても、たどった範囲だけを読む作りです。エディション選定やCypherの詳しい書き方はNeo4jとは?グラフデータベースの構造とCypherを参照してください。
クエリから逆算するNoSQLのデータ設計とRDBの正規化との違い
4つの型を触ると、どれも「どう引くか」を先に決めないと表が作れないことに気づきます。NoSQLで一番つまずくのはここです。
アクセスパターンを先に列挙し非正規化でテーブルを組む設計の順番
RDBは正規化したモデルを先に作り、問い合わせはあとから考えても成り立ちます。NoSQLは逆です。Cassandraのデータモデリング解説は「データモデルからではなくクエリモデルから始める」と書き、非正規化は普通のことだと明言しています。DynamoDBのガイドも、答えるべき問いが分かるまでスキーマ設計を始めるべきではないとしています。
- 画面とAPIを洗い出し、「何をキーに、何を、どの順で取るか」を1行ずつ書く
- 読み取り回数の多い順に並べ、上位の問い合わせが1回の読み取りで済む形を決める
- その形に合わせてパーティションキーとソート順を決め、必要ならデータを複製して持つ
- 残った少数の問い合わせは索引(GSIなど)か、別の仕組みに逃がす
手順1の一覧が書けない段階なら、まだNoSQLを選ぶ時期ではありません。要件が固まっていないなら、変更に強いRDBで始めるほうが手戻りは少なくなります。DynamoDBで設計を検証する道具としてはNoSQL Workbenchの使い方で紹介しているData Modelerが使えます。
JOINが無い前提で起きる二重書き込みと更新漏れを防ぐ実装の型
非正規化すると、同じ値が複数の場所に入ります。Cassandraの例で「顧客別」に加えて「日付別」の注文一覧が要るなら、orders_by_dateという2つ目の表を作り、注文のたびに両方へ書き込む構成です。片方だけ書けて片方が落ちると、画面によって注文が見えたり見えなかったりする状態が生まれます。
実装の型は2つあります。1つは書き込み側で両方の更新を1つの単位にまとめる方法で、CassandraならBATCH文、DynamoDBならTransactWriteItemsを使います。もう1つは、正本を1か所にだけ書き、変更フィード(DynamoDB StreamsやMongoDBのChange Streams)から複製先を非同期に作り直す方法です。後者は数秒の遅れを許せる画面に限って使います。どちらも採らずにアプリのコードで2回書くだけの実装は、障害時に必ずずれます。
整合性とトランザクションの扱い:CAPと結果整合性を設定値で読む
分散したデータベースでは、ネットワークが切れたときに「最新の値を返すこと」と「応答を返し続けること」を同時には満たせません。2000年にEric Brewerが示したこの関係はCAP定理と呼ばれ、NoSQLの製品説明に頻繁に出てきます。実装者が見るべきは理論ではなく、その選択がどの設定値に現れているかです。
DynamoDBとCassandraで選ぶ読み取りの整合性レベル
DynamoDBの読み取り整合性は既定が結果整合性で、直前の書き込みが読み取りに反映されていないことがあります。ConsistentReadをtrueにすると最新の値を返しますが、読み取り単価は結果整合性の2倍です。グローバルセカンダリインデックス(GSI)からの読み取りは、常に結果整合性になります。
# DynamoDB:既定は結果整合性。最新値が必要な読み取りだけ強い整合性にする
aws dynamodb get-item --table-name Orders \
--key '{"PK":{"S":"CUSTOMER#1001"},"SK":{"S":"ORDER#2026-11-01"}}' \
--consistent-read
-- Cassandra(cqlsh):複製数3なら書き込みと読み取りを QUORUM(2台)にそろえる
CONSISTENCY QUORUM;
SELECT * FROM shop.orders_by_customer WHERE customer_id = 1001;
Cassandraでは操作ごとに整合性レベルを選ぶ仕組みです。公式ドキュメントは、書き込みと読み取りで応答を待つレプリカの集合が重なるように選ぶのが一般的だとしています。複製数3で両方をQUORUMにすれば2台+2台で必ず重なり、書いた値を次の読み取りで確認できる構成です。両方をONEにすると速い代わりに、古い値が返る可能性は残ったままです。DynamoDBの設計と料金の詳細はAmazon DynamoDBとはで解説しています。
MongoDBの単一ドキュメント原子性とマルチドキュメントトランザクション
MongoDBのトランザクション解説によると、1つのドキュメントへの操作は原子的に実行されます。関連データを1件に埋め込めば、複数ドキュメントをまたぐトランザクションはそもそも要りません。在庫の引当なら、条件付きの1回の更新で二重引当を防げます。
// 在庫が2以上あるときだけ2減らす。0件更新なら在庫不足として扱う
db.stock.updateOne(
{ sku: "A-1", qty: { $gte: 2 } },
{ $inc: { qty: -2 } }
)
複数ドキュメントのトランザクションも使えますが、レプリカセットかシャードクラスタが前提です。上のDockerの単体起動ではトランザクションを開始できません。本番運用の注意点には、既定で1分未満で終わらせる必要があるとの記載もあります。分散トランザクションは単一ドキュメントの書き込みより重く、スキーマ設計の代わりにはならない。これは公式自身の注記です。分離レベルなどトランザクション一般の考え方はトランザクションとは?分離レベルの違い・ACIDで整理しています。
NoSQLを採用すべき処理と見送るべき処理を分ける受託開発の判断基準
ここまでの性質を踏まえ、どの処理ならNoSQLに置いてよく、どの処理なら置かないかを言い切ります。
セッション・ログ・カタログ・関係探索でNoSQLを採用してよい条件
採用してよいのは、問い合わせが3〜5種類程度に収まり、その一覧を設計前に書き出せる処理です。具体的には次の場面が当てはまります。
- ログイン状態やカートなど、キーで1件を引き、期限で消えてよいデータ(キーバリュー型)
- 商品ごとに属性の数も種類も違うカタログや、画面単位で丸ごと読むCMSのデータ(ドキュメント型)
- IoTのセンサー値や行動ログなど、書き込みが多く時系列で読むデータ(ワイドカラム型)
- レコメンドや不正検知など、つながりを3段以上たどる検索(グラフ型)
どれも「消えても正本から作り直せる」か「書き込みの量が1台のRDBの限界を超える」かのどちらかを満たしています。両方とも当てはまらないなら、NoSQLを選ぶ理由はまだありません。
会計・在庫・帳票集計をNoSQLに置かないと決める理由と失敗パターン
会計仕訳、在庫の受払、請求のように、複数の表を同時に正しく更新し、あとから監査で突き合わせるデータはRDBに置きます。集計軸があとから増える管理画面の帳票も同じです。NoSQLでは新しい集計軸のたびに表かインデックスを作り直すことになり、要件追加のたびに移行作業が発生します。
よくある失敗は、「スキーマ変更が楽そうだから」という理由で業務システム全体をドキュメント型で作り、半年後に月次集計と他データとの突き合わせで行き詰まるパターンです。JSONの柔軟さだけが目的なら、RDBのままPostgreSQLのjsonb型に可変部分だけを入れる構成で足ります。既存のRDBとNoSQLをどう分担させるか、移行するなら何から動かすかの設計は、一創のデータベース設計・移行支援で要件整理から支援しています。
マネージドサービスで選ぶ場合のDynamoDB・Atlas・Cosmos DBの対応表
本番では自分でクラスタを運用せず、クラウドのマネージドサービスを使うのが一般的です。型との対応は次のとおりです。
| 型 | AWS | Google Cloud | Azure・その他 |
|---|---|---|---|
| キーバリュー | DynamoDB、ElastiCache | Memorystore | Azure Managed Redis |
| ドキュメント | DocumentDB、DynamoDB | Firestore | Cosmos DB、MongoDB Atlas |
| ワイドカラム | Amazon Keyspaces | Bigtable | Cosmos DB(Cassandra API) |
| グラフ | Neptune | Spanner Graph | Neo4j AuraDB |
選ぶ順番は、まず型を決め、次に既に使っているクラウドに合わせる流れです。型を決めずにクラウドの都合でサービスから選ぶと、問い合わせに合わない型を引き当てやすくなります。MongoDBのマネージド版はMongoDB Atlasとは、複数のAPIを持つAzureのサービスはAzure Cosmos DBとは、GCPのワイドカラム型はCloud Bigtableとはで個別に比較しています。
よくある質問
NoSQLを初めて検討するときによく出る質問に答えます。
NoSQLの読み方と意味は何ですか?
「ノーエスキューエル」と読みます。「エヌオーエスキューエル」と読む人もいます。意味は「Not Only SQL」の略とされることが多く、RDB以外のデータベースをまとめて指す呼び名です。特定の製品や規格を指す言葉ではないため、「NoSQLはこういう性能」と一括りに語ることはできません。キーバリュー型・ドキュメント型・ワイドカラム型・グラフ型のどれを指しているかで、得意な処理がまったく違います。
NoSQLのメリットとデメリットは何ですか?
メリットは、決まった引き方の読み書きをノードを足して大量にさばけることと、項目の形が揃っていないデータをそのまま入れられることです。デメリットは、JOINや任意条件の検索が弱く、あとから問い合わせを足すたびに表の作り直しが起きやすい点にあります。整合性も製品と設定によって変わるため、どこまで古い値を許すかを設計時に決めなければなりません。実務ではデメリット側の重みのほうが大きく、要件が固まっていない段階での採用は避けるのが無難です。
NoSQLでもSQLのような問い合わせは書けますか?
書けるものがあります。CassandraのCQL、DynamoDBのPartiQLはSQLに似た文法で、SELECTやINSERTを使える言語です。ただし文法が似ているだけで、結合はできず、キー以外の条件だけで検索すると全件の読み取りになったりエラーになったりします。本文のCassandraの例でALLOW FILTERINGを求められたのがその典型です。SQLに見えるからといってRDBと同じ感覚で条件を書くと、性能と料金の両方で問題が出ます。
JSONを保存したいならNoSQLを選ぶべきですか?
JSONを保存したいだけなら、NoSQLは必須ではありません。PostgreSQLのjsonb型やMySQLのJSON型で、RDBの中にJSONを持ち、中のキーで検索することもできます。NoSQLを選ぶべきなのは、JSONの形に加えて、書き込み量がRDB1台の限界を超える、あるいは問い合わせが少数に決まっていてその速さが最優先、という条件がそろうときです。取引データと同じ表で管理したいなら、RDBのJSON型を使うほうが整合性を保ちやすくなります。
NoSQLの代表的な製品にはどんな例がありますか?
型ごとに挙げると、キーバリュー型はRedisやValkey、Amazon DynamoDB、ドキュメント型はMongoDBやCloud Firestore、ワイドカラム型はApache CassandraやCloud Bigtable、グラフ型はNeo4jやAmazon Neptuneが代表です。DynamoDBやAzure Cosmos DBのように、複数の型にまたがる使い方ができるサービスもあります。製品名から入るより、先に自分の処理がどの型に合うかを決めてから候補を絞るほうが、選定の手戻りは少なくなります。
関連記事
- データベースとは?RDBとNoSQLの違い・種類と選び方を実測で解説:RDBを含むデータベース全体の分類とDBMSの役割
- KVS(キーバリューストア)とは:Redisで動かして分かる仕組みとRDBとの使い分け:キーバリュー型をキャッシュとセッションに組み込む実装
- MongoDBとは?ドキュメント指向データベースの仕組み・利点・使い方入門:ドキュメント型の構造と埋め込み・参照の使い分け
- Cassandraとは?分散NoSQLの仕組み・データモデル・採用判断:ワイドカラム型の分散構成と運用
- Neo4jとは?グラフデータベースの構造とCypher・エディション選定:グラフ型の問い合わせとエディションの選び方