Upgrade to Pro — share decks privately, control downloads, hide ads and more …

DBを選定する際のポイントをパッと言えない人全員集合

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.

 DBを選定する際のポイントをパッと言えない人全員集合

DB選択の「なぜ」を持つ — データ指向アプリケーションデザイン 第2章をもとに、「なんとなく選ぶ」から「なぜを持って選ぶ」への変化を目指すスライド。ひまじんプログラマーの週末エンジニアリングレッスンのPodcastの原稿用のスライド。

Avatar for 飯田嘉一郎

飯田嘉一郎

May 10, 2026

More Decks by 飯田嘉一郎

Other Decks in Programming

Transcript

  1. ANTI-PATTERN · よくある選び方 こんな理由でDB選んでませんか? ? 「スキーマレスだから MongoDB にした」 → 本当に必要だったのはスキーマの柔軟性?それとも…

    ? 「パフォーマンスが求められるから MongoDB にした」 → パフォーマンスの課題はDBの種類で解決する問題? ? 「スキーマがあるから MySQL にした」 → スキーマは「あるか・ないか」ではなく「どこでチェックするか」の違い これらは全て、データの形を見る前に結論を出している。今日はその判断基準を根本 から整理する。 3
  2. TODAY'S REFERENCE 今日参考にする書籍 データ指向アプリケーションデザイン Designing Data-Intensive Applications 著者: Martin Kleppmann

    / オライリー・ ジャパン 一言で言うと データを扱うシステムを正しく設計・構 築・運用するための原理原則を学ぶバイ ブル。 バックエンドエンジニア・アーキテクト 必読の1冊。 今日扱う範囲 第2章「データモデルとクエリ言語」— どのデータモデルがどんな用途に向いている か 5
  3. BOOK OVERVIEW · この本で学ぶこと 「データ指向」って何?この本で何が得られる? データ指向とは システムのボトルネックがCPUではなく 「データ」にある現代のアプリ設計思 想。 データ量・複雑さ・変化速度を制御する

    ため、信頼性・スケーラビリティ・メン テナビリティを軸に設計する。 本書の構成(3部構成) Part 1:データシステムの基礎(DB・レプリケ ーション・パーティション) Part 2:分散データ(一貫性・合意・トランザ クション) Part 3:派生データ(バッチ・ストリーム処 理) ✓ DBの内部構造・トレードオフを理解し、 「なぜそのDBを選ぶか」を根拠を持って説明できる ✓ 分散システムの落とし穴(CAP・一貫性モデル)を把握し、障害に強いアーキテクチャを設計で きる 6
  4. TODAY'S SCOPE 第2章で扱うトピック 歴史・経緯 なぜRDBが生まれたか なぜNoSQLが生まれたか 歴史の繰り返し 2つのデータモデル ドキュメントDB リレーショナルDB

    選び方の軸 1対多 vs 多対多 スキーマの考え方 データの局所性 📖 データ指向アプリケーションデザイン 第2章 pp.27–63 7
  5. SCOPE · 第2章の範囲 第2章が扱うこと・扱わないこと ✅ 第2章のスコープ(今日話す内容) データモデルの違い(ドキュメント・リレーシ ョナル) クエリ言語の違い(SQL・MapReduce) スキーマの考え方(オンライト・オンリード)

    データの局所性(locality) ⚠️ 第2章では扱わない(別章のテーマ) 耐障害性・レプリケーション → 第5〜6章 並行処理・トランザクション(ACID) → 第7章 クエリのパフォーマンス最適化 → 第3章 分散システムの信頼性 → 第8〜9章 このスライドは第2章「データモデル」の範囲に絞ります。耐障害性・並行処理につ いては末尾に参考情報として掲載しています。 📖 データ指向アプリケーションデザイン 第2章(スコープ確認) 8
  6. AGENDA 今日の構成 1 歴史・経緯 — なぜ今のDBがあるか(IMS → CODASYL → Relational

    → NoSQL) 2 2つのデータモデルを比較する — ドキュメント・リレーショナルの違いと選び方 3 かいちの失敗談 — データの形を無視した結果、何が起きたか 4 DB選択フレームワーク — 判断軸を手に入れて「なぜ」を持つ 9
  7. TODAY'S ROADMAP 今日のロードマップ GOAL :自分のシステムのDB選択を1文で説明できるようになる 1 歴史・経緯 なぜ今のDBがこの形になったかを知る → 現代の技術選択に「意味」が見えてくる

    2 2つのデータモデルを比較する ドキュメント・リレーショナルの違いを掴む → 比較の軸が手に入る 3 失敗談 データの形を無視した実体験 → 「なぜ選ぶか」の重要性を自分ごと化する 4 DB選択フレームワーク 判断軸を手に入れ、 「なぜ」を持って選べるようになる → GOAL 達成 10
  8. PART 1 / 4 歴史・経緯 なぜ今のDBがこの形になったかを理解する 1 歴史・経緯 → 現代の技術選択に「意味」が見えてくる

    ← 今ここ GOAL :DB選択を1文で説明できるようになる 2 データモデル → 3つのモデルの違いと選び方を知る 3 失敗談 → 「なぜ選ぶか」の重要性を自分ごと化する 4 フレームワーク → 判断軸を手に入れる → GOAL 11
  9. WHY IT MATTERS データモデルは「世界の見方」を決める 「データモデルはソフトウェアを開発する際だけでなく、 解決しようとしている問題の考え方にまで影響を与えます」 — データ指向アプリケーションデザイン 第2章 モデルが「設計の起点」になる

    「どうデータを持つか」の判断が、その 後の設計・実装・パフォーマンス全てに 影響する。 「なんとなく」が積み重なると… 最初の判断の影響が、機能追加のたびに 複利で大きくなっていく。 📖 データ指向アプリケーションデザイン 第2章 p.27 12
  10. HISTORY データモデルの歴史 — 60年の流れ 1968 IMS(IBM) — 階層型モデル。アポロ計画のデータ管理から生まれた。1対多のみ対応。 1969〜 CODASYL

    — ネットワーク型モデル。多対多を扱えるようにした。しかし複雑すぎた。 1970 リレーショナルモデル(Codd) — 「格納方法を知らなくていい」革命。クエリオプティマイザ の登場。 1980〜90s RDBMS全盛期 — Oracle, MySQL, PostgreSQL。業界標準として40年君臨。 2010s〜 NoSQL台頭 — MongoDB, Cassandra, Neo4j。スケール・柔軟性・特殊クエリへの需要から。 📖 データ指向アプリケーションデザイン 第2章 pp.34–42 13
  11. HISTORY · 1968 IMS — 階層型モデルの誕生 背景 IBM がアポロ計画の部品表管理のために開発 膨大な数の宇宙船部品を階層的に管理

    当時最先端のデータ管理システム 構造 製品 ├─ エンジン │ ├─ 燃料ポンプ │ └─ バルブ └─ 外装パネル 🔍 アナロジー:家系図(祖父→父→子) 。1方向の親子関係しか表現できない。 📖 データ指向アプリケーションデザイン 第2章 pp.34–36 14
  12. HISTORY · IMS の限界 多対多が表現できない 問題:「この部品は複数の製品で使われている」— ツリー構造では表現できない 解決策A:非正規化 同じ部品データを複数の場所にコピーす る。

    → 整合性の問題:片方を更新すると他方 と食い違う 解決策B:手動参照 アプリ側で複数のクエリを発行してデー タを組み立てる。 → コードが複雑化:機能が増えるほど悪 化 ⚠️ この問題は現代のドキュメントDBでも全く同じ形で起きる 📖 データ指向アプリケーションデザイン 第2章 pp.36–37 15
  13. HISTORY · 1969〜 CODASYL — ネットワーク型への挑戦と失敗 解決しようとしたこと IMSの多対多の問題を解決 ポインタのチェーンでデータをナビゲート 多対多の関係をDBレベルで表現

    🔍 アナロジー:ハードコードされた迷路。出 口までの道順を事前に宣言する必要がある。 なぜ失敗したか アクセスパスの事前宣言が必要 データ構造が変わると→アプリ全体も書き直し 複雑すぎてプログラマーが苦労 普及せず、事実上消えた 📖 データ指向アプリケーションデザイン 第2章 pp.37–39 16
  14. HISTORY · 1970 Edgar F. Codd の革命 革命的なアイデア 「データをどこにどう格納するかを、ユーザーは知らなくていい」 クエリオプティマイザがDBの内部で最適なアクセスパスを選ぶ。

    CODASYL との違い CODASYL: アクセスパスを手動で辿る Relational: SELECTを書けばDBが最適化 新しいクエリを追加してもコード変更不要 アナロジー 図書館で: ❌ 棚の位置を全部覚えて自分で探す (CODASYL) ✅ 司書に「◦◦の本が欲しい」と伝える (Relational) 📖 データ指向アプリケーションデザイン 第2章 pp.39–40 17
  15. HISTORY · なぜ40年間君臨できたか リレーショナルが勝った理由 1 アクセスパスを覚えなくていい — 開発効率が劇的に向上 2 汎用性が高い

    — 1対多も多対多も、JOINで全て扱える 3 クエリオプティマイザが賢くなる — ハードウェアの進化と共に自動的に高速化 4 トランザクション・ACID — 信頼性の高いデータ操作を保証 📖 データ指向アプリケーションデザイン 第2章 pp.40–42 18
  16. QUERY LANGUAGES · 宣言的 VS 命令的 SQLが「宣言的」であることの革命 命令的(Imperative)— How 「どうやって処理するか」をステップで

    指定する。 // MapReduce(命令的) db.animals.mapReduce( function map() { if (this.family === "Sharks") emit(this.family, 1); }, function reduce(k, v) { return Array.sum(v); } ); 宣言的(Declarative)— What 「何が欲しいか」だけを伝える。どう取 るかはDBが決める。 -- SQL(宣言的) SELECT family, COUNT(*) FROM animals WHERE family = 'Sharks' GROUP BY family; 同じ結果を、より簡潔に記述できる。 19
  17. QUERY LANGUAGES · 宣言的クエリのメリット 宣言的だとDBエンジンが賢くなれる 1 DBが最適な実行計画を選べる インデックスの使い方・JOINの順序をクエリオプティマイザが自動選択。アプリを変えずにパフォ ーマンスが上がる。 2

    並列実行がしやすい 「どの順序で処理するか」を指定していないので、DBが並列処理を自由に選択できる。 3 コードが短くなる MapReduceでは数十行かかる処理が、SQLなら数行で書ける。可読性・保守性が上がる。 🔍 アナロジー:タクシーに「〇〇ホテルまで」と言う(宣言的)vs「この道を左に曲がって、次を右に…」 と指示する(命令的) 📖 データ指向アプリケーションデザイン 第2章 pp.47–49 20
  18. HISTORY · 2010S なぜNoSQLが生まれたか NoSQL が生まれた背景 Webスケール:Google・Amazon規模のデータ 量へ対応 スキーマの柔軟性:仕様変更の多いスタートア ップのニーズ

    特殊なクエリ:グラフ解析・全文検索など オープンソース:RDBMSのライセンスコストを 回避 4つのカテゴリ ドキュメント:MongoDB, CouchDB キーバリュー:Redis, DynamoDB グラフ:Neo4j カラム:Cassandra, HBase RDB vs NoSQL は「どちらが優れているか」ではなく「いつどちらを選ぶか」の問い 📖 データ指向アプリケーションデザイン 第2章 pp.29–30 21
  19. PART 2 / 4 データモデルを理解する 2つのモデルの違いと、選ぶ軸を知る 2 データモデル → 2つのモデルの違いと選び方を知る

    ← 今ここ GOAL :DB選択を1文で説明できるようになる 1 歴史・経緯 → 現代の技術選択に「意味」が見えてくる ✓ 3 失敗談 → 「なぜ選ぶか」の重要性を自分ごと化する 4 フレームワーク → 判断軸を手に入れる → GOAL 22
  20. BASICS · インピーダンスミスマッチ OOPとRDBのギャップ OOPの世界 class User { String name;

    List<Position> positions; List<Education> education; } RDBの世界 users テーブル positions テーブル educations テーブル → JOINで組み合わせる 🔍 アナロジー:英語の契約書を日本語に翻訳するコスト。ORMがこの翻訳を担うが、完璧ではない(N+1 問題など) 。 ドキュメントDBはオブジェクトとJSONの構造が近いため、このギャップが小さい。 📖 データ指向アプリケーションデザイン 第2章 pp.30–32 23
  21. DATA MODEL · ドキュメント ドキュメントモデル 特徴 JSON / XML で表現

    関連データを1ドキュメントにまとめる 1回のクエリで全データ取得(locality が高い) スキーマ変更が柔軟 向いているデータの形 ユーザー ├─ 職歴 ×N ├─ 学歴 ×N └─ 連絡先 1対多のツリー構造が中心のデータ 🔍 アナロジー:書類ケース(ファイリングキャビネット)— 案件ごとに関連書類を1フォルダにまとめ る。全部まとめて取り出せる。 📖 データ指向アプリケーションデザイン 第2章 pp.32–34 24
  22. DOCUMENT DB · 設計の判断 ドキュメントDB設計の決断:埋め込む vs 参照する 埋め込む(Embedding) { "user_id":

    1, "name": "太郎", "address": { "city": "Tokyo", "zip": "100-0001" } // ← address を直接埋め込む } ✅ 1クエリで全データ取得 ⚠️ 同じデータを複数箇所に持つと整合性 問題 参照(Reference) { "user_id": 1, "name": "太郎", "address_id": "addr_42" // ← IDだけ持ち、アプリでJOIN } ✅ データの一元管理、整合性が高い ⚠️ 複数クエリが必要(アプリ側JOIN) 25
  23. DATA MODEL · リレーショナル リレーショナルモデル 特徴 テーブル・行・列で表現 同じデータは1箇所だけに持つ(正規化) JOINで多様な組み合わせが可能 トランザクション・ACID保証

    向いているデータの形 ユーザーA ─── 会社X ユーザーB ─── 会社X ユーザーB ─── 会社Y ユーザーC ─── 会社Y 多対多が絡むデータ 🔍 アナロジー:正規化された図書館 — 同じ情報は1箇所だけ。貸出記録と書籍情報は分けて管理し、JOIN (照合)して使う。 📖 データ指向アプリケーションデザイン 第2章 pp.34–42 26
  24. DESIGN · 正規化 VS 非正規化 正規化 vs 非正規化 のトレードオフ 正規化(Normalized)

    非正規化(Denormalized) やること 同じ情報を1箇所だけに持つ 同じ情報を複数箇所にコピー 読み取り JOINが必要 → やや遅い 1回のクエリで全データ取得 → 速い 更新 1箇所を変えるだけ → 簡単 全コピーを同期する必要 → 複雑 整合性 高い(矛盾が起きない) 低い(更新漏れで矛盾が起きうる) 向き先 書き込みが多いデータ 読み取りが多いデータ 🔍 アナロジー:正規化 = DRY原則(同じことを1箇所だけに書く) 。非正規化 = キャッシュ(速くなるが、 鮮度管理が必要) 。 📖 データ指向アプリケーションデザイン 第2章 pp.33–34 27
  25. DESIGN · スキーマ変更 スキーマ変更(マイグレーション)の現実 RDB:スキーマオンライト -- 新しい列を追加する ALTER TABLE users

    ADD COLUMN first_name TEXT; -- 既存データを埋める UPDATE users SET first_name = split_part(name,' ',1); 大規模テーブルでは ALTER TABLE が 数分〜数時間かかることも。 28
  26. ANALOGY · ゲームで理解する RPGで覚えるデータモデルの違い 🗡️ ドキュメントDB = 一人用RPGのセーブデータ 主人公データ(1ファイル) ├─

    HP / MP ├─ 所持アイテム × N ├─ 習得スキル × N └─ クエスト進捗 × N → 自己完結。1ファイルで完結する1対 多ツリー ⚔️ リレーショナルDB = MMORPGのコアDB(取引・アイテム 管理) players ←→ guilds players ←→ items(取引) guilds ←→ quests players ←→ players(フレンド) → 多対多が絡み合う。JOINで関係を取 り出す データが自己完結か・絡み合うか → これがモデル選択の直感 29
  27. COMPARISON · 1対多のデータ 1対多ツリー → ドキュメントDBが輝く 例:LinkedInのプロフィール(DDIAで使われている実例) データの形 1人のユーザー ├─

    職歴 × N ├─ 学歴 × N └─ 連絡先 データが自己完結している。まとめて1 回で読み出す。 ドキュメントDBのメリット 全体を1回のクエリで取得 テーブル結合が不要 スキーマ変更が容易 オブジェクトとの対応が自然 📖 データ指向アプリケーションデザイン 第2章 pp.32–34 30
  28. COMPARISON · JSON の例 ドキュメントDB:1つのJSONに全部入る { "user_id": 251, "name": "Bill

    Gates", "positions": [ { "title": "Co-chair", "org": "Bill & Melinda Gates Foundation" }, { "title": "Chairman", "org": "Microsoft" } ], "education": [ { "school": "Harvard University", "end_year": 1975 } ], "contact": { "twitter": "@BillGates" } } → 1クエリでプロフィール全体が取得できる。結合なし。 📖 データ指向アプリケーションデザイン 第2章 pp.31–32 31
  29. COMPARISON · RDB の場合 RDB:複数テーブルに分散し、JOINで結合 -- テーブル定義 CREATE TABLE users

    (id, name, summary); CREATE TABLE positions (id, user_id, title, org); CREATE TABLE educations (id, user_id, school, end_year); CREATE TABLE contacts (id, user_id, twitter); -- プロフィール取得 SELECT u.name, p.title, p.org, e.school FROM users u JOIN positions p ON p.user_id = u.id JOIN educations e ON e.user_id = u.id WHERE u.id = 251; 32
  30. COMPARISON · 多対多のデータ 多対多が出た途端、ドキュメントDBは詰む 「この会社で働いたことがある人全員にニュースフィードを出したい」 ドキュメントDBの問題 DBが結合をサポートしない アプリ側で複数回クエリ → コード複雑化

    非正規化すると整合性コードがアプリに溜まる 歴史との対応 これは1968年のIMSが直面した問題と全 く同じ。 リレーショナルモデルはこの問題を解決 するために登場した。 📖 データ指向アプリケーションデザイン 第2章 pp.37–39 33
  31. COMPARISON · RDBの弱点 RDBが苦手とする3つのケース 万能ではない。以下のケースでは別のモデルが有利になる 🌲 深いツリー構造 フォルダ階層・コメント スレッドなど、再帰的な1 対多

    再帰JOIN(WITH RECURSIVE)が必要で 複雑化。 ドキュメントDBはネ ストで自然に表現でき る 🔧 頻繁なスキーマ変更 スタートアップ初期・仕 様が固まっていないフェ ーズ ALTER TABLEは大きな テーブルでは数分〜数 時間かかる。 スキーマオンリードな ら無停止で変更できる ⚡ シンプルなKVアクセス セッション管理・キャッ シュ・一時データ パーサ・クエリプラン ナのオーバーヘッドが 無駄。 Redis等のKVSが圧倒 的に速い 34
  32. COMPARISON · スキーマの考え方 「スキーマレス」は誤解を招く言葉 スキーマがないのではなく、いつチェックするかが違うだけ スキーマオンライト スキーマオンリード 代表例 リレーショナルDB ドキュメントDB

    チェック 書き込み時にDBが強制 読み取り時にアプリが解釈 類比 静的型付け(コンパイル時) 動的型付け(実行時) 複雑さの場所 スキーマ定義・マイグレーション アプリ側のハンドリングコード 📖 データ指向アプリケーションデザイン 第2章 pp.44–46 35
  33. COMPARISON · アナロジー スキーマ = 型チェックの「タイミング」の違い スキーマオンライト(静的型付け) コンパイル時にエラー検出(Go, Java) 間違いが早期発見できる

    型定義という「設計図」を事前に書く 変更コストは高いが、安全 スキーマオンリード(動的型付け) 実行時に型チェック(Python, JavaScript) 柔軟に変更できる 「このフィールドはある?」とアプリが確認 確認漏れは実行時エラーになる 「スキーマレス=自由」ではなく、「整合性の責任をアプリが負う」ということ。複 雑さは消えず、場所が変わる。 📖 データ指向アプリケーションデザイン 第2章 pp.44–46 36
  34. COMPARISON · データの局所性 ドキュメントDBのメリット:locality(局所性) locality が高い = 読み取りが速い 関連データがディスク上の1箇所にまと まっている。

    → プロフィール全体を読むなら1回のI/O で完結。 ただしトレードオフがある ドキュメントの一部だけ更新→全体を書き直す ドキュメントが大きくなるほどコスト増 一部だけ読みたい場合も全体をロード 🔍 アナロジー:引き出しに全部まとめて入れる ↔ ファイルが増えると引き出しが重くなる。 「まとめ方」 はデータの読み方に合わせる。 📖 データ指向アプリケーションデザイン 第2章 pp.43–44 37
  35. COMPARISON · まとめ ドキュメント vs リレーショナル 比較 ドキュメントDB リレーショナルDB 得意な構造

    1対多ツリー 多対多・複雑な結合 スキーマ オンリード(柔軟) オンライト(厳格) 局所性 高い(1クエリ) 低い(JOIN必要) 結合 アプリ側で処理 DB側でサポート 代表 MongoDB PostgreSQL, MySQL 📖 データ指向アプリケーションデザイン 第2章 pp.32–46 38
  36. PART 3 / 4 失敗談 データの形を無視した実体験から学ぶ 3 失敗談 → 「なぜ選ぶか」の重要性を自分ごと化する

    ← 今ここ GOAL :DB選択を1文で説明できるようになる 1 歴史・経緯 → 現代の技術選択に「意味」が見えてくる ✓ 2 データモデル → 3つのモデルの違いと選び方を知る ✓ 4 フレームワーク → 判断軸を手に入れる → GOAL 39
  37. PERSONAL STORY · パターンA パターンA:データが絡み始めた 何が起きたか 最初は独立していたドキュメントが、機能追加のたびに「あのドキュメントも参照し たい」という要求が増えていった。 // 最初はシンプルだった

    const user = await User.findById(userId); // 機能追加のたびにクエリが増える const user = await User.findById(userId); const orders = await Order.find({ userId }); const products = await Product.find({ _id: { $in: orders.map(o => o.productId) } }); 41
  38. PERSONAL STORY · パターンB パターンB:整合性コードが溜まった 何が起きたか 同じ情報を複数のドキュメントに持つ非正規化をしたため、更新時に全ての場所を同 期する必要が生まれた。 // 会社名を変更するだけなのに…

    async function updateCompanyName(companyId, newName) { await Company.updateOne({ _id: companyId }, { name: newName }); // 非正規化しているので、全参照先も更新が必要 await User.updateMany({ companyId }, { companyName: newName }); await Post.updateMany({ companyId }, { companyName: newName }); await Event.updateMany({ companyId }, { companyName: newName }); // 更新漏れが起きると → データ不整合 } 「スキーマレス=自由」ではなく、整合性の責任がアプリに移転していただけ 42
  39. AHA MOMENT ぼくは1968年と同じ問題にはまっていた 1968年 · IMS の開発者 階層型モデルでシステムを設計 多対多が出てきて詰んだ 「非正規化か手動参照か」を迫られた

    整合性コードがアプリに溜まった 2020年代 · ぼく ドキュメントDBでシステムを設計 多対多が出てきて詰んだ 「非正規化か手動クエリか」を迫られた 整合性コードがアプリに溜まった 技術は変わる。本質は変わらない。 歴史を知ることで、同じ失敗を繰り返さずに済む。 📖 データ指向アプリケーションデザイン 第2章 pp.36–37 43
  40. ADVANCED · ポリグロットパーシステンス 1つのシステムで複数のDBを使い分けていい PostgreSQL (RDB) ユーザー情報、注文、決 済など多対多が絡む業務 データ Redis

    (KVS) セッション、キャッシ ュ、リアルタイムランキ ングなど高速読み書き Elasticsearch 全文検索、ログ解析な ど、RDBが苦手な検索ク エリ ただし運用コストは増える(監視・バックアップ・チームのスキルセット) 。 「でき る」と「すべき」は別の話。 📖 データ指向アプリケーションデザイン 第2章 pp.29–30 44
  41. PART 4 / 4 DB選択フレームワーク 「なぜ」を持って選べるようになる → GOAL達成 4 フレームワーク

    → 判断軸を手に入れる → GOAL ← 今ここ GOAL :DB選択を1文で説明できるようになる 1 歴史・経緯 → 現代の技術選択に「意味」が見えてくる ✓ 2 データモデル → 3つのモデルの違いと選び方を知る ✓ 3 失敗談 → 「なぜ選ぶか」の重要性を自分ごと化する ✓ 45
  42. FRAMEWORK DB選択の判断フレームワーク Step 1:データの関係を図に書く ER図でも手書きでも。 「どのデータがどのデータに紐づくか」を可視化する。 Step 2:1対多か、多対多かを確認する 1対多ツリーが中心 →

    ドキュメントDB(MongoDB等)が候補 多対多が出てくる → リレーショナルDBが候補 Step 3:「なぜ」を1文で言えるか確認する 「このシステムのデータは◦◦な形なので、△△DBを選んだ」と言えれば合格。 47
  43. SUMMARY 今日の学び 1 データの形で選ぶ 1対多ツリーが中心 → ドキュメントDB。多対多が絡む → リレーショナルDB。 「なんとなく」から

    脱却する。 2 「スキーマレス=自由」ではない スキーマのチェックをアプリ側に移しているだけ。整合性の複雑さは消えず、場所が変わる。 3 歴史は繰り返す IMSが1968年に直面した問題は、現代のドキュメントDBでも同じ形で起きる。歴史を知ることが最 大の武器。 48
  44. REFERENCE · 耐障害性(DDIA 第5〜6章) 参考:耐障害性の違い ⚠️ これは第2章のスコープ外です。第5〜6章(レプリケーション・パーティショニング) のテーマです。 MongoDB —

    Replica Set Primary + Secondary × N の構成 Primary 障害時に自動フェイルオーバー(選挙 で新 Primary を選出) Write Concern で書き込み確認の強度を調整 Read Preference で Secondary からの読み取り も可能 RDB(PostgreSQL / MySQL) ストリーミングレプリケーション(Primary → Standby) 自動フェイルオーバーには Patroni 等の追加ツ ールが必要 MySQL: Group Replication, Galera Cluster WAL(Write-Ahead Log)でクラッシュ復旧 ポイント:どちらも耐障害性を実現できる。MongoDB は Replica Set が組み込みで自 50
  45. REFERENCE · 並行処理・トランザクション(DDIA 第7章) 参考:並行処理・トランザクションの違い ⚠️ これは第2章のスコープ外です。第7章(トランザクション)のテーマです。 RDB(PostgreSQL等) MongoDB ≤

    v3.x MongoDB v4.0+ トランザク ション 複数テーブルにまたがる ACID トラ ンザクション 単一ドキュメントの み原子的 Multi-document ACID トランザ クション追加 分離レベル Read Committed / Serializable 等を 選択可 なし Snapshot isolation(限定的) パフォーマ ロックによるオーバーヘッドあり 高速(ロックなし) トランザクション使用時はコス ポイント:複数エンティティにまたがる複雑な更新は RDB の ACID モデルが強い。 MongoDB は「1ドキュメントに必要な情報をまとめる」設計でトランザクションを回 避するのが基本。 📖 データ指向アプリケーションデザイン 第7章(トランザクション) 51