読み書き経路、レイテンシ、一貫性、成長ニーズに基づいてデータベースを選ぶ実践ガイド。流行で技術的負債を増やさないための指針。

「流行っているから」という理由でデータベースを選ぶのは、皆が話題にしているから車を買うようなものです — スクーター、ピックアップ、バスのどれが必要かを確認せずに。トレンドは別のプロダクトのチームサイズ、予算、リスク許容度に合った結果を反映します。あなたのデータベースはあなたのワークロードに合う必要があります:アプリが実際に毎日何をしているか。
ワークロードは本番環境でのシステムの実際の振る舞いです:
これらの振る舞いがあなたのアクセスパターンです—アプリがデータに触れる繰り返しの方法を明確に説明できれば、データベース選びはずっとシンプルになります。
万能な解はほとんどありません。多くの成功しているシステムはハイブリッドアプローチを採ります:トランザクションに最適化されたデータベース、分析向けの別のデータベース、検索エンジンやキャッシュを専用に置くこともあります。これは「余分な複雑さ」ではなく、異なるアクセスパターンが異なるストレージやクエリエンジンから恩恵を受けることを認めた設計です。
「SQL vs NoSQL」を比較したり流行を追う前に、まず上位の5〜10件の読み/書きを書き出してください。そこから始めれば他は詳細に過ぎません。
アクセスパターンは、アプリが日常的にデータをどのように扱うかの実務的な記述です:何を読み、何を書き、どのくらいの頻度で、どの速度で、どのような形で。データが「何であるか」(注文やユーザー)ではなく、何を「するか」(「IDで注文を1万回/分取得する」や「先月の全注文をスキャンしてレポートを作る」)に注目します。
多くの読み取りは以下のバケットに当てはまります:
ソーシャルフィードは混合的な読み方の好例です:プロファイルはポイントルックアップ、最新投稿はレンジ読み、カウントは集計が必要になります。
書き込みパターンも重要です:
ログはしばしば「書き込み重視で追記のみ」(大量の挿入、更新は少ない)です。注文は通常「書き込み→更新」(作成後にステータス変更)になります。
多くのプロダクトは同時に全てを求めます:アプリのための高速ポイントルックアップ、サポートのための複雑なクエリ、分析のための大規模スキャン。1つのデータベースがいくつかの組み合わせをよく処理できる場合もありますが、ある組み合わせは互いにぶつかり合います—例えば解析スキャンがレイテンシ敏感な小さな読み取り(チェックアウトやフィード)を遅くすることがあります。
アクセスパターンを明確に言えると、流行ではなく実際の振る舞いでデータベースを評価できます。
ブランド比較をする前に、実際に提供しているワークロードを名付けてください。多くのプロダクトは「一つのワークロード」ではなく、いくつかの異なるワークロードが並んで存在します(時には競合します)。初期にこの分類を正しく行えば、本来最適化されていない仕事にデータベースを無理やり使わせることを防げます。
OLTPはほとんどのアプリの日々の心拍です:多数の小さな読み書き、同時ユーザー多数、そして速く終わることが求められるリクエスト。
考えてみてください:「カートを更新する」「注文を作成する」「住所を変更する」「在庫を確認する」。これらは短くターゲットが明確で、正確性が重要です。支払いが確定したなら消えてはならず、席が予約されたら二人に同じ席が割り当てられてはなりません。
OLTPは通常、高い同時実行を扱い、トランザクションやデータ整合性に関する明確な保証を提供するシステムに傾きます。
分析は作業の形状を反転させます:クエリは少ないが、各クエリがより多くのデータに触れます。
考えてみてください:「四半期ごとの地域別収益」「チャネル別コンバージョン」「カテゴリ別トップ商品」「日次アクティブユーザートレンド」。これらは多くの行をスキャンし、グループ化、集計、ソートします。レイテンシ期待は緩いことが多い(数秒で許容される)が、重いスキャンのコストは重要です—特にダッシュボードが一日中動く場合。
OLAPスタイルのスキャンをチェックアウトを支える同じシステムで走らせると、多くの場合どちらかが犠牲になります。
時系列とログは通常追記重視:新しいイベントが継続的に到着し、主に時間範囲でクエリされます。
考えてみてください:メトリクス、クリックストリーム、デバイステレメトリ、監査ログ。一般的なニーズは保持ポリシー(古いデータを削除/期限切れにする)、ロールアップ(生データは7日、集計は12か月保存など)、スパイク時の高速な書き込みです。
このワークロードは複雑な結合よりも、タイムスタンプ付きレコードを効率的に取り込み、時間とともにストレージを予測可能に保つことが重要になります。
検索は単に「行を見つける」ではありません。テキストマッチ、関連度スコア、部分一致、ユーザーフレンドリーなフィルタリングです。
考えてみてください:キーワードで商品を検索する、フレーズでチケットを探す、ファセット(ブランド、価格帯、色)で絞り込み、「ベストマッチ」でソートする。これらは専門的なインデックスやクエリ機能を必要とし、汎用データベースは近似できても得意にはなりません。
検索がコア機能なら、最初から独立したワークロードとして扱い、後回しにしないでください。
パフォーマンスは一つの数字ではありません。両方とも「速い」と言える2つのデータベースが、ユーザーや運用者にとって全く異なる感触を与えることがあります。適切な選択をするために、人間が感じるもの(レイテンシ)とシステムが持続しなければならない量(スループット)を分けて考え、スパイクで仮定を負荷試験してください。
レイテンシは単一リクエストにかかる時間 — 「ボタンを押して結果が返るまで」。ユーザーはレイテンシを直接感じます。
スループットは1秒あたりに処理できるリクエスト数 — システムが合計で扱えるトラフィック量。
あるDBはバッチ処理で高スループットを達成するが、個々のリクエスト遅延が目立つ場合があります。別のDBは高速なポイント読み取りに最適化されるが、多数の書き込みが同時に来ると苦手かもしれません。
平均レイテンシは痛みを隠します。99件が50msで終わり1件が2秒かかると、平均は良好に見えますが、その1%が「アプリが遅い」瞬間になります。
それがP99レイテンシの意味です:最も遅い1%のリクエストに要する時間。ユーザー向け機能(チェックアウト、ログイン、検索結果)では、P99がデータベース設計の判断基準になることが多いです。
ほとんどのシステムは平均トラフィックでは壊れません。壊れるのはピーク時です:マーケティングメール、速報、給与日、月末処理。
スパイクはデータベース設計の会話を変えます:
キャッシュは読み取り重視ワークロードを小さく見せます—キャッシュミスやパージまでは。多くの読み取りがキャッシュヒットだと、データベースは主に書き込みとたまの高コスト読みをさばくことになります。これは、全ての読み取りがデータベースに行く場合とは異なる選択を促します。コールドキャッシュ事象やミス時のテールレイテンシを想定しておくことが重要です。
データベース選びは速度だけで決まりません。何が間違って良いのか、どれだけのダウンタイムを許容できるか、ユーザーがどこにいるかも重要です。
まず、常に正確でなければならないデータを明記してください。支払い、口座残高、在庫数は典型例です。顧客が二重に課金されたり、在庫を過剰販売したりすると、遅いアプリ以上のコスト(返金、サポート、信頼喪失)が発生します。
これらには通常強い保証が必要です:書き込みは確認されてから完了、読者は途中状態を見ない、など。強い正確性は柔軟性を下げ、クロスリージョン書き込みを遅くするトレードオフがあります。
次に、データベースが5分間利用不可になったらどうなるかを決めてください。
ダウンタイムで「注文が止まり収益が止まる」なら、高可用性(自動フェイルオーバー、良いバックアップ、メンテでアプリを止めない設計)が必要です。一方で「内部ダッシュボードが遅れる」程度なら、シンプルな構成で受け入れられます。
高可用性は通常コストと運用複雑性を上げます(レプリカ増、監視強化、慎重なアップグレード)。投資をビジネスインパクトに合わせることが大切です。
ユーザーがほぼ一地域にいるなら、データを1箇所に置く方が安くて速いことが多いです。大陸横断でユーザーがいる、あるいはデータ所在地に関する規制がある場合はマルチリージョンのレプリケーションが必要になります。
マルチリージョンはユーザー体験と耐障害性を高めますが、厳しい選択を迫ります:読み取りを多少古く許容するか、書き込みを遅くして完全同期を保つか。正解はワークロードの耐性次第です。
多くの「データベース論争」は本質的にクエリ形状の議論です。アプリがどのような問いを投げる必要があるか(結合、集計、フィルタ、時間窓)を知れば、候補を素早く絞り込めます。
多対多の柔軟なフィルタや結合が必要で、要件が進化しそうならリレーショナルモデルが映えます(顧客→注文→商品など)。「Xを買ってYを返品した顧客を探す」ようなアドホックなレポートは、SQLと結合の方が長期的にシンプルです。
典型的なクエリが主キー中心(user_idでプロファイル取得)で予測可能なら、ドキュメントやキー・バリュー型が有効です。読み取り側で使う形にデータをまとめて保存することで高速化できますが、データ重複が増え、書き込み/更新が複雑になります。
インデックスはデータベースに「これが私のアクセスパターンだ」と伝える手段です。モックアップでは速そうに見えるクエリでも、インデックスがないと遅くなります。
役立つルール:頻繁に使うフィルタ、ソート、結合キーにはインデックス計画を用意する。ただしインデックスは無償ではなく、ストレージを使い、書き込みを重くします。
「速い書き込み」の主張は、二次インデックス、コンパクション、レプリケーション、複数コピーへのデータ更新による書き込み増幅を無視しがちです。読み取りを最適化するためにインデックスやデータ複製を増やす設計は、気づかないうちに高書き込みワークロードをボトルネックに変えます。
スキーマレスは構造がないことを意味しません。柔軟なスキーマは初期のイテレーションを早めますが、慣習がなければフィールドの不整合、デバッグ困難なクエリ、後の高コストなマイグレーションを生みます。多チーム、多機能、長期保持が予想される場合、より厳密なスキーマと制約がトータルコストを下げることが多いです。
人気でデータベースを選ぶと、運用の地味な部分で裏目に出ることが多いです:稼働維持、安全確保、月々の支払い。機能要件が同じでも、運用負担や総所有コストは大きく異なります。
誰が深夜2時にこのシステムを運用するのかを早めに尋ねてください。バックアップ、ポイントインタイムリカバリ、アップグレード、パッチ適用、フェイルオーバー訓練、監視は「後でやる」仕事ではなくリスクと人員配置を決めます。
マネージドサービスは作業を減らしますが、完全に無くすわけではありません。定期的なコンパクションやチューニング、深い専門知識がないと回避できない遅延を招くシステムもあります。チームが小さければ、運用が容易なデータベースが紙上の“完璧”より勝つことがあります。
データベースのコストは通常以下に由来します:
書き込みや二次インデックスが多いアクセスパターンは、データセットが小さくてもI/Oやストレージを何倍にもすることがあります。
独自のクエリ言語、特殊な一貫性機能、サーバーレスの“おまじない”は初期導入を早めますが、将来の移行を難しくします。データをエクスポートできるか、ローカルでテストできるか、プロバイダを切り替える際にアプリの書き直しが必要かを考慮してください。
最低限確認すべきは通信中/保存時の暗号化、キー管理、監査、アクセス制御、保持ポリシーです。コンプライアンス要件はしばしば「動作する」か「受け入れ可能」かを決めます。
アクセスパターンを(何を読むか、何を書き込むか、どの頻度で、どんなスパイクの下で)記述すれば、適切なデータベースファミリーは自然と見えてきます。目的は最も人気のあるツールを選ぶことではなく、ワークロード下で正しさを保てる最も単純なシステムを選ぶことです。
強い一貫性、明確な関係性、信頼できるトランザクションが必要ならリレーショナルを選んでください—注文、支払い、在庫、権限、スケジューリングなど。複数エンティティを跨いだ柔軟なフィルタや結合が頻繁に発生する場合、SQLはアプリの複雑さを下げる傾向があります。
ひとつの目安:チームが結合、制約、トランザクションをコードで再実装しようとしているなら、多分リレーショナルが適しています。
ドキュメントDBは、構造が変化し得るオブジェクト(ユーザープロファイル、コンテンツページ、オプションフィールドのある製品カタログ、設定など)を丸ごと読み書きする場合に最適です。典型的なクエリが「user_idでプロファイルを取得」し、一部を更新するようなものであれば、ドキュメントは使用するデータを一箇所にまとめられます。
多くのクロスドキュメントクエリやマルチエンティティのトランザクション保証が必要な場合は注意が必要です。
キャッシュ、セッション、レート制限、フィーチャーフラグ、短命状態など「キーでget/set」し、レイテンシが重要な用途に向きます。主にレコードの補助に使われることが多く、一次の信頼できるソースとしては補完的な役割です。
永続的な業務データを保存する場合は、排出(eviction)や再起動、レプリケーション遅延時にどうなるかを考えてください。
分析やダッシュボード、コホートや収益集計など長期間にわたるグループ化クエリにはカラムナ型やウェアハウスが有利です。大量の行を効率的にスキャン・集計するよう最適化されています。
実務的な分離:OLTPは一次データベースに残し、レポート用にウェアハウスへ流す。こうすることで顧客向けクエリがBIによって遅くなるのを避けられます。
多くの成功するプロダクトは「データベースを1つに決める」わけではありません。主要な各アクセスパターンに対して最も単純なストレージを割り当て、場合によっては2〜3のデータベースを並行して使います。
オンラインストアはしばしば三つの非常に異なるワークロードを持ちます:
プロダクトは統一感を保ちながら、アクセスパターンごとに専門化されたストレージを使うのが普通です。
B2B SaaSはコアエンティティ(プロジェクト、請求書、チケット)をトランザクショナルDBに置きつつ、次を必要とします:
IoTプラットフォームはテレメトリをバースト的に取り込み、時間窓のダッシュボードで読み返します。
一般的な分割は:最近データ向けの高速取り込みストア、長期保持用の安価なストレージ、集計用の分析エンジン。アクセスパターンが分岐したら、それぞれに適したDBを選ぶのが鍵です。
データベースのミスマッチは小さな修正が積み重なる形で現れます。チームがデータベースと戦う時間が機能開発より長くなっていれば注意が必要です—多くはアクセスパターンの問題で、チューニングでは解決しません。
よく見られる警告サイン:
通常業務を支えるために人海戦術が必要なデータベースは、ワークロードとDBファミリーが合致していない可能性が高いです。
流行で選ぶと長期コストが来ます:
スケールや要件が変わったときに請求書が届き、現実的な解決は痛みを伴う再プラットフォームになります。
完璧な可観測性は不要ですが、いくつかのシグナルは必要です:
上位のアクセスパターン(読み/書き、主要クエリ、ピークレート)、データ量の想定、そして「非交渉事項」(一貫性、可用性、地域制約)を書き留めてください。ダッシュボードへのリンクや最悪ケースのクエリ例を添えると、将来の判断が速くなり、データベースが現実に合わなくなったときに気付きやすくなります。
データベース選定は“人気コンテスト”ではなく要件定義です。このチェックリストを使って「スケーラブルな何かが必要」という曖昧さを具体化してください。
まず平易な言葉で答え、その後可能なら数値を入れます:
評価基準を左に、候補を上に並べた1ページ表を作り、各基準を必須かあると良いか付け、候補を(例0–2で)採点します。
最低限に含める項目:クエリ適合性、スケーリング方針、一貫性要件、運用負荷、エコシステム/ツール、コスト予測可能性。
代表的なデータと実際のクエリで試験してください(おもちゃの例ではない)。上位クエリを再現し、実際の書き込みパターン(スパイク含む)を走らせます。
もしプロダクトの検証を高速に回したいなら、Koder.aiのようなvibe-coding環境でReactフロントエンドとGo+PostgreSQLバックエンドを素早く立ち上げ、上位5つのクエリがどのように振る舞うかを測定してから長期アーキテクチャを決めるのも有効です。ソースコードをエクスポートでき、スキーマやマイグレーションを自分で管理できる点も後戻りを避けるのに役立ちます。
「合格」が何を意味するかを事前に書き出してください:レイテンシ目標、許容エラー率、必要な運用手順(バックアップ、スキーマ変更)、予想月額費用。PoCで必須条件を満たさない候補は早めに切りましょう。
将来に備えることは、初日から「最もスケーラブルな」データベースを選ぶことではありません。アクセスパターンが変わったときに柔軟でいられるよう、意図的な選択をすることです。
ワークロードが主にトランザクショナルな読み書きで単純なクエリなら、リレーショナルDBがしばしば最速で確実な道です。目的は確実にローンチすること:予測可能な性能、明確な正確性保証、チームが既に理解しているツール。
ここでの「将来対応」とは、早期に取り返しのつかない選択(特化ストアの採用)を避けることです。
データアクセス層(またはサービス境界)を明確に作り、アプリの残りがDB固有のクセに依存しないようにします。クエリロジックを集中管理し、入力/出力の契約を定義し、スキーマ変更を通常の開発活動として扱ってください。
後のマイグレーションを容易にする実践:
多くのプロダクトは最終的に二つの道を必要とします:日々のトランザクション向けのOLTPと、レポーティングや実験のための分析。分析クエリが本番レイテンシを害し始めたら、または保持/パーティショニング要件が異なるなら分離を検討してください。
両者を整合させるために、イベント/データ定義を標準化し、パイプラインを自動化し、システム間で合計値(日次売上など)を突き合わせる仕組みを作って“真実”が分散しないようにします。
具体的な次のステップを望むなら、チームで使える軽量のマイグレーション計画テンプレートを作ってください:/blog/database-migration-checklist。
アクセスパターンとは、本番環境でアプリがデータに触れる繰り返しの方法です。何を読み書きするか、どの頻度で、どれくらいの速度で、どのようなクエリ形状か(ポイントルックアップ、範囲スキャン、結合、集計、時間窓など)を表します。「ユーザーと注文がある」よりも実務的で、インデックス設計、スキーマ選択、データベース適合性に直接結びつきます。
“人気”は他チームの制約や背景を反映しているだけで、あなたのワークロードに最適とは限りません。同じデータベースがあるワークロード(例:OLTP)では素晴らしく、別のワークロード(重い分析スキャン)では扱いにくいことがあります。まずは上位の5〜10個の読み書きを列挙し、それらの振る舞いに基づいて評価してください。ブランドや流行に引きずられるべきではありません。
まず書き留めるべき項目:
これがオプション比較のための要件ドキュメントになります。
OLTPは多数の小さな同時読み書きで、正確性が重要な操作(チェックアウト、在庫更新、アカウント変更など)です。トランザクションや制約が重要になります。
OLAP/分析は大規模データに触れる少数のクエリ(スキャン、グループ化、集計)が中心で、秒単位のレイテンシが許容されることも多いです。
両者を同一システムで混在させると、分析クエリがユーザー向けレイテンシを悪化させることがよくあります。
平均ではなくp95/p99を確認してください。99%のリクエストが50msで返り、残り1%が2秒掛かると、平均は良く見えてもユーザー体験は悪くなります。重要なエンドポイント(ログイン、チェックアウト、検索など)のp95/p99を追い、データベースのロックやレプリケーション遅延、I/O飽和と相関させて監視するのが実務的な対処です。
多くの場合、それぞれの要件(OLTPの低レイテンシ、分析の大規模スキャン、検索の全文照合)は競合します。
専門化したストアを併用する方が、1つのDBに無理やり詰め込むより全体としてシンプルになることが多いです。
キャッシュにより通常の読み取り負荷が隠れると、実際の負荷は書き込み+キャッシュミス時の高コスト読みになります。設計上考慮すべき点:
キャッシュは問題を一時的に覆い隠すことがありますが、ミス時にデータベースを圧倒するクリフエッジを生む可能性があります。
強い正確性は、トランザクションと更新可視性の保証(半端な状態を読ませないなど)を意味します。支払い、残高、在庫、予約などは“絶対に間違ってはいけない”データの典型例です。トレードオフとして:
どのデータが“決して間違ってはならない”かを明確に定義してください。
インデックスはワークロードとDBの間の性能契約です。頻繁に使う以下にはインデックス計画を用意してください:
ただしインデックスはストレージを消費し、書き込みを重くする(書き込み増幅)ので、実際によく行うことだけをインデックス化するのが目標です。
PoCは小さな本番リハーサルと考えてください:
PoCで必須要件を満たせない候補は早めに切ってください。