大量データ集計・分析(OLAP)
RDBでは難しい大量データのリアルタイム集計・分析を実現するための知識を学ぶセクションです。
なぜ OLAP を学ぶのか
┌─────────────────────────────────────────────────────────────┐
│ 「年間のログイン失敗率を出してほしい」 │
├ ─────────────────────────────────────────────────────────────┤
│ │
│ PostgreSQL(OLTP)で頑張る場合: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 18億行フルスキャン → 数分〜タイムアウト │ │
│ │ 事前集計テーブルの設計・運用が必要 │ │
│ │ ロック競合、バッチ集計のTZ問題... │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ OLAP エンジンを使う場合: │
│ ┌─────────── ──────────────────────────────────────────┐ │
│ │ 18億行 → 数秒で集計完了 │ │
│ │ 事前集計テーブル不要(生データから直接クエリ) │ │
│ │ SQLそのまま、JDBCで接続 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ 「適材適所」を知ることで、設計の選択肢が広がる │
│ │
└─────────────────────────────────────────────────────────────┘
OLTP vs OLAP
┌──────────────────────────────────────────────────────────────────────┐
│ │
│ OLTP (Online Transaction Processing) │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ 目的: トランザクション処理(認証、決済、登録) │ │
│ │ 代表: PostgreSQL, MySQL, Oracle │ │
│ │ 得意: INSERT/UPDATE/DELETE、1行〜数百行の読み書き │ │
│ │ 苦手: 数億行の集計、年次レポート │ │
│ │ ストレージ: 行指向(1行のデータが連続して格納) │ │
│ │ │ │
│ │ 行1: [id][type][tenant_id][user_id][detail][created_at] │ │
│ │ 行2: [id][type][tenant_id][user_id][detail][created_at] │ │
│ │ 行3: [id][type][tenant_id][user_id][detail][created_at] │ │
│ │ → 1行取得は速い、集計は全カラム読むので遅い │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │
│ OLAP (Online Analytical Processing) │
│ ┌────────────────────────────────────────────────────────────────┐ │
│ │ 目的: 分析・集計(レポート、ダッシュボード、傾向分析) │ │
│ │ 代表: ClickHouse, BigQuery, Redshift, Snowflake │ │
│ │ 得意: COUNT/SUM/GROUP BY、数億〜数十億行の集計 │ │
│ │ 苦手: 1行のUPDATE/DELETE、トランザクション │ │
│ │ ストレージ: 列指向(同じカラムのデータが連続して格納) │ │
│ │ │ │
│ │ type列: [login_success][login_success][login_failure] │ │
│ │ tenant_id列: [tenant-1][tenant-1][tenant-2] │ │
│ │ user_id列: [user-1][user-2][user-3] │ │
│ │ created_at列: [2026-03-24][2026-03-24][2026-03-25] │ │
│ │ → 必要な列だけ読む、同じ値が並ぶので圧縮率が高い │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────────┘
| OLTP (PostgreSQL) | OLAP (ClickHouse) | |
|---|---|---|
| 1行INSERT | ◎ ミリ秒 | ○ ミリ秒(バッチ推奨) |
| 1行UPDATE | ◎ ミリ秒 | × 非効率 |
| トランザクション | ◎ ACID保証 | × 限定的 |
| 100万行 COUNT | △ 数秒 | ◎ ミリ秒 |
| 1億行 GROUP BY | × 数分〜不可 | ◎ 秒 |
| 18億行 年次集計 | × タイムアウト | ◎ 数秒 |
| 圧縮率 | 1x | 10〜40x |
| SQL | ◎ 標準SQL | ◎ 標準SQL + 拡張関数 |
学習の流れ
┌─────────────────────────────────────────────────────────────┐
│ 学習ロードマップ │
├─────────────────────────────────────────────────────────────┤
│ │
│ 基礎 │
│ ├── OLTP vs OLAP の違い(このページ) │
│ └── 列指向ストレージの仕組み │
│ └── なぜ集計が速いのか │
│ │
│ ClickHouse │
│ ├── アーキテクチャと特徴 │
│ │ └── Dremel, Colossus, 列指向, 圧縮 │
│ ├── SQL の違い(PostgreSQL との比較) │
│ │ └── 便利関数、テーブルエンジン │
│ └── データ投入パターン │
│ └── JDBC, CDC, Kafka, S3 ロード │
│ │
│ アーキテクチャ │
│ ├── OLTP + OLAP の組み合わせ設計 │
│ │ └── PostgreSQL + ClickHouse のデュアル構成 │
│ ├── データ連携パターン │
│ │ └── CDC (PeerDB), バッチ, デュアルライト │
│ └── AWS 上の構築パターン │
│ └── EKS, Cloud, BYOC │
│ │
│ 代替ツール │
│ ├── BigQuery / Redshift / Athena │
│ ├── OpenSearch / Elasticsearch │
│ └── TimescaleDB │
│ │
└─────────────────────────────────────────────────────────────┘
ドキュメント一覧
基礎
| # | ドキュメント | 説明 |
|---|---|---|
| 01 | 列指向ストレージと OLAP | なぜ集計が速いのか、行指向との違い |
ClickHouse
| # | ドキュメント | 説明 |
|---|---|---|
| 02 | ClickHouse 入門 | アーキテクチャ、テーブルエンジン、SQL |
| 03 | データ投入パターン | JDBC, CDC, Kafka, S3 ロード |
アーキテクチャ
| # | ドキュメント | 説明 |
|---|---|---|
| 04 | OLTP + OLAP デュアル構成 | PostgreSQL + ClickHouse の組み合わせ設計 |
| 05 | AWS 上の構築パターン | EKS, Cloud, BYOC, コスト比較 |
このセクションで学べること
判断力
| 問い | 答え |
|---|---|
| このクエリは PostgreSQL で返せるか? | データ量とクエリパターンで判断できる |
| 事前集計テーブルは必要か? | OLAP エンジンがあれば不要かもしれない |
| リアルタイム分析が必要か? | CDC vs バッチ vs アプリ直接書き込みの選択 |
設計力
| パターン | 使い分け |
|---|---|
| PostgreSQL のみ | 小規模、集計要件が限定的 |
| PostgreSQL + バッチ集計 | 中規模、翌日反映で十分 |
| PostgreSQL + ClickHouse | 大規模、リアルタイム分析が必要 |