C
データベース/NoSQL/Lesson 05

NoSQL 基礎 — Redis・MongoDB をいつ使うか

45分·theory

NoSQL 基礎 — Redis・MongoDB をいつ使うか

🎯 このレッスンを読み終えたら

このレッスンをすべて読み終えると、以下の3つを自信を持って実践できるようになります。

  • ✅ RDBMS vs NoSQL の選択基準(整合性 vs 柔軟性)
  • ✅ Redis の3大活用法(キャッシュ・セッション・Rate Limit)
  • ✅ MongoDB のドキュメントが適しているケース vs 向かないケース

学習目標をチェックリストとして手元に置き、すべて答えられるようになったらレッスンを閉じてください。

なぜ NoSQL が登場したか

RDBMS の強み — データ整合性

MySQL・PostgreSQL は数十年にわたって検証された標準。トランザクション・外部キー・正規化によってデータの一貫性を保証します。

RDBMS の限界 — 水平スケールが難しい

  • トラフィックが急増するとサーバー1台では限界に達する
  • 複数サーバーへのデータ分割(シャーディング)が困難 — JOIN や外部キーがサーバー境界を越えると破綻する
  • すべての行が同じカラム構造 — 柔軟性に乏しい

NoSQL の4種類

分類代表例データモデル用途
Key-ValueRedis, DynamoDBkey → valueキャッシュ・セッション
DocumentMongoDB, CouchbaseJSON ドキュメント柔軟なスキーマ、高速開発
Wide-ColumnCassandra, HBaseカラムファミリ大容量時系列データ
GraphNeo4jノード + リレーションSNS、レコメンデーション

実務での選択基準 — RDBMS がデフォルト

2026年現在、新規プロジェクトの大半は RDBMS をメインに採用しています。NoSQL は特定用途のサブシステムとして活用:

code
[Webアプリ]
   ↓
[MySQL] ← ユーザー・注文・商品(整合性重視)
[Redis] ← キャッシュ・セッション・ランキング(速度重視)
[Elasticsearch] ← 全文検索(オプション)

「MySQL + Redis」が実務の80% を占める標準構成。最初から MongoDB をメインにするケースは減少傾向にあります。

Redis — キャッシュ・セッション・Rate Limit の3パターン

Redis が速い理由

すべてのデータをメモリ上に保持します。MySQL がディスク(ミリ秒)なら、Redis はメモリ(マイクロ秒) — 100倍の差があります。

パターン1 — キャッシュ(最もよく使われる用途)

python
def get_user(user_id):
    cached = redis.get(f"user:{user_id}")
    if cached:
        return json.loads(cached)        # キャッシュヒット → DB アクセス不要

    user = db.query("SELECT * FROM users WHERE id = ?", user_id)
    redis.setex(f"user:{user_id}", 300, json.dumps(user))   # 5分キャッシュ
    return user

読み取りが圧倒的に多いデータ(読み取り100:書き込み1 の比率)に対して絶大な効果を発揮します。

キャッシュの無効化 — 最も難しい問題

python
def update_user(user_id, data):
    db.update(...)
    redis.delete(f"user:{user_id}")   # キャッシュを即時削除

「コンピュータサイエンスで本当に難しいことは2つだけ:キャッシュの無効化と名前付けだ」 — キャッシュ無効化の漏れは実務バグの定番原因です。

パターン2 — セッションストア

python
# ログイン時にセッションを保存
session_id = secrets.token_urlsafe(32)
redis.setex(f"session:{session_id}", 86400, user_id)   # 24時間有効

# リクエストごとに検証
user_id = redis.get(f"session:{session_id}")
if not user_id:
    raise Unauthorized()

複数サーバー(Tomcat クラスタなど)が同じセッションを共有できます。JWT と異なり、サーバー側で即時無効化が可能です。

パターン3 — Rate Limit

python
def check_rate_limit(user_id, limit=100, window=60):
    key = f"rate:{user_id}"
    count = redis.incr(key)
    if count == 1:
        redis.expire(key, window)        # 最初のリクエスト時に TTL を設定
    if count > limit:
        raise TooManyRequests()

1分あたり100回を超えるリクエストをブロックします。INCR + EXPIRE の2行で実装完了。API 乱用防止・DDoS の第一防衛ラインとして機能します。

その他のよく使われる用途

  • ランキングZADD leaderboard 100 user1 → Sorted Set によるリアルタイムランキング
  • Pub/Sub — 軽量なメッセージブローカー(小規模限定)
  • 分散ロック — Redlock アルゴリズム(慎重に使うこと)

限界 — 永続性が弱い

メモリが失われるとデータも消えます。AOF・RDB バックアップはありますが、主要なデータストアには不向きです。常に原本は DB、キャッシュは Redis というアーキテクチャを守ってください。

MongoDB — ドキュメント構造と使うべきタイミング

ドキュメントとは何か

JSON に似た文書が1行分のレコードになります。カラムを事前に定義する必要はありません。

json
// users コレクション(= RDBMS のテーブル)
{
    "_id": ObjectId("..."),
    "email": "[email protected]",
    "name": "Alice",
    "address": {
        "city": "Seoul",
        "zip": "06000"
    },
    "hobbies": ["coding", "music"]
}

オブジェクトや配列をそのまま保存できます。RDBMS なら3テーブル + JOINが必要な構造を1つのドキュメントに収められます。

基本クエリ

javascript
// 追加
db.users.insertOne({ email: "[email protected]", name: "Alice", age: 30 });

// 検索
db.users.find({ age: { $gte: 18 } });

// 更新
db.users.updateOne(
    { email: "[email protected]" },
    { $set: { age: 31 } }
);

// 削除
db.users.deleteOne({ email: "[email protected]" });

MongoDB が適しているケース

✅ 適している

  • 柔軟なスキーマ — コンテンツのメタデータ(動画・記事 — フィールドが都度異なる)
  • 高速プロトタイピング — マイグレーションの負担が少ない
  • ログ・イベント保存 — 時系列データ
  • 階層構造データ — コメントツリー、ナビゲーションメニュー

❌ 向かないケース

  • トランザクション + 強い整合性 — MongoDB もトランザクションをサポートするが、RDBMS ほど堅牢ではない
  • 複雑な JOIN — MongoDB の $lookup遅い
  • 固定スキーマ + 整合性重視 — ユーザー・決済・注文 — MySQL が正解

RDBMS との一行比較

MySQLMongoDB
データモデルテーブル + カラムコレクション + ドキュメント
スキーマ固定(DDL 必要)柔軟(都度定義)
JOIN強力制限あり($lookup
トランザクション強力(ACID)4.0+ からサポート(制約あり)
スケール垂直スケールが優勢水平スケール(シャーディング)が容易
学習コスト標準 SQL独自クエリ言語

推奨学習順序

1. まず MySQL をマスター — あらゆるバックエンドエンジニアの共通基礎
2. Redis — キャッシュとセッションは最も使用頻度が高い
3. MongoDB — 実際に必要なプロジェクトが生まれたときに学ぶ

「NoSQL が得意です」より「MySQL が得意です」のほうが、面接では圧倒的に力強いアピールになります。

🤖 AI にこう依頼してみてください

このレッスンの概念を理解すれば、AI に具体的な指示を出せるようになります。漠然とした「直して」ではなく、適切な語彙を使ったリクエスト — それがトークン節約の出発点です。

  • 「users・orders・products の3テーブルを設計し、外部キーとインデックスまで作成して」
  • 「過去7日間に登録したユーザー数を日別に集計するクエリを書いて」
  • 「このクエリに EXPLAIN を付けて実行計画を解釈して」

なぜこれがトークンを減らすのか

概念を知らないままだと、AI の回答を受け取っても「それは何ですか?」と再度質問しなければなりません。その「再質問」がトークンを消費します。概念を一度しっかり身につければ、1回のやり取りで会話が完結します。

NoSQL 基礎 — Redis・MongoDB をいつ使うか - データベース