はじめに
今年、私は Redis を Valkey へ移行する検討を行うために、NoSQL とはなんぞや、Valkey とはなんぞやを改めて学習する機会がありました。
この記事では NoSQL とはどういうものなのかの知見をまとめたいと思います。
NoSQL とは
NoSQL(Not Only SQL)は、一般的に知られているのリレーショナルデータベース (RDBMS)とは異なるアプローチでデータを管理するデータベースの総称です。
2000 年代後半、Web サービスの急速な成長に伴い、大量のデータを高速に処理する必要性が高まりました。Google の Bigtable や Amazon の Dynamo といった論文が公開され、これらに影響を受けた様々なデータベースが登場しました。
NoSQL という名前は「SQL を使わない」という意味ではなく、「SQL だけではない(Not Only SQL)」という意味だそうです。
RDBMS を否定せず、用途に応じて RDBMS と NoSQL を使い分けることが重要です。
RDBMS と NoSQL の違い
| 項目 | RDBMS | NoSQL |
|---|---|---|
| データモデル | テーブル | キーバリュー、ドキュメント、カラム、グラフなど |
| スキーマ | 固定スキーマ | 柔軟なスキーマ |
| スケーリング | 垂直スケーリング | 水平スケーリング |
| トランザクション | ACID | BASE |
| クエリ | SQL | データベースごとに異なる |
ACID と BASE
ACIDは RDBMS が保証するトランザクション特性です。
- Atomicity(原子性):トランザクションは全て成功するか全て失敗する
- Consistency(一貫性):データは常に整合性のある状態を保つ
- Isolation(独立性):トランザクション同士は互いに影響しない
- Durability(永続性):コミットされたデータは失われない
BASEは NoSQL が採用する考え方です。
- Basically Available(基本的に利用可能):システムは常に応答を返す
- Soft state(柔軟な状態):データは時間とともに変化しうる
- Eventual consistency(結果整合性):最終的にはデータが整合する
NoSQL の種類
キーバリュー型
キーとバリューのペアでデータを保存するシンプルな構造です。高速な読み書きが特徴で、キャッシュやセッション管理に適しています。
代表的なデータベース
- Redis
- Valkey
- Amazon DynamoDB
- Memcached
実際の使用イメージを Redis で示します。
SET user:1001 "{"name": "田中", "email": "tanaka@example.com"}"
GET user:1001
ドキュメント型
JSON や BSON などのドキュメント形式でデータを保存します。ドキュメントごとに異なる構造を持てるため、柔軟なデータモデリングが可能です。
代表的なデータベース
- MongoDB
- Couchbase
- Amazon DocumentDB
実際の使用イメージを MongoDB で示します。
{
"_id": "1001",
"name": "田中",
"email": "tanaka@example.com",
"orders": [
{ "product": "商品A", "price": 1000 },
{ "product": "商品B", "price": 2000 }
]
}
カラム指向型
行ではなく列単位でデータを格納します。大量のデータに対する集計処理や時系列データの分析に適しています。
代表的なデータベース
- Apache Cassandra
- HBase
- Google Bigtable
実際の使用イメージを Cassandra で示します。
CREATE TABLE users (
user_id UUID PRIMARY KEY,
name TEXT,
email TEXT,
created_at TIMESTAMP
);
INSERT INTO users (user_id, name, email, created_at)
VALUES (uuid(), '田中', 'tanaka@example.com', toTimestamp(now()));
ここで使われているのは CQL という Cassandra 専用クエリ言語です。
CQL は SQL に似ていますが、内部のデータ格納方法が異なります。RDBMS は 1 行のデータをまとめて格納しますが、カラム指向型は同じ列のデータをまとめて格納します。一方、JOIN はサポートされておらず、分散環境での性能を優先した設計になっています。
グラフ型
ノードとエッジでデータ間の関係性を表現します。SNS の友人関係や推薦システムなど、複雑な関係性を扱うのに適しています。
代表的なデータベース
- Neo4j
- Amazon Neptune
- JanusGraph
実際の使用イメージを Neo4j で示します。
// Neo4jの例(Cypher)
CREATE (tanaka:User {name: '田中', email: 'tanaka@example.com'})
CREATE (suzuki:User {name: '鈴木', email: 'suzuki@example.com'})
CREATE (tanaka)-[:FOLLOWS]->(suzuki)
// 田中がフォローしているユーザーを取得
MATCH (tanaka:User {name: '田中'})-[:FOLLOWS]->(followed)
RETURN followed.name
上記で用いられている Cypher は Neo4j 専用のクエリ言語です。Cypher は SQL に似た構文ですが、関係性の探索性能が大きく異なります。RDBMS で「友達の友達の友達」といったようなデータを探す場合、JOIN を重ねるたびに指数関数的に遅くなります。グラフ DB は関係性をポインタで直接持っているため、何階層たどっても一定の速度で探索できます。
まとめ
- NoSQL は「Not Only SQL」の略で、RDBMS を補完するデータベース
- 用途に応じて 4 つの種類(キーバリュー、ドキュメント、カラム指向、グラフ)から選択
- スケーラビリティと柔軟性が強みだが、トランザクション処理には注意が必要
- RDBMS と NoSQL は対立するものではなく、適材適所で使い分けることが重要