<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Sql on Tarragon</title><link>https://tarrragon.github.io/blog/tags/sql/</link><description>Recent content in Sql on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Mon, 15 Jun 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/sql/index.xml" rel="self" type="application/rss+xml"/><item><title>PostgreSQL</title><link>https://tarrragon.github.io/blog/backend/01-database/vendors/postgresql/</link><pubDate>Wed, 13 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/01-database/vendors/postgresql/</guid><description>&lt;p>PostgreSQL 是 backend 預設關聯式資料庫的安全選擇。生態完整、SQL 功能豐富、MVCC 跟 transaction 模型穩定、新版本仍積極演進（pg17 加入 JSON_TABLE、平行 vacuum；pg18 加入 io_uring async）。Aurora（AWS managed）、CockroachDB、Aurora DSQL（2024-12 preview / 2025-05 GA）、Spanner（2024 PostgreSQL dialect）都把 PostgreSQL wire protocol 當作相容標的 — 它是 SQL DB 世界的 lingua franca。&lt;/p>
&lt;h2 id="教學路線sql-baseline-與交易演進">教學路線：SQL baseline 與交易演進&lt;/h2>
&lt;p>PostgreSQL 服務頁的教學目標是建立 SQL baseline。讀者讀完後要能用 PostgreSQL 理解 transaction、schema evolution、query boundary、connection pressure 與 managed / distributed SQL 的比較基準。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>學習段&lt;/th>
 &lt;th>核心問題&lt;/th>
 &lt;th>對應段落&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>SQL baseline&lt;/td>
 &lt;td>PostgreSQL 為什麼常作為 OLTP 預設比較基準&lt;/td>
 &lt;td>定位、適用場景&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>容量邊界&lt;/td>
 &lt;td>connection、write throughput、replica、storage 如何限制服務&lt;/td>
 &lt;td>容量特性、容量規劃要點&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>交易與查詢&lt;/td>
 &lt;td>複雜 SQL、JSONB、GIS、全文檢索如何影響資料模型&lt;/td>
 &lt;td>適用場景、跟其他 vendor 的取捨&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>演進與維護&lt;/td>
 &lt;td>vacuum、partition、index、replication 如何成為長期責任&lt;/td>
 &lt;td>容量規劃要點、常見陷阱&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>替代路由&lt;/td>
 &lt;td>何時轉 Aurora、CockroachDB、Spanner、DynamoDB 或 OLAP&lt;/td>
 &lt;td>不適用場景、跟其他 vendor 的取捨&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="定位oltp-預設sql-工程深度">定位：OLTP 預設、SQL 工程深度&lt;/h2>
&lt;p>PostgreSQL 跟 MySQL 是兩大 SQL OLTP 主流、但設計取捨明顯不同：&lt;/p>
&lt;ul>
&lt;li>PostgreSQL 偏 &lt;em>特性深度&lt;/em> — JSON、GIS、full-text search、partial index、CTE、window function 都成熟&lt;/li>
&lt;li>MySQL 偏 &lt;em>簡單 query 效能 + 分片生態&lt;/em> — Vitess / PlanetScale 提供超大規模 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/database-sharding/" data-link-title="Database Sharding" data-link-desc="說明資料庫如何依 shard key 分散資料、路由請求與承擔跨 shard 查詢成本">database sharding&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>選 PostgreSQL 的核心訴求：需要進階 SQL 特性、需要長期 schema evolution 彈性、信任 community-driven 演進、想避免單一 vendor lock-in（PostgreSQL 是 open source、可跨雲 / on-prem）。&lt;/p>
&lt;h2 id="容量特性">容量特性&lt;/h2>
&lt;p>PostgreSQL 沒有「vendor 給的容量數字」、要靠 instance 配置 + tuning 推估。但有幾個工程上限要知道：&lt;/p>
&lt;p>&lt;strong>單一 primary 寫吞吐&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>一般 m5.4xlarge 級 instance：5K-10K WPS（依 schema、index、commit fsync）&lt;/li>
&lt;li>高階 r6i.16xlarge + io2 storage：30K-50K WPS&lt;/li>
&lt;li>超過這個級別 → 應用層 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/database-sharding/" data-link-title="Database Sharding" data-link-desc="說明資料庫如何依 shard key 分散資料、路由請求與承擔跨 shard 查詢成本">database sharding&lt;/a> 或換 Aurora / Spanner&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Connection 上限&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>預設 100 connection、每個 connection ~10MB RAM&lt;/li>
&lt;li>1000+ connection 必須 pgBouncer / PgCat 共享 pool&lt;/li>
&lt;li>對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/ntt-docomo-lemino-japanese-streaming/" data-link-title="9.C29 NTT DOCOMO Lemino：3 個月達 500 萬 MAU 的串流後端" data-link-desc="Lemino 用 DynamoDB &amp;#43; AWS Media Services 撐 30 channels live &amp;#43; 5M MAU、工程工時下降 90%">9.C29 Lemino case&lt;/a> — RDB connection limit 是 surge 場景的隱性 bottleneck&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Read replica&lt;/strong>：&lt;/p></description><content:encoded><![CDATA[<p>PostgreSQL 是 backend 預設關聯式資料庫的安全選擇。生態完整、SQL 功能豐富、MVCC 跟 transaction 模型穩定、新版本仍積極演進（pg17 加入 JSON_TABLE、平行 vacuum；pg18 加入 io_uring async）。Aurora（AWS managed）、CockroachDB、Aurora DSQL（2024-12 preview / 2025-05 GA）、Spanner（2024 PostgreSQL dialect）都把 PostgreSQL wire protocol 當作相容標的 — 它是 SQL DB 世界的 lingua franca。</p>
<h2 id="教學路線sql-baseline-與交易演進">教學路線：SQL baseline 與交易演進</h2>
<p>PostgreSQL 服務頁的教學目標是建立 SQL baseline。讀者讀完後要能用 PostgreSQL 理解 transaction、schema evolution、query boundary、connection pressure 與 managed / distributed SQL 的比較基準。</p>
<table>
  <thead>
      <tr>
          <th>學習段</th>
          <th>核心問題</th>
          <th>對應段落</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>SQL baseline</td>
          <td>PostgreSQL 為什麼常作為 OLTP 預設比較基準</td>
          <td>定位、適用場景</td>
      </tr>
      <tr>
          <td>容量邊界</td>
          <td>connection、write throughput、replica、storage 如何限制服務</td>
          <td>容量特性、容量規劃要點</td>
      </tr>
      <tr>
          <td>交易與查詢</td>
          <td>複雜 SQL、JSONB、GIS、全文檢索如何影響資料模型</td>
          <td>適用場景、跟其他 vendor 的取捨</td>
      </tr>
      <tr>
          <td>演進與維護</td>
          <td>vacuum、partition、index、replication 如何成為長期責任</td>
          <td>容量規劃要點、常見陷阱</td>
      </tr>
      <tr>
          <td>替代路由</td>
          <td>何時轉 Aurora、CockroachDB、Spanner、DynamoDB 或 OLAP</td>
          <td>不適用場景、跟其他 vendor 的取捨</td>
      </tr>
  </tbody>
</table>
<h2 id="定位oltp-預設sql-工程深度">定位：OLTP 預設、SQL 工程深度</h2>
<p>PostgreSQL 跟 MySQL 是兩大 SQL OLTP 主流、但設計取捨明顯不同：</p>
<ul>
<li>PostgreSQL 偏 <em>特性深度</em> — JSON、GIS、full-text search、partial index、CTE、window function 都成熟</li>
<li>MySQL 偏 <em>簡單 query 效能 + 分片生態</em> — Vitess / PlanetScale 提供超大規模 <a href="/blog/backend/knowledge-cards/database-sharding/" data-link-title="Database Sharding" data-link-desc="說明資料庫如何依 shard key 分散資料、路由請求與承擔跨 shard 查詢成本">database sharding</a></li>
</ul>
<p>選 PostgreSQL 的核心訴求：需要進階 SQL 特性、需要長期 schema evolution 彈性、信任 community-driven 演進、想避免單一 vendor lock-in（PostgreSQL 是 open source、可跨雲 / on-prem）。</p>
<h2 id="容量特性">容量特性</h2>
<p>PostgreSQL 沒有「vendor 給的容量數字」、要靠 instance 配置 + tuning 推估。但有幾個工程上限要知道：</p>
<p><strong>單一 primary 寫吞吐</strong>：</p>
<ul>
<li>一般 m5.4xlarge 級 instance：5K-10K WPS（依 schema、index、commit fsync）</li>
<li>高階 r6i.16xlarge + io2 storage：30K-50K WPS</li>
<li>超過這個級別 → 應用層 <a href="/blog/backend/knowledge-cards/database-sharding/" data-link-title="Database Sharding" data-link-desc="說明資料庫如何依 shard key 分散資料、路由請求與承擔跨 shard 查詢成本">database sharding</a> 或換 Aurora / Spanner</li>
</ul>
<p><strong>Connection 上限</strong>：</p>
<ul>
<li>預設 100 connection、每個 connection ~10MB RAM</li>
<li>1000+ connection 必須 pgBouncer / PgCat 共享 pool</li>
<li>對應 <a href="/blog/backend/09-performance-capacity/cases/ntt-docomo-lemino-japanese-streaming/" data-link-title="9.C29 NTT DOCOMO Lemino：3 個月達 500 萬 MAU 的串流後端" data-link-desc="Lemino 用 DynamoDB &#43; AWS Media Services 撐 30 channels live &#43; 5M MAU、工程工時下降 90%">9.C29 Lemino case</a> — RDB connection limit 是 surge 場景的隱性 bottleneck</li>
</ul>
<p><strong>Read replica</strong>：</p>
<ul>
<li>streaming replication：1 個 primary + 多個 standby（async / sync）</li>
<li>跨 AZ replication lag 通常 &lt; 100ms、跨 region 可能秒級</li>
<li>跟 Aurora 比、自管 PostgreSQL replication lag 較大</li>
</ul>
<p><strong>Storage 上限</strong>：</p>
<ul>
<li>單一 table 32 TB（PostgreSQL 設計上限）</li>
<li>實務上單表超過 1 TB 開始有 vacuum / index 問題、建議 partition</li>
</ul>
<h2 id="適用場景">適用場景</h2>
<p><strong>1. 多用途 OLTP、複雜查詢</strong>：</p>
<ul>
<li>複雜 JOIN、CTE、window function、subquery</li>
<li>訂單系統、會員系統、訂閱方案、權限 RBAC</li>
<li>需要 strong consistency + ACID transaction</li>
</ul>
<p><strong>2. JSON / 半結構化資料</strong>：</p>
<ul>
<li>JSONB column 支援 indexing、partial query</li>
<li>比 MongoDB 適合 <em>主要結構化 + 部分 JSON</em> workload</li>
<li>不適合主要 document workload（用 MongoDB / Cosmos DB）</li>
</ul>
<p><strong>3. 地理 / 全文檢索</strong>：</p>
<ul>
<li>PostGIS 是業界標準 GIS extension</li>
<li>全文檢索（ts_vector）對中等規模夠用、超大規模用 Elasticsearch</li>
</ul>
<p><strong>4. 進階特性需求</strong>：</p>
<ul>
<li>partial index（WHERE 條件下才建 index）</li>
<li>exclusion constraints（避免 booking 重疊）</li>
<li>range types（時間 / 數字範圍）</li>
<li>logical decoding / CDC（Debezium、pgcapture）</li>
<li>foreign data wrapper（query 跨 DB）</li>
</ul>
<p><strong>5. 跨雲 / on-prem 部署</strong>：</p>
<ul>
<li>不想 vendor lock-in</li>
<li>可用 Patroni / Stolon / pg_auto_failover 做 HA</li>
<li>對應 <a href="/blog/backend/01-database/global-distributed-oltp/" data-link-title="1.11 全球分散式 OLTP" data-link-desc="Spanner / Aurora DSQL / Cosmos DB multi-region write / CockroachDB / TiDB 的全球一致性取捨">1.11 全球分散式 OLTP</a> 的 CockroachDB / Aurora DSQL 比較段</li>
</ul>
<p><strong>6. 中小規模高峰場景</strong>：</p>
<ul>
<li>流量 &lt; 10K WPS 級別、PostgreSQL 自管或 RDS 通常夠</li>
<li>流量更高、考慮 Aurora（同 wire protocol、storage 升級）</li>
</ul>
<h2 id="不適用場景">不適用場景</h2>
<p><strong>1. 極高寫入吞吐（單機 &gt; 50K WPS）</strong>：</p>
<ul>
<li>必須進入 <a href="/blog/backend/knowledge-cards/database-sharding/" data-link-title="Database Sharding" data-link-desc="說明資料庫如何依 shard key 分散資料、路由請求與承擔跨 shard 查詢成本">database sharding</a> 或分散式 SQL</li>
<li>替代：CockroachDB、TiDB、Spanner、應用層 sharding</li>
</ul>
<p><strong>2. 全球 multi-region active-active write</strong>：</p>
<ul>
<li>PostgreSQL 是 single primary、不支援 multi-region active-active</li>
<li>替代：Aurora DSQL、Spanner、CockroachDB multi-region</li>
</ul>
<p><strong>3. KV 簡單查詢 + sub-10ms p99</strong>：</p>
<ul>
<li>PostgreSQL connection 開銷 + parsing + planning 已經 1-3ms</li>
<li>KV-pattern workload 用 DynamoDB / Redis / Cosmos DB 更便宜更快</li>
</ul>
<p><strong>4. 大規模 OLAP</strong>：</p>
<ul>
<li>PostgreSQL 定位在 OLTP，analytics workload 交給 OLAP 系統</li>
<li>大數據分析用 ClickHouse / BigQuery / Snowflake / Redshift / Synapse</li>
</ul>
<p><strong>5. 連線量極大 SaaS（每個用戶一個 connection）</strong>：</p>
<ul>
<li>即使有 pgBouncer、超大連線量仍是 PostgreSQL 結構性限制</li>
<li>對應 <a href="/blog/backend/09-performance-capacity/cases/ntt-docomo-lemino-japanese-streaming/" data-link-title="9.C29 NTT DOCOMO Lemino：3 個月達 500 萬 MAU 的串流後端" data-link-desc="Lemino 用 DynamoDB &#43; AWS Media Services 撐 30 channels live &#43; 5M MAU、工程工時下降 90%">9.C29 Lemino</a> 案例 — 流量上升 connection 爆是換 DynamoDB 的主因</li>
</ul>
<h2 id="跟其他-vendor-的取捨">跟其他 vendor 的取捨</h2>
<p><strong>vs MySQL</strong>：</p>
<ul>
<li>PostgreSQL：SQL 特性深、JSON / GIS / window 完整、replication 較簡單但 lag 較大</li>
<li>MySQL：簡單 query 效能好、replication 機制成熟、Vitess 分片生態強</li>
<li>選 PostgreSQL：需要進階 SQL、複雜 query、JSON workload</li>
<li>選 MySQL：高併發簡單 query、需要 sharding、已用 MySQL 生態</li>
</ul>
<p><strong>vs Aurora（同 PostgreSQL wire protocol）</strong>：</p>
<ul>
<li>PostgreSQL：自管 / RDS、特性接近 upstream、跨雲可用</li>
<li>Aurora：AWS managed、storage / compute 分離、更多 read replica</li>
<li>選 PostgreSQL：跨雲、想最新特性、預算敏感</li>
<li>選 Aurora：AWS 生態、需要更快 failover + 更多 read replica</li>
<li>詳見 <a href="/blog/backend/01-database/vendors/aurora/" data-link-title="AWS Aurora" data-link-desc="AWS managed PostgreSQL / MySQL、storage / compute 分離、&#43;75% 效能改善的 production 證據">Aurora vendor page</a></li>
</ul>
<p><strong>vs CockroachDB（PostgreSQL wire protocol 相容）</strong>：</p>
<ul>
<li>PostgreSQL：single-primary OLTP、SQL 特性完整</li>
<li>CockroachDB：multi-region 強一致 SQL、PostgreSQL wire 相容但部分特性缺</li>
<li>選 PostgreSQL：single-region 或 read replica 跨 region 夠</li>
<li>選 CockroachDB：必須 multi-region active-active write</li>
<li>詳見 <a href="/blog/backend/01-database/global-distributed-oltp/" data-link-title="1.11 全球分散式 OLTP" data-link-desc="Spanner / Aurora DSQL / Cosmos DB multi-region write / CockroachDB / TiDB 的全球一致性取捨">1.11 全球分散式 OLTP</a></li>
</ul>
<p><strong>vs Spanner / Aurora DSQL（全球分散式 SQL）</strong>：</p>
<ul>
<li>PostgreSQL：傳統設計、跨 region 是 async replication</li>
<li>Spanner / Aurora DSQL：全球線性化、跨 region 強一致</li>
<li>選 PostgreSQL：90% 場景夠用、便宜、容易</li>
<li>選 Spanner / Aurora DSQL：金融交易、ticketing inventory、必須全球強一致</li>
</ul>
<p><strong>vs DynamoDB</strong>：</p>
<ul>
<li>詳見 <a href="/blog/backend/01-database/kv-document-capacity-planning/" data-link-title="1.10 KV / Document DB 容量規劃" data-link-desc="DynamoDB / Cosmos DB / Bigtable / MongoDB 等 KV / Document DB 的容量設計、partition key 取捨、capacity mode 選擇">1.10 KV / Document DB 容量規劃</a> 的 connection model 對比段</li>
</ul>
<p><strong>vs Neon（PostgreSQL serverless）</strong>：</p>
<ul>
<li>PostgreSQL：standard、自管或 RDS</li>
<li>Neon：branch-based、scale-to-zero、適合 dev / preview environment</li>
<li>選 Neon：dev / preview、稀疏 workload、CI 用</li>
<li>選 PostgreSQL：production sustained workload</li>
</ul>
<h2 id="容量規劃要點">容量規劃要點</h2>
<p><strong>1. Connection pool 必須有</strong>：</p>
<ul>
<li>直接連 1000+ connection 會壓垮 PostgreSQL</li>
<li>pgBouncer（最簡單、transaction pooling）</li>
<li>PgCat（rust 寫的進階替代、支援 sharding）</li>
<li>application 層 pool（HikariCP、SQLAlchemy pool）</li>
<li>通常組合使用：application pool 30-50 connection × 多 instance → pgBouncer 共享 → PostgreSQL 200 connection</li>
<li>對應 <a href="/blog/backend/knowledge-cards/connection-pool/" data-link-title="Connection Pool" data-link-desc="說明連線池如何限制下游資源並影響服務容量">Connection Pool 卡片</a></li>
</ul>
<p><strong>2. Replication 配置</strong>：</p>
<ul>
<li>streaming replication：async / sync / <a href="/blog/backend/knowledge-cards/quorum/" data-link-title="Quorum" data-link-desc="分散式系統以多數節點同意作為提交或讀取有效性的門檻">quorum</a></li>
<li>跨 AZ async：lag 通常 &lt; 100ms、failover 1-2 分鐘</li>
<li>跨 AZ sync：lag 接近 0、但寫入要等 standby ack、會降寫吞吐</li>
<li>跨 region 通常 async</li>
<li>HA 工具：Patroni（最常見）、pg_auto_failover、Stolon</li>
</ul>
<p><strong>3. Vacuum 跟 bloat 治理</strong>：</p>
<ul>
<li>PostgreSQL MVCC 會留下 dead tuples、必須 vacuum</li>
<li>autovacuum 配置：throttle 大表、避免在 peak 跑</li>
<li>bloat 監控：pg_stat_user_tables 看 dead_tup ratio</li>
<li>大表 vacuum 可能要 hours、影響 maintenance window</li>
</ul>
<p><strong>4. 大表 partitioning</strong>：</p>
<ul>
<li>單表 &gt; 1 TB 建議 partition（按時間、按 tenant）</li>
<li>partition pruning 讓 query 只掃需要的 partition</li>
<li>partition 限制：cross-partition unique constraint、跨 partition join 較慢</li>
</ul>
<p><strong>5. Index 策略</strong>：</p>
<ul>
<li>預設 B-tree、適合大多數 query</li>
<li>partial index 對 boolean / status column 特別有用</li>
<li>GIN / GiST 對 JSON / full-text / GIS</li>
<li>index 太多會拖累寫入、定期 review 未用 index（pg_stat_user_indexes）</li>
</ul>
<h2 id="安全dr-與角色分工">安全、DR 與角色分工</h2>
<p>PostgreSQL 的 production 完整性不只來自 SQL 特性，也來自資料存取、備份復原、升級責任與事故證據的分工。這一段補上 PG baseline 原本留在 limitation 的三個缺口：Security / RLS / audit logging、cross-region DR、application developer vs DBA / SRE 視角。</p>
<table>
  <thead>
      <tr>
          <th>責任面</th>
          <th>PostgreSQL 要回答的問題</th>
          <th>主要引用路徑</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Access control / RLS</td>
          <td>table、row、function、extension 與 service account 權限如何切</td>
          <td><a href="security-rls-audit-logging/">Security / RLS / Audit Logging</a>、<a href="/blog/backend/07-security-data-protection/data-protection-and-masking-governance/" data-link-title="7.4 資料保護與遮罩治理" data-link-desc="以問題驅動方式整理資料分級、遮罩、匯出與備份治理">7.4 Data Protection</a>、<a href="/blog/backend/knowledge-cards/audit-log/" data-link-title="Audit Log" data-link-desc="說明高風險操作如何留下可追溯、可稽核的紀錄">Audit Log</a></td>
      </tr>
      <tr>
          <td>TLS / credential</td>
          <td>application 連線、DB user、憑證與 secret rotation 如何治理</td>
          <td><a href="/blog/backend/knowledge-cards/tls-mtls/" data-link-title="TLS / mTLS" data-link-desc="說明傳輸加密與雙向憑證驗證如何保護跨邊界資料流">TLS / mTLS</a>、<a href="/blog/backend/knowledge-cards/credential/" data-link-title="Credential" data-link-desc="整理身分驗證與系統存取用秘密資料">Credential</a>、<a href="/blog/backend/knowledge-cards/secret-management/" data-link-title="Secret Management" data-link-desc="說明 token、key、password 與憑證如何保存、輪替與撤銷">Secret Management</a></td>
      </tr>
      <tr>
          <td>Cross-region DR</td>
          <td>region 失效時要 async replica、PITR、Aurora Global Database 還是 distributed SQL</td>
          <td><a href="cross-region-dr/">Cross-region DR</a>、<a href="/blog/backend/knowledge-cards/rpo/" data-link-title="RPO" data-link-desc="說明恢復點目標如何定義可接受資料損失範圍">RPO</a>、<a href="/blog/backend/knowledge-cards/rto/" data-link-title="RTO" data-link-desc="說明恢復時間目標如何約束事故回復策略">RTO</a>、<a href="/blog/backend/knowledge-cards/failover/" data-link-title="Failover" data-link-desc="說明主要服務或節點失效時如何切換到備援能力">Failover</a>、<a href="pitr-wal-archiving/">PITR + WAL Archiving</a></td>
      </tr>
      <tr>
          <td>Developer / DBA split</td>
          <td>application schema、migration、query、index 與 rollback 誰負責</td>
          <td><a href="developer-dba-responsibility-split/">Developer / DBA Responsibility Split</a>、<a href="/blog/backend/01-database/schema-design/" data-link-title="1.2 Schema Design 與資料建模" data-link-desc="整理 table、index、key、partition、denormalization 與命名規則">1.2 Schema Design</a>、<a href="/blog/backend/01-database/database-migration-playbook/" data-link-title="1.6 資料庫轉換實作：雙寫、回填、切流與回滾" data-link-desc="同 DB 內 schema 演進與資料變更的可分段驗證流程、跟 1.12 cross-DB migration 分工">1.6 Migration Playbook</a></td>
      </tr>
      <tr>
          <td>Incident evidence</td>
          <td>資料事故中要留下哪些 query、timeline、restore 與 decision evidence</td>
          <td><a href="/blog/backend/04-observability/observability-evidence-package/" data-link-title="4.20 Observability Evidence Package" data-link-desc="把 log、metric、trace、audit 與資料品質限制包成可交接證據">4.20 Observability Evidence Package</a>、<a href="/blog/backend/08-incident-response/incident-decision-log/" data-link-title="8.19 Incident Decision Log" data-link-desc="把事中假設、決策、證據、回退條件與責任人留下可復盤紀錄">8.19 Incident Decision Log</a></td>
      </tr>
  </tbody>
</table>
<p>Access control / RLS 的判讀重點是把資料責任放在資料層與 application 層之間分工。PostgreSQL 支援 role、grant、schema、function security 與 row-level security；但 RLS 會把授權邏輯拉進 database，適合 multi-tenant row isolation、資料平台或共享 reporting schema，日常 OLTP 仍要保留 application authorization 與 audit trail。</p>
<p>TLS / credential 的判讀重點是連線安全與憑證生命週期。Self-managed PostgreSQL 要處理 server cert、client cert、DB user rotation 與 <a href="/blog/backend/knowledge-cards/connection-pool/" data-link-title="Connection Pool" data-link-desc="說明連線池如何限制下游資源並影響服務容量">connection pool</a> 重連；managed PostgreSQL 常把 certificate、IAM auth 或 secret integration 交給平台，但 application pool、migration tool 與 read replica 仍要一起更新。</p>
<p>Cross-region DR 的判讀重點是 <a href="/blog/backend/knowledge-cards/rpo/" data-link-title="RPO" data-link-desc="說明恢復點目標如何定義可接受資料損失範圍">RPO</a> / <a href="/blog/backend/knowledge-cards/rto/" data-link-title="RTO" data-link-desc="說明恢復時間目標如何約束事故回復策略">RTO</a> 與資料一致性。自管 PostgreSQL 可用 streaming replication、WAL archiving、PITR 與 Patroni 做 region <a href="/blog/backend/knowledge-cards/failover/" data-link-title="Failover" data-link-desc="說明主要服務或節點失效時如何切換到備援能力">failover</a>；Aurora 把 backup、PITR 與 Global Database 交給 AWS；真正 active-active 或 global strong consistency 需求要回到 CockroachDB、Spanner 或 Aurora DSQL，single-primary PostgreSQL 保留為 region failover 與 async DR 路線。</p>
<p>Developer / DBA split 的判讀重點是把日常責任寫進流程。Application developer 擁有 query shape、transaction boundary、repository adapter 與 migration contract；DBA / SRE 擁有 backup、replication、pooler、extension、vacuum、index maintenance 與 DR drill；release gate 需要把兩邊 evidence 合在同一份 decision log。</p>
<h2 id="managed-pg-與相容變體路由">Managed PG 與相容變體路由</h2>
<p>PostgreSQL wire protocol 已成為 managed SQL 與 distributed SQL 的相容目標。選型時要區分「PostgreSQL 本體」、「managed PostgreSQL」、「PostgreSQL-compatible distributed SQL」與「PostgreSQL extension ecosystem」四種不同責任。</p>
<table>
  <thead>
      <tr>
          <th>變體</th>
          <th>適合情境</th>
          <th>主要代價 / 檢查點</th>
          <th>下一步路由</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>RDS / self-managed PG</td>
          <td>想接近 upstream、保留跨雲與 extension 彈性</td>
          <td>團隊承擔 HA、backup、upgrade、vacuum 與 pooler</td>
          <td><a href="patroni-ha/">Patroni HA</a>、<a href="pitr-wal-archiving/">PITR + WAL Archiving</a></td>
      </tr>
      <tr>
          <td>Aurora PostgreSQL</td>
          <td>AWS 內 production OLTP、想轉移 HA / storage ops</td>
          <td>extension whitelist、cost model、cluster endpoint</td>
          <td><a href="migrate-to-aurora/">→ Aurora</a>、<a href="/blog/backend/01-database/vendors/aurora/" data-link-title="AWS Aurora" data-link-desc="AWS managed PostgreSQL / MySQL、storage / compute 分離、&#43;75% 效能改善的 production 證據">Aurora vendor</a></td>
      </tr>
      <tr>
          <td>Cloud SQL / AlloyDB</td>
          <td>GCP 內 managed PostgreSQL 與 Google operation model</td>
          <td>extension / version matrix、IAM / backup / cost model</td>
          <td><a href="managed-pg-comparison/">Managed PG Comparison</a></td>
      </tr>
      <tr>
          <td>Azure Cosmos DB for PostgreSQL</td>
          <td>Citus-based distributed PostgreSQL、tenant / shard workload</td>
          <td>coordinator / worker topology、Citus 語意</td>
          <td><a href="citus-distributed/">Citus distributed</a>、<a href="/blog/backend/knowledge-cards/database-sharding/" data-link-title="Database Sharding" data-link-desc="說明資料庫如何依 shard key 分散資料、路由請求與承擔跨 shard 查詢成本">Database Sharding</a>、<a href="/blog/backend/01-database/vendors/cosmosdb/" data-link-title="Azure Cosmos DB" data-link-desc="全球分散式 multi-model DB、5 個 consistency levels、Microsoft 自家 dogfood 證據">Cosmos DB vendor</a></td>
      </tr>
      <tr>
          <td>Neon / serverless PG</td>
          <td>preview、branch、稀疏 workload、dev environment</td>
          <td>cold start、connection、production sustained workload</td>
          <td>本頁 vs Neon 段、後續 serverless PG comparison</td>
      </tr>
      <tr>
          <td>Aurora DSQL / CockroachDB</td>
          <td>global write、distributed SQL、region resiliency</td>
          <td>transaction retry、extension gap、latency / cost</td>
          <td><a href="migrate-to-aurora-dsql/">→ Aurora DSQL</a>、<a href="migrate-to-cockroachdb/">→ CockroachDB</a></td>
      </tr>
  </tbody>
</table>
<p>Managed PG 變體的引用規則是先查 compatibility，再談 migration。Extension whitelist、backup / restore API、logical replication 支援、connection endpoint 行為與 pricing 都是時間敏感 claim；實作前要回到官方文件確認版本，並把確認日期留在 migration plan 或 decision log。</p>
<h2 id="deep-article--migration-playbook已完成">Deep article + Migration playbook（已完成）</h2>
<table>
  <thead>
      <tr>
          <th>主題</th>
          <th>文章</th>
          <th>類型</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Streaming replication topology + LSN + slot</td>
          <td><a href="replication-topology/">replication-topology</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>pg_repack / pg-osc 跟 PG 內建 ALTER 行為</td>
          <td><a href="online-schema-change/">online-schema-change</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>Process-per-connection model + pooler 必要性</td>
          <td><a href="connection-scaling/">connection-scaling</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>pgBouncer + PgCat connection pool</td>
          <td><a href="pgbouncer-config/">pgbouncer-config</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>Patroni HA + DCS-based failover</td>
          <td><a href="patroni-ha/">patroni-ha</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>Autovacuum tuning + bloat 治理</td>
          <td><a href="autovacuum-tuning/">autovacuum-tuning</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>Logical replication + Debezium CDC</td>
          <td><a href="logical-replication-debezium/">logical-replication-debezium</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>Citus distributed extension</td>
          <td><a href="citus-distributed/">citus-distributed</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>BDR / pgEdge / Bucardo multi-master</td>
          <td><a href="bdr-multi-master/">bdr-multi-master</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>MVCC + lock model（PG 並行控制核心）</td>
          <td><a href="mvcc-lock-model/">mvcc-lock-model</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>EXPLAIN / auto_explain / pg_hint_plan</td>
          <td><a href="query-optimization/">query-optimization</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>Index method 選型決策樹（B-tree / GIN / GiST / BRIN）</td>
          <td><a href="index-selection/">index-selection</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>Declarative partitioning + pg_partman</td>
          <td><a href="declarative-partitioning/">declarative-partitioning</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>JSONB binary storage + GIN index</td>
          <td><a href="jsonb-deep-dive/">jsonb-deep-dive</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>Full-text search（tsvector + pg_trgm）</td>
          <td><a href="full-text-search/">full-text-search</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>Extension ecosystem（pgvector / TimescaleDB 等）</td>
          <td><a href="extension-ecosystem/">extension-ecosystem</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>TimescaleDB hypertable + CAGG + compression</td>
          <td><a href="timescaledb-deep-dive/">timescaledb-deep-dive</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>pgvector HNSW / IVFFlat ANN search</td>
          <td><a href="pgvector-deep-dive/">pgvector-deep-dive</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>PostGIS geometry / geography + GiST</td>
          <td><a href="postgis-deep-dive/">postgis-deep-dive</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>PITR + WAL archiving</td>
          <td><a href="pitr-wal-archiving/">pitr-wal-archiving</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>Replication slot management（含 PG 17 failover slot）</td>
          <td><a href="replication-slot-management/">replication-slot-management</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>SQL features baseline + MySQL 對比</td>
          <td><a href="sql-features-baseline/">sql-features-baseline</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>Hands-on 操作路線</td>
          <td><a href="hands-on/">hands-on</a></td>
          <td>操作型章節群</td>
      </tr>
      <tr>
          <td>Major version upgrade（N → N+1 pg_upgrade）</td>
          <td><a href="major-version-upgrade/">major-version-upgrade</a></td>
          <td>Migration playbook（5-type 漏類 / 接近 Type B 但需 upgrade-specific audit）</td>
      </tr>
      <tr>
          <td>→ Aurora PostgreSQL</td>
          <td><a href="migrate-to-aurora/">migrate-to-aurora</a></td>
          <td>Migration playbook（Type C）</td>
      </tr>
      <tr>
          <td>→ Aurora DSQL（PG wire-compat distributed）</td>
          <td><a href="migrate-to-aurora-dsql/">migrate-to-aurora-dsql</a></td>
          <td>Migration playbook（Type E）</td>
      </tr>
      <tr>
          <td>→ CockroachDB</td>
          <td><a href="migrate-to-cockroachdb/">migrate-to-cockroachdb</a></td>
          <td>Migration playbook（Type E）</td>
      </tr>
      <tr>
          <td>Multi-region + GDPR rollout</td>
          <td><a href="multi-region-gdpr-rollout/">multi-region-gdpr-rollout</a></td>
          <td>Migration playbook（Type F）</td>
      </tr>
      <tr>
          <td>Partition redesign</td>
          <td><a href="partition-redesign/">partition-redesign</a></td>
          <td>Migration playbook（Type F）</td>
      </tr>
  </tbody>
</table>
<h2 id="補充正文路由">補充正文路由</h2>
<p>當前 deep article、migration playbook、補充正文與 hands-on 已 cover replication / HA / OSC / connection / CDC / sharding / multi-master / MVCC / query opt / index / partitioning / JSONB / FTS / extension（含 TimescaleDB / pgvector / PostGIS）/ backup / slot / SQL features / upgrade / migration / security / DR / managed variant 等維度。下列補充正文用來承接 overview 中提到的延伸議題：</p>
<ul>
<li><strong><a href="logical-decoding-plugins/">Logical decoding plugins deep dive</a></strong>：wal2json / pgoutput / decoderbufs 對位、CDC pipeline 整合</li>
<li><strong><a href="pg-partman-advanced/">pg_partman advanced</a></strong>：retention 跟 child partition 自動 management</li>
<li><strong><a href="connection-pooler-comparison/">Connection pooler comparison</a></strong>：PgBouncer vs Pgcat vs Odyssey 細部對比</li>
<li><strong><a href="aurora-io-optimized-cost/">Aurora I/O-Optimized vs standard</a></strong>：cost model 取捨</li>
<li><strong><a href="managed-pg-comparison/">AlloyDB / Cloud SQL 比較</a></strong>：GCP managed PG 選型</li>
</ul>
<p>上述補充篇已完成正文，並保留既有引用路徑。Logical decoding 接 <a href="logical-replication-debezium/">Logical Replication + Debezium</a> 與 <a href="replication-slot-management/">Replication Slot Management</a>；pg_partman advanced 接 <a href="declarative-partitioning/">Declarative Partitioning</a>；pooler comparison 接 <a href="connection-scaling/">Connection Scaling</a> 與 <a href="pgbouncer-config/">pgBouncer Config</a>；Aurora cost 接 <a href="migrate-to-aurora/">→ Aurora</a>；AlloyDB / Cloud SQL 接 <a href="managed-pg-comparison/">Managed PG Comparison</a>。</p>
<h2 id="案例對照">案例對照</h2>
<p>PostgreSQL 沒有直接的 09 case（多數 09 case 用 managed vendor）、但作為 <em>baseline 跟遷移源頭</em> 在許多 case 出現：</p>
<table>
  <thead>
      <tr>
          <th>案例</th>
          <th>跟 PostgreSQL 的關係</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix Aurora consolidation</a></td>
          <td>從多套 RDBMS（含 PostgreSQL）統一到 Aurora</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/clearent-azure-sql-hyperscale-payments/" data-link-title="9.C32 Clearent：Azure SQL Hyperscale 撐每年 5 億筆支付交易" data-link-desc="Clearent 在 Azure SQL Hyperscale 上處理每年 5 億筆支付交易、autoscale &#43; 微服務架構">9.C32 Clearent Azure SQL Hyperscale</a></td>
          <td>Azure 生態替代 PostgreSQL 的選擇</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/ntt-docomo-lemino-japanese-streaming/" data-link-title="9.C29 NTT DOCOMO Lemino：3 個月達 500 萬 MAU 的串流後端" data-link-desc="Lemino 用 DynamoDB &#43; AWS Media Services 撐 30 channels live &#43; 5M MAU、工程工時下降 90%">9.C29 Lemino RDB connection limit</a></td>
          <td>PostgreSQL/MySQL 都有的 connection 限制</td>
      </tr>
  </tbody>
</table>
<h2 id="已知-limitation-與-audit-紀錄">已知 Limitation 與 Audit 紀錄</h2>
<p>本 vendor 頁的 22 篇 deep article + 6 篇 migration playbook 經過 4-reviewer audit（A 寫作規範 / B 跨檔一致性 / C 技術準確性 / D 框架偏誤）、Phase 1-3 修法完成。承認以下 limitation：</p>
<ul>
<li><strong>PG narrative bias</strong>：pgvector / TimescaleDB / extension-ecosystem / Citus 四篇對「PG 取代專業 DB」描述偏 PG-favoring；對手 vendor（Pinecone / InfluxDB / Vitess）的優勢段相對簡短。讀者選型時、請以 cost / ops / scale 三軸綜合判斷、不依本 vendor 頁單一視角。</li>
<li><strong>Anti-recommendation 深度不一</strong>：bdr-multi-master / extension-ecosystem 有「99% 不需要」明確邊界、其他篇章邊界較柔（如「Vector 量 &gt; 5-20M」是粗略門檻）。實際 production 決策請參考多 vendor 對照 + 自家 workload 量測。</li>
<li><strong>Sibling cross-link 狀態</strong>：MySQL ↔ PG sibling、PG 既有 ↔ 新章節 cross-link 已補（refer <a href="/blog/report/sibling-vendor-cross-link-bidirectionality-audit/" data-link-title="Sibling Vendor Cross-Link 雙向性 Audit：寫 Vendor Batch 結束必跑" data-link-desc="當寫 sibling vendor batch（A vs B）、cross-link 容易單向 — A 提 B 多次、B 沒回提 A、形成 navigation asymmetry。Case：MySQL 18 篇對 PG sibling cross-link 9 條、PG 對 MySQL cross-link 0 條。機制：寫第二個 batch 時 reference 第一個 batch 是自然行為、但 reverse direction 必須主動補。修法：vendor batch 結束跑 bidirectional link audit、`A → B` 跟 `B → A` 對比、缺一邊就補。">#136 卡</a>）；本輪同步補 Aurora / CockroachDB / Spanner / Cosmos DB / DynamoDB vendor 頁的反向 sibling 路由，剩餘精修可在各 migration playbook 補更細的 step-by-step 對照。</li>
<li><strong>時間敏感 vendor claim</strong>：Aurora DSQL（2024-12 preview / 2025-05 GA）/ pgvector（0.8 iterative scan）/ TimescaleDB version matrix / DSQL extension 支援範圍持續演進、本 vendor 頁以 2025-2026 公開狀態為準、實作前請以 vendor 官方 docs 為準（refer <a href="/blog/report/vendor-feature-time-sensitivity-claim-verification/" data-link-title="Vendor Feature 時間敏感性：Claim Verification 必跑、寫作日期必標" data-link-desc="寫 vendor article 時、feature limitation claim（『不支援 X』『最多 Y』『預設 Z』）有時間敏感性 — vendor 持續演進、寫作後 N 個月可能 invalidate 整段 audit 邏輯。Case：PlanetScale FK 不支援是 2022 年的事實、2023 末 Vitess 18 加 FK 支援、寫作時若不 verify、Phase 1 audit「FK audit &#43; 全 drop」整段過時。機制：LLM training cutoff vs vendor changelog 速度差、且 LLM 預設不標 claim 的時間性。修法：每篇 vendor article 標 *Last verified* date、limitation claim 必要時加 *as of N* 註、claim 反轉 invalidates 整段 audit 時必須重寫不是修補。">#137 卡</a>）。</li>
<li><strong>補充維度已正文化</strong>：<a href="security-rls-audit-logging/">Security / RLS / audit logging</a>、<a href="cross-region-dr/">cross-region DR</a>、<a href="developer-dba-responsibility-split/">application developer vs DBA 視角分工</a>、<a href="migrate-to-yugabytedb-tidb/">YugabyteDB / TiDB migration playbook</a>、<a href="specialized-pg-variants/">specialized PG variants</a> 已補成正文。本輪也補上跨 vendor 反向連結與時間敏感 claim 路由；下一輪可集中在 migration playbook 的操作步驟與 lab 化。</li>
</ul>
<p>詳細 audit findings 跟修法見 <a href="/blog/report/sibling-vendor-cross-link-bidirectionality-audit/" data-link-title="Sibling Vendor Cross-Link 雙向性 Audit：寫 Vendor Batch 結束必跑" data-link-desc="當寫 sibling vendor batch（A vs B）、cross-link 容易單向 — A 提 B 多次、B 沒回提 A、形成 navigation asymmetry。Case：MySQL 18 篇對 PG sibling cross-link 9 條、PG 對 MySQL cross-link 0 條。機制：寫第二個 batch 時 reference 第一個 batch 是自然行為、但 reverse direction 必須主動補。修法：vendor batch 結束跑 bidirectional link audit、`A → B` 跟 `B → A` 對比、缺一邊就補。">#136 Sibling Vendor Cross-Link Bidirectionality</a> / <a href="/blog/report/vendor-feature-time-sensitivity-claim-verification/" data-link-title="Vendor Feature 時間敏感性：Claim Verification 必跑、寫作日期必標" data-link-desc="寫 vendor article 時、feature limitation claim（『不支援 X』『最多 Y』『預設 Z』）有時間敏感性 — vendor 持續演進、寫作後 N 個月可能 invalidate 整段 audit 邏輯。Case：PlanetScale FK 不支援是 2022 年的事實、2023 末 Vitess 18 加 FK 支援、寫作時若不 verify、Phase 1 audit「FK audit &#43; 全 drop」整段過時。機制：LLM training cutoff vs vendor changelog 速度差、且 LLM 預設不標 claim 的時間性。修法：每篇 vendor article 標 *Last verified* date、limitation claim 必要時加 *as of N* 註、claim 反轉 invalidates 整段 audit 時必須重寫不是修補。">#137 Vendor Feature 時間敏感性</a> / <a href="/blog/report/cross-reviewer-convergence-priority-weighting/" data-link-title="Cross-Reviewer Convergence：多 Reviewer 收斂的 finding 比單 Reviewer flag 信號強" data-link-desc="Multi-reviewer audit（4-reviewer / N-reviewer parallel）後、finding priority 不該是 *N 個 reviewer 報告平均合併*、應該按 *跨 reviewer convergence* 加權 — 兩個獨立 reviewer 從不同 axis 各自發現同一 finding 是 *信號收斂*、比單 reviewer flag 信號強 5-10x。Case：MySQL 17 篇 4-reviewer audit、Reviewer A（寫作規範）跟 Reviewer B（跨檔一致性）獨立 flag 同一 finding『4 篇 migration playbook 缺 weight &#43; banner』、是跨軸 convergence、是最 high-priority fix。機制：N 個獨立 axis 隨機 hit 同一 finding 的機率隨 N 增加而 exponential decline、convergence 排除噪音、是 signal-to-noise 的最高比訊號。修法：multi-reviewer audit 後做 *cross-reviewer matrix*、convergence column 自動標 priority bump。">#138 Cross-Reviewer Convergence</a>。</p>
<h2 id="常見陷阱">常見陷阱</h2>
<ul>
<li><strong>connection 沒 pool 直接連</strong>：1000 application instance × 30 connection = 30K connection、PostgreSQL 撐不住</li>
<li><strong>沒 vacuum 治理</strong>：dead tuple 累積、table bloat、query 變慢</li>
<li><strong>大表沒 partition</strong>：&gt; 1 TB 單表的 vacuum / index rebuild 變成事故</li>
<li><strong>index 不 review</strong>：寫吞吐被舊 index 拖垮</li>
<li><strong>跨 AZ sync replication 給寫入吞吐高的 workload</strong>：每次 commit 等 standby ack、寫吞吐減半</li>
<li><strong>logical replication 拖太多 publication</strong>：可能造成 primary WAL 堆積、disk 爆</li>
</ul>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>完整 T1 對照：<a href="/blog/backend/01-database/vendors/" data-link-title="資料庫 Vendor 清單" data-link-desc="規劃 SQL、managed SQL、document、KV 與 distributed SQL 的服務頁撰寫順序與教學大綱">01-database vendors index</a></li>
<li>平行：<a href="/blog/backend/01-database/vendors/mysql/" data-link-title="MySQL" data-link-desc="高併發網路服務常用關聯式資料庫、Vitess / PlanetScale 分片生態、GitHub / Shopify / Facebook 規模驗證">MySQL vendor</a>、<a href="/blog/backend/01-database/vendors/aurora/" data-link-title="AWS Aurora" data-link-desc="AWS managed PostgreSQL / MySQL、storage / compute 分離、&#43;75% 效能改善的 production 證據">Aurora vendor</a>（managed PostgreSQL）</li>
<li>操作：<a href="/blog/backend/01-database/vendors/postgresql/hands-on/" data-link-title="PostgreSQL Hands-on 操作路線" data-link-desc="PostgreSQL local lab、connection pool、PITR restore drill、schema migration evidence 與 HA failover 的操作型章節設計">PostgreSQL Hands-on</a>（local lab、pool、PITR、migration evidence、HA drill）</li>
<li>上游：<a href="/blog/backend/01-database/high-concurrency-access/" data-link-title="1.1 高併發下的 SQL 讀寫邊界" data-link-desc="說明高併發服務如何共用資料庫 client、控制 transaction、管理 connection pool、避免資料庫成為瓶頸">1.1 高併發資料存取</a>、<a href="/blog/backend/01-database/transaction-boundary/" data-link-title="1.3 Transaction 與一致性邊界" data-link-desc="交易邊界、isolation level、retry 策略、distributed transaction（2PC、Saga）與跨 region 強一致取捨">1.3 Transaction Boundary</a></li>
<li>下游：<a href="/blog/backend/01-database/kv-document-capacity-planning/" data-link-title="1.10 KV / Document DB 容量規劃" data-link-desc="DynamoDB / Cosmos DB / Bigtable / MongoDB 等 KV / Document DB 的容量設計、partition key 取捨、capacity mode 選擇">1.10 KV / Document DB 容量規劃</a>（PostgreSQL 不適用時的替代）/ <a href="/blog/backend/01-database/global-distributed-oltp/" data-link-title="1.11 全球分散式 OLTP" data-link-desc="Spanner / Aurora DSQL / Cosmos DB multi-region write / CockroachDB / TiDB 的全球一致性取捨">1.11 全球分散式 OLTP</a>（PostgreSQL 不夠用時的升級路徑）</li>
<li>跨模組：<a href="/blog/backend/09-performance-capacity/bottleneck-localization/" data-link-title="9.5 瓶頸定位流程" data-link-desc="從 app 到 DB / cache / broker / 第三方 quota 的逐層瓶頸定位">9.5 瓶頸定位流程</a> — connection / replication lag / vacuum 都是 PostgreSQL 常見 bottleneck 源</li>
<li>官方：<a href="https://www.postgresql.org/docs/">PostgreSQL Documentation</a></li>
</ul>
]]></content:encoded></item><item><title>MySQL</title><link>https://tarrragon.github.io/blog/backend/01-database/vendors/mysql/</link><pubDate>Wed, 13 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/01-database/vendors/mysql/</guid><description>&lt;p>MySQL 是大型網路服務的常見選擇、簡單 query 效能跟 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/database-sharding/" data-link-title="Database Sharding" data-link-desc="說明資料庫如何依 shard key 分散資料、路由請求與承擔跨 shard 查詢成本">database sharding&lt;/a> 生態（Vitess / PlanetScale）成熟。GitHub、Shopify、Slack、Facebook（YouTube 從 MySQL 起家）等大規模服務的核心 OLTP 多採 MySQL。InnoDB engine 的 row-level lock、clustered index、buffer pool tuning 都被深度驗證。&lt;/p>
&lt;h2 id="教學路線高併發-oltp-與分片生態">教學路線：高併發 OLTP 與分片生態&lt;/h2>
&lt;p>MySQL 服務頁的教學目標是把「簡單 SQL 查詢」推進到高併發 OLTP、replication、online schema change 與 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/database-sharding/" data-link-title="Database Sharding" data-link-desc="說明資料庫如何依 shard key 分散資料、路由請求與承擔跨 shard 查詢成本">sharding governance&lt;/a>。讀者讀完後要能判斷 MySQL 何時是成熟預設、何時已經進入 Vitess / PlanetScale 或 application sharding 的討論。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>學習段&lt;/th>
 &lt;th>核心問題&lt;/th>
 &lt;th>對應段落&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>OLTP 基線&lt;/td>
 &lt;td>MySQL 適合哪種大量簡單查詢與交易路徑&lt;/td>
 &lt;td>定位、適用場景&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Replication&lt;/td>
 &lt;td>replica、failover、lag 與 read scaling 如何影響服務&lt;/td>
 &lt;td>容量特性、容量規劃要點&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Schema change&lt;/td>
 &lt;td>online schema change 與 migration 如何保護高流量服務&lt;/td>
 &lt;td>容量規劃要點、預計實作話題&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Sharding&lt;/td>
 &lt;td>Vitess、PlanetScale 與 application sharding 何時變成主線&lt;/td>
 &lt;td>跟其他 vendor 的取捨&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>替代路由&lt;/td>
 &lt;td>何時轉 PostgreSQL、Aurora、DynamoDB 或 distributed SQL&lt;/td>
 &lt;td>不適用場景、下一步路由&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="定位高併發簡單-sql--強分片生態">定位：高併發簡單 SQL + 強分片生態&lt;/h2>
&lt;p>MySQL 跟 PostgreSQL 是 SQL OLTP 兩大主流、但設計取捨明顯不同：&lt;/p>
&lt;ul>
&lt;li>MySQL 偏 &lt;em>簡單 query 效能 + 分片生態&lt;/em> — InnoDB clustered index 對 primary key range query 特別快、Vitess 提供超大規模透明 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/database-sharding/" data-link-title="Database Sharding" data-link-desc="說明資料庫如何依 shard key 分散資料、路由請求與承擔跨 shard 查詢成本">database sharding&lt;/a>&lt;/li>
&lt;li>PostgreSQL 偏 &lt;em>特性深度&lt;/em> — 詳見 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/vendors/postgresql/" data-link-title="PostgreSQL" data-link-desc="多用途 OLTP 主流關聯式資料庫、MVCC、豐富 SQL 特性、是 Aurora / Cosmos DB / Spanner / CockroachDB / Aurora DSQL 的相容目標">PostgreSQL vendor page&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>選 MySQL 的核心訴求：需要超大規模分片（&amp;gt; 100 TB、&amp;gt; 100K WPS）、簡單 query 為主、已用 MySQL 生態工具鏈（gh-ost、pt-online-schema-change）。&lt;/p>
&lt;h2 id="容量特性">容量特性&lt;/h2>
&lt;p>&lt;strong>單一 primary 寫吞吐&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>標準 InnoDB：10K-30K WPS（依 row size、commit sync、index 數量）&lt;/li>
&lt;li>高階 instance + 優化 schema：50K-100K WPS&lt;/li>
&lt;li>超過此級別 → &lt;a href="vitess-sharding/">Vitess sharding&lt;/a> 或 PlanetScale&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Connection 上限&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>預設 max_connections = 151、實務常設 1000-5000&lt;/li>
&lt;li>每個 connection thread stack ~3 MB + session buffer 累積、active 高峰時 ~8-10 MB（thread + sort/join buffer）&lt;/li>
&lt;li>仍建議 ProxySQL / connection pool 限制 backend connection 數&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Replication&lt;/strong>：&lt;/p></description><content:encoded><![CDATA[<p>MySQL 是大型網路服務的常見選擇、簡單 query 效能跟 <a href="/blog/backend/knowledge-cards/database-sharding/" data-link-title="Database Sharding" data-link-desc="說明資料庫如何依 shard key 分散資料、路由請求與承擔跨 shard 查詢成本">database sharding</a> 生態（Vitess / PlanetScale）成熟。GitHub、Shopify、Slack、Facebook（YouTube 從 MySQL 起家）等大規模服務的核心 OLTP 多採 MySQL。InnoDB engine 的 row-level lock、clustered index、buffer pool tuning 都被深度驗證。</p>
<h2 id="教學路線高併發-oltp-與分片生態">教學路線：高併發 OLTP 與分片生態</h2>
<p>MySQL 服務頁的教學目標是把「簡單 SQL 查詢」推進到高併發 OLTP、replication、online schema change 與 <a href="/blog/backend/knowledge-cards/database-sharding/" data-link-title="Database Sharding" data-link-desc="說明資料庫如何依 shard key 分散資料、路由請求與承擔跨 shard 查詢成本">sharding governance</a>。讀者讀完後要能判斷 MySQL 何時是成熟預設、何時已經進入 Vitess / PlanetScale 或 application sharding 的討論。</p>
<table>
  <thead>
      <tr>
          <th>學習段</th>
          <th>核心問題</th>
          <th>對應段落</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>OLTP 基線</td>
          <td>MySQL 適合哪種大量簡單查詢與交易路徑</td>
          <td>定位、適用場景</td>
      </tr>
      <tr>
          <td>Replication</td>
          <td>replica、failover、lag 與 read scaling 如何影響服務</td>
          <td>容量特性、容量規劃要點</td>
      </tr>
      <tr>
          <td>Schema change</td>
          <td>online schema change 與 migration 如何保護高流量服務</td>
          <td>容量規劃要點、預計實作話題</td>
      </tr>
      <tr>
          <td>Sharding</td>
          <td>Vitess、PlanetScale 與 application sharding 何時變成主線</td>
          <td>跟其他 vendor 的取捨</td>
      </tr>
      <tr>
          <td>替代路由</td>
          <td>何時轉 PostgreSQL、Aurora、DynamoDB 或 distributed SQL</td>
          <td>不適用場景、下一步路由</td>
      </tr>
  </tbody>
</table>
<h2 id="定位高併發簡單-sql--強分片生態">定位：高併發簡單 SQL + 強分片生態</h2>
<p>MySQL 跟 PostgreSQL 是 SQL OLTP 兩大主流、但設計取捨明顯不同：</p>
<ul>
<li>MySQL 偏 <em>簡單 query 效能 + 分片生態</em> — InnoDB clustered index 對 primary key range query 特別快、Vitess 提供超大規模透明 <a href="/blog/backend/knowledge-cards/database-sharding/" data-link-title="Database Sharding" data-link-desc="說明資料庫如何依 shard key 分散資料、路由請求與承擔跨 shard 查詢成本">database sharding</a></li>
<li>PostgreSQL 偏 <em>特性深度</em> — 詳見 <a href="/blog/backend/01-database/vendors/postgresql/" data-link-title="PostgreSQL" data-link-desc="多用途 OLTP 主流關聯式資料庫、MVCC、豐富 SQL 特性、是 Aurora / Cosmos DB / Spanner / CockroachDB / Aurora DSQL 的相容目標">PostgreSQL vendor page</a></li>
</ul>
<p>選 MySQL 的核心訴求：需要超大規模分片（&gt; 100 TB、&gt; 100K WPS）、簡單 query 為主、已用 MySQL 生態工具鏈（gh-ost、pt-online-schema-change）。</p>
<h2 id="容量特性">容量特性</h2>
<p><strong>單一 primary 寫吞吐</strong>：</p>
<ul>
<li>標準 InnoDB：10K-30K WPS（依 row size、commit sync、index 數量）</li>
<li>高階 instance + 優化 schema：50K-100K WPS</li>
<li>超過此級別 → <a href="vitess-sharding/">Vitess sharding</a> 或 PlanetScale</li>
</ul>
<p><strong>Connection 上限</strong>：</p>
<ul>
<li>預設 max_connections = 151、實務常設 1000-5000</li>
<li>每個 connection thread stack ~3 MB + session buffer 累積、active 高峰時 ~8-10 MB（thread + sort/join buffer）</li>
<li>仍建議 ProxySQL / connection pool 限制 backend connection 數</li>
</ul>
<p><strong>Replication</strong>：</p>
<ul>
<li>async / semi-sync / GTID-based</li>
<li>跨 AZ async lag 通常 &lt; 100ms</li>
<li>跨 region 通常用 chain replication 或 binlog 同步</li>
</ul>
<p><strong>Storage 上限</strong>：</p>
<ul>
<li>單一 table 64 TB（InnoDB 設計上限）</li>
<li>實務超過 1 TB 表建議分片</li>
</ul>
<h2 id="適用場景">適用場景</h2>
<p><strong>1. 大規模 OLTP + 分片需求</strong>：</p>
<ul>
<li>流量 &gt; 50K WPS、必須進入 <a href="/blog/backend/knowledge-cards/database-sharding/" data-link-title="Database Sharding" data-link-desc="說明資料庫如何依 shard key 分散資料、路由請求與承擔跨 shard 查詢成本">database sharding</a> 設計</li>
<li>用 Vitess / PlanetScale 透明 sharding、應用層幾乎不必改</li>
<li>對應產業：超大網路服務（GitHub、Shopify、Slack）</li>
</ul>
<p><strong>2. 簡單 query 為主</strong>：</p>
<ul>
<li>primary key lookup、簡單 range query</li>
<li>不太用 CTE、window function、複雜 JOIN</li>
<li>InnoDB clustered index 對這類 workload 特別快</li>
</ul>
<p><strong>3. 既有 MySQL 生態工具</strong>：</p>
<ul>
<li>gh-ost / pt-online-schema-change（online schema migration）</li>
<li>Orchestrator（HA topology 管理）</li>
<li>ProxySQL（query routing + connection pool）</li>
<li>Maxwell / Debezium MySQL（<a href="/blog/backend/knowledge-cards/change-data-capture/" data-link-title="Change Data Capture" data-link-desc="說明資料變更如何被捕捉並傳送到其他系統">CDC</a>）</li>
</ul>
<p><strong>4. 強一致 transaction 但容忍部分 SQL 功能缺失</strong>：</p>
<ul>
<li>不需 partial index、不需 JSONB indexing</li>
<li>不需 PostGIS、用 spatial extension 夠</li>
</ul>
<p><strong>5. Aurora MySQL（managed 路徑）</strong>：</p>
<ul>
<li>從自管 MySQL 上 AWS、保留 wire protocol</li>
<li>詳見 <a href="/blog/backend/01-database/vendors/aurora/" data-link-title="AWS Aurora" data-link-desc="AWS managed PostgreSQL / MySQL、storage / compute 分離、&#43;75% 效能改善的 production 證據">Aurora vendor page</a></li>
</ul>
<h2 id="不適用場景">不適用場景</h2>
<p><strong>1. 需要 PostgreSQL 等級的 SQL / JSON 特性</strong>：</p>
<ul>
<li>複雜 CTE、recursive query、window function</li>
<li>JSON Schema validation、JSONB GIN indexing</li>
<li>PostGIS 等深度 extension</li>
</ul>
<p><strong>2. 全球 multi-region active-active write</strong>：</p>
<ul>
<li>MySQL 設計是 single primary、跨 region 是 async</li>
<li>替代：Aurora DSQL、Spanner、Vitess multi-cluster</li>
</ul>
<p><strong>3. 大規模 OLAP</strong>：</p>
<ul>
<li>MySQL 定位在 OLTP，analytics workload 交給 OLAP 系統</li>
<li>替代：ClickHouse、BigQuery、Snowflake</li>
</ul>
<p><strong>4. KV 簡單查詢 + sub-10ms p99</strong>：</p>
<ul>
<li>跟 PostgreSQL 一樣有 parsing / planning 開銷</li>
<li>替代：DynamoDB、Redis</li>
</ul>
<h2 id="跟其他-vendor-的取捨">跟其他 vendor 的取捨</h2>
<p><strong>vs PostgreSQL</strong>：</p>
<ul>
<li>詳見 <a href="/blog/backend/01-database/vendors/postgresql/" data-link-title="PostgreSQL" data-link-desc="多用途 OLTP 主流關聯式資料庫、MVCC、豐富 SQL 特性、是 Aurora / Cosmos DB / Spanner / CockroachDB / Aurora DSQL 的相容目標">PostgreSQL vendor page</a> 對比段</li>
<li>摘要：MySQL 適合超大規模分片、PostgreSQL 適合進階 SQL 特性</li>
</ul>
<p><strong>vs Aurora MySQL（同 wire protocol）</strong>：</p>
<ul>
<li>MySQL（自管 / RDS）：可跨雲、彈性高</li>
<li>Aurora MySQL：AWS managed、storage / compute 分離、更多 read replica</li>
<li>選自管 MySQL：跨雲需求、預算敏感</li>
<li>選 Aurora MySQL：AWS 生態深、需要 storage scaling</li>
</ul>
<p><strong>vs PlanetScale（Vitess managed）</strong>：</p>
<ul>
<li>MySQL（自管 + Vitess）：完全控制、可自管分片</li>
<li>PlanetScale：managed Vitess、branch-based schema migration</li>
<li>選 MySQL + Vitess：team 有能力管 Vitess、預算敏感</li>
<li>選 PlanetScale：想 zero ops、branch-based workflow</li>
</ul>
<p><strong>vs TiDB</strong>：</p>
<ul>
<li>MySQL：single-primary、傳統分片靠 Vitess</li>
<li>TiDB：MySQL wire protocol 相容、HTAP（OLTP + OLAP 同庫）、跨 region 強一致</li>
<li>選 MySQL：已有 MySQL 投資、不想換引擎</li>
<li>選 TiDB：需要跨 region 強一致 + OLAP 同庫</li>
</ul>
<p><strong>vs Vitess（self-managed sharding layer）</strong>：</p>
<ul>
<li>Vitess 本質是 MySQL 上層的 sharding layer</li>
<li>由 YouTube 設計、捐贈 CNCF</li>
<li>適合超大規模 MySQL 集群、需要透明 sharding</li>
</ul>
<p><strong>vs DynamoDB（document/KV 替代）</strong>：</p>
<ul>
<li>MySQL：SQL、有 transaction、ad-hoc query、connection-based</li>
<li>DynamoDB：KV、partition 透明、無 connection 限制、5 個 9 SLA</li>
<li>選 MySQL：需要 ad-hoc query、複雜 JOIN、SQL transaction</li>
<li>選 DynamoDB：access pattern 固定、AWS-only、想避免 connection limit 問題</li>
<li>詳見 <a href="/blog/backend/01-database/kv-document-capacity-planning/" data-link-title="1.10 KV / Document DB 容量規劃" data-link-desc="DynamoDB / Cosmos DB / Bigtable / MongoDB 等 KV / Document DB 的容量設計、partition key 取捨、capacity mode 選擇">1.10 KV / Document DB 容量規劃</a> 的 connection model 對比</li>
</ul>
<p><strong>vs Spanner / CockroachDB / Aurora DSQL（distributed SQL）</strong>：</p>
<ul>
<li>MySQL + Vitess：自管 sharding、operational 重、跨雲可用</li>
<li>Spanner / CockroachDB / Aurora DSQL：分散式 SQL、跨 region 強一致、transparent sharding</li>
<li>選 MySQL + Vitess：已有 MySQL 投資、有能力管 Vitess、預算敏感</li>
<li>選 distributed SQL：需要 multi-region 強一致、不想自管 sharding</li>
<li>詳見 <a href="/blog/backend/01-database/global-distributed-oltp/" data-link-title="1.11 全球分散式 OLTP" data-link-desc="Spanner / Aurora DSQL / Cosmos DB multi-region write / CockroachDB / TiDB 的全球一致性取捨">1.11 全球分散式 OLTP</a></li>
</ul>
<p><strong>vs MongoDB（document 替代）</strong>：</p>
<ul>
<li>MySQL：SQL + JSON column 補充</li>
<li>MongoDB：document 為主、aggregation pipeline 強、schema-flexible</li>
<li>選 MySQL：主要結構化、少量半結構化</li>
<li>選 MongoDB：document 占主要 schema、aggregation 工作負載</li>
</ul>
<h2 id="容量規劃要點">容量規劃要點</h2>
<p><strong>1. Sharding 是 MySQL 大規模的核心</strong>：</p>
<ul>
<li>單一 MySQL primary 寫吞吐有上限</li>
<li>Vitess / PlanetScale 用 keyspace + shard 切分</li>
<li>shard key 設計類似 DynamoDB partition key — 必須均勻</li>
<li>大規模案例：Shopify（多 shard 分散）、Slack（per-team sharding）</li>
</ul>
<p><strong>2. Online schema change 是必備</strong>：</p>
<ul>
<li>ALTER TABLE 直接跑會 lock 整個 table</li>
<li>gh-ost（GitHub）/ pt-online-schema-change（Percona）/ Vitess online DDL 用 ghost table 漸進 migrate</li>
<li>大表 schema change 可能跑 hours / days、要排程</li>
</ul>
<p><strong>3. Replication 跟 GTID</strong>：</p>
<ul>
<li>GTID-based replication 比 binlog position 容易管 topology</li>
<li>semi-sync replication 保證至少一個 standby ack 才 commit</li>
<li>async replication 高吞吐但 lag 較大</li>
</ul>
<p><strong>4. Connection management</strong>：</p>
<ul>
<li>ProxySQL 是 MySQL 生態的 connection pool 標準</li>
<li>提供 query routing（讀 → replica、寫 → primary）</li>
<li>對應 <a href="/blog/backend/09-performance-capacity/cases/ntt-docomo-lemino-japanese-streaming/" data-link-title="9.C29 NTT DOCOMO Lemino：3 個月達 500 萬 MAU 的串流後端" data-link-desc="Lemino 用 DynamoDB &#43; AWS Media Services 撐 30 channels live &#43; 5M MAU、工程工時下降 90%">9.C29 Lemino case</a> — RDB connection limit 議題對 MySQL 同樣適用</li>
</ul>
<p><strong>5. InnoDB tuning</strong>：</p>
<ul>
<li>innodb_buffer_pool_size：dedicated server 70-75%、shared server 30-50%（詳見 <a href="innodb-tuning/">InnoDB Tuning</a>）</li>
<li>innodb_flush_log_at_trx_commit：1（durable）vs 2（faster）vs 0（fastest, 不安全）</li>
<li>innodb_io_capacity：依 storage 類型調整</li>
</ul>
<h2 id="anti-recommendation-與升級路由">Anti-recommendation 與升級路由</h2>
<p>MySQL 的成熟生態容易讓讀者過早引入重工具。這一段補上 deep article audit 提到的 anti-recommendation 缺口：先說何時維持簡單 MySQL 路徑，再說何時升級到 ProxySQL、Orchestrator、gh-ost、Vitess、PlanetScale 或 distributed SQL。</p>
<table>
  <thead>
      <tr>
          <th>機制</th>
          <th>維持簡單設計的條件</th>
          <th>升級訊號</th>
          <th>主要引用路徑</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Replication</td>
          <td>單 primary + 1-2 replica，lag 可被 read routing 容忍</td>
          <td>failover 反覆手動、GTID gap、semi-sync fallback</td>
          <td><a href="replication-topology/">Replication Topology</a>、<a href="orchestrator-failover/">Orchestrator Failover</a></td>
      </tr>
      <tr>
          <td>Online schema change</td>
          <td>小表、maintenance window 足夠、MySQL 8.0 instant DDL 可 cover</td>
          <td>大表 ALTER 需 hours、metadata lock 影響 production</td>
          <td><a href="online-schema-change-tools/">Online Schema Change Tools</a>、<a href="/blog/backend/06-reliability/migration-safety/" data-link-title="6.11 Migration Safety 與 DB Rollout" data-link-desc="把 schema migration 從一次性事件變成可逆、可漸進的 rollout 流程">6.11 Migration Safety</a></td>
      </tr>
      <tr>
          <td>ProxySQL</td>
          <td>application pool + primary endpoint 已能控制連線</td>
          <td>read/write routing、lag-aware routing、connection storm</td>
          <td><a href="proxysql-config/">ProxySQL Config</a>、<a href="/blog/backend/knowledge-cards/connection-pool/" data-link-title="Connection Pool" data-link-desc="說明連線池如何限制下游資源並影響服務容量">Connection Pool</a></td>
      </tr>
      <tr>
          <td>Vitess / sharding</td>
          <td>單 primary 寫入與資料量仍在可維護範圍</td>
          <td>&gt; 50K WPS、&gt; 100 TB、shard key 已明確、跨 shard query 可接受</td>
          <td><a href="vitess-sharding/">Vitess Sharding</a>、<a href="/blog/backend/knowledge-cards/database-sharding/" data-link-title="Database Sharding" data-link-desc="說明資料庫如何依 shard key 分散資料、路由請求與承擔跨 shard 查詢成本">Database Sharding</a></td>
      </tr>
      <tr>
          <td>PlanetScale</td>
          <td>團隊已有 DBA / SRE 能力管理 Vitess 或自管 MySQL</td>
          <td>想把 Vitess ops、schema branch workflow 與 failover 交給平台</td>
          <td><a href="migrate-to-planetscale/">→ PlanetScale</a>、<a href="migrate-vitess-to-planetscale/">Vitess → PlanetScale</a></td>
      </tr>
      <tr>
          <td>Distributed SQL</td>
          <td>workload 仍是 single-region OLTP 或 Vitess 可解</td>
          <td>multi-region 強一致、cross-shard transaction 是核心需求</td>
          <td><a href="/blog/backend/01-database/global-distributed-oltp/" data-link-title="1.11 全球分散式 OLTP" data-link-desc="Spanner / Aurora DSQL / Cosmos DB multi-region write / CockroachDB / TiDB 的全球一致性取捨">1.11 全球分散式 OLTP</a></td>
      </tr>
  </tbody>
</table>
<p>Replication 的簡單路徑是 GTID + async replica + 明確 read routing。當 failover 仍靠人工判斷、replica re-pointing 反覆出錯、或 semi-sync fallback 沒有被監控時，才需要把 Orchestrator、ProxySQL 與 incident runbook 放進同一條 HA 路徑。</p>
<p>Online schema change 的簡單路徑是先判斷 MySQL 8.0 instant / inplace DDL 能否 cover。只有大表 rewrite、長時間 metadata lock、FK / trigger 複雜互動或 maintenance window 不足時，才讓 gh-ost / pt-online-schema-change 成為主線工具。</p>
<p>Sharding 的簡單路徑是延後到資料形狀穩定後再做。Vitess 能把 MySQL 推到超大規模，但它也引入 VTGate、VTTablet、VReplication、VSchema、resharding workflow 與跨 shard transaction 邊界；<a href="/blog/backend/knowledge-cards/database-sharding/" data-link-title="Database Sharding" data-link-desc="說明資料庫如何依 shard key 分散資料、路由請求與承擔跨 shard 查詢成本">shard key</a> 還沒穩定時，應先用 schema、index、read replica、partition 與容量治理延長單 primary 壽命。</p>
<p>Managed sharding 的簡單路徑是先確認團隊想轉移哪一層責任。PlanetScale 解的是 Vitess operation、branch-based schema workflow 與 managed failover；FK、cross-shard query、connection pool 與 cost model 仍要在 migration playbook 中驗證。</p>
<h2 id="deep-article--migration-playbook已完成">Deep article + Migration playbook（已完成）</h2>
<table>
  <thead>
      <tr>
          <th>主題</th>
          <th>文章</th>
          <th>類型</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Replication topology（async / semi-sync / GTID）配置</td>
          <td><a href="replication-topology/">replication-topology</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>gh-ost / pt-online-schema-change 對比</td>
          <td><a href="online-schema-change-tools/">online-schema-change-tools</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>ProxySQL 配置跟 query routing</td>
          <td><a href="proxysql-config/">proxysql-config</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>Orchestrator failover 設計</td>
          <td><a href="orchestrator-failover/">orchestrator-failover</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>InnoDB tuning（buffer pool / log / IO）</td>
          <td><a href="innodb-tuning/">innodb-tuning</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>Binary log + Maxwell / Debezium CDC</td>
          <td><a href="binlog-cdc/">binlog-cdc</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>Vitess sharding 設計</td>
          <td><a href="vitess-sharding/">vitess-sharding</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>8.0 modern SQL（CTE / window / JSON_TABLE）</td>
          <td><a href="modern-sql-features/">modern-sql-features</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>Group Replication / InnoDB Cluster 部署</td>
          <td><a href="group-replication/">group-replication</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>Query optimization deep dive</td>
          <td><a href="query-optimization/">query-optimization</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>Partitioning（range / list / hash / sub-partition）</td>
          <td><a href="partitioning/">partitioning</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>PITR + Backup strategy</td>
          <td><a href="pitr-backup/">pitr-backup</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>Lock contention（gap / next-key / deadlock）</td>
          <td><a href="lock-contention/">lock-contention</a></td>
          <td>Deep article</td>
      </tr>
      <tr>
          <td>Hands-on 操作路線</td>
          <td><a href="hands-on/">hands-on</a></td>
          <td>操作型章節群</td>
      </tr>
      <tr>
          <td>5.7 → 8.0 major version upgrade</td>
          <td><a href="major-version-upgrade/">major-version-upgrade</a></td>
          <td>Migration playbook（Type E）</td>
      </tr>
      <tr>
          <td>從自管 MySQL 遷到 Aurora MySQL</td>
          <td><a href="migrate-to-aurora/">migrate-to-aurora</a></td>
          <td>Migration playbook（Type C）</td>
      </tr>
      <tr>
          <td>從自管 MySQL 遷到 PlanetScale</td>
          <td><a href="migrate-to-planetscale/">migrate-to-planetscale</a></td>
          <td>Migration playbook（Type E）</td>
      </tr>
      <tr>
          <td>自管 Vitess 遷到 PlanetScale</td>
          <td><a href="migrate-vitess-to-planetscale/">migrate-vitess-to-planetscale</a></td>
          <td>Migration playbook（Type C）</td>
      </tr>
      <tr>
          <td>從 MySQL 遷到 PostgreSQL</td>
          <td><a href="migrate-to-postgresql/">migrate-to-postgresql</a></td>
          <td>Migration playbook</td>
      </tr>
  </tbody>
</table>
<h2 id="補充正文路由">補充正文路由</h2>
<p>當前 deep article、migration playbook、補充正文與 hands-on 已 cover ops / schema / failover / tuning / SQL features / sharding / backup / migration / security / audit / document / OLAP / memory / metadata lock 等維度。下列補充正文用來承接 overview 中提到的延伸議題：</p>
<ul>
<li><strong><a href="encryption-tls-key-management/">Encryption at rest + TLS in transit + key management</a></strong>：對應 PG TLS-mTLS 議題</li>
<li><strong><a href="audit-log-siem/">Audit log + SIEM 整合</a></strong>：MySQL Enterprise Audit Plugin 跟 Splunk / Elastic Security 整合</li>
<li><strong><a href="document-store-x-protocol/">MySQL Document Store（X-Protocol）</a></strong>：少用但對特定 use case 有興趣</li>
<li><strong><a href="multi-source-replication/">Multi-source replication topology</a></strong>：1 個 replica 從 N 個 primary 拉、用於 sharded environment 整合</li>
<li><strong><a href="heatwave-olap-addon/">HeatWave（MySQL OLAP add-on）</a></strong>：Oracle 推的 HTAP solution、跟 ClickHouse / Snowflake 對比</li>
<li><strong><a href="cross-buffer-memory-contention/">Cross-buffer memory contention deep dive</a></strong>：buffer pool / connection thread / temp table / sort buffer 之間的 RAM 競爭、跟 OS swap 互動</li>
<li><strong><a href="metadata-lock-deep-dive/">Metadata lock deep dive</a></strong>：DDL / long-running SELECT / FK 互動造成的 stalls</li>
</ul>
<p>上述補充篇已完成正文，並保留既有路由。Encryption / TLS / key management 接 <a href="/blog/backend/knowledge-cards/tls-mtls/" data-link-title="TLS / mTLS" data-link-desc="說明傳輸加密與雙向憑證驗證如何保護跨邊界資料流">TLS / mTLS</a> 與 <a href="/blog/backend/knowledge-cards/secret-management/" data-link-title="Secret Management" data-link-desc="說明 token、key、password 與憑證如何保存、輪替與撤銷">Secret Management</a>；audit log 接 <a href="/blog/backend/knowledge-cards/audit-log/" data-link-title="Audit Log" data-link-desc="說明高風險操作如何留下可追溯、可稽核的紀錄">Audit Log</a> 與 07 資安資料保護；Document Store 接 <a href="/blog/backend/01-database/vendors/mongodb/" data-link-title="MongoDB" data-link-desc="Document database 代表、Atlas managed、跨雲可用、許多大規模平台從 MongoDB 起家">MongoDB vendor</a> 與 <a href="/blog/backend/01-database/kv-document-capacity-planning/" data-link-title="1.10 KV / Document DB 容量規劃" data-link-desc="DynamoDB / Cosmos DB / Bigtable / MongoDB 等 KV / Document DB 的容量設計、partition key 取捨、capacity mode 選擇">1.10 KV / Document DB 容量規劃</a>；multi-source replication 接 <a href="replication-topology/">Replication Topology</a>；HeatWave 接 OLAP 替代路由；memory contention 接 <a href="innodb-tuning/">InnoDB Tuning</a>；metadata lock 接 <a href="lock-contention/">Lock Contention</a> 與 <a href="online-schema-change-tools/">Online Schema Change Tools</a>。</p>
<h2 id="已知-limitation多輪-audit-結論">已知 limitation（多輪 audit 結論）</h2>
<p>17 篇 batch 跑過 4-reviewer audit（寫作規範 / 跨檔一致性 / 技術準確性 / 結構性質疑）後留下的 limitation：</p>
<ul>
<li><em>Framework bias</em>：5 篇 migration playbook 全落在 Type A / C / E、沒一篇 Type B / D / F。這反映 <em>MySQL 領域 migration 的本質</em>（多數情境是 schema 差 / operational 轉手 / paradigm shift）、也可能反映 <a href="/blog/posts/migration-playbook-%E6%96%B9%E6%B3%95%E8%AB%96%E7%9A%84%E6%BC%94%E5%8C%96%E7%B4%80%E9%8C%84stage-0-variant-%E8%A6%8F%E5%8A%83%E6%8A%8A-collapse-%E7%8E%87%E5%BE%9E-60-%E9%99%8D%E5%88%B0-0/" data-link-title="Migration Playbook 方法論的演化紀錄：Stage 0 variant 規劃把 collapse 率從 60% 降到 0%" data-link-desc="跨 vendor migration playbook 需要獨立寫作方法論的依據，以及這套方法論從三輪 batch dogfood 中演化出來的驗證證據。">6 type framework</a> 的覆蓋限制</li>
<li><em>Anti-recommendation 已補 overview 路由</em>：本頁新增「Anti-recommendation 與升級路由」作為總入口；各 deep article 之後仍可逐篇補「何時維持簡單設計」段。</li>
<li><em>Real case anchor 已下沉</em>：本頁「真實案例 anchor」把 Shopify、Slack、GitHub gh-ost、YouTube / Vitess 與既有 09 case 串回 deep article；Shopify CDC、gh-ost workflow、YouTube / Vitess 與 Netflix Aurora consolidation 已補到對應 deep article 的 production case 段。</li>
<li><em>PG 對比 narrative</em>：對比段公允度尚可、但 PG 弱點（vacuum ops 開銷 / connection-per-process model / replication slot 治理）較少在 MySQL 視角展開、單方面對比偶有偏 MySQL 不利</li>
</ul>
<h2 id="案例對照">案例對照</h2>
<p>MySQL 沒有直接的 09 case（大規模 MySQL 多在 engineering blog、不在 vendor case study）、但作為 baseline / 遷移源 在多處出現：</p>
<table>
  <thead>
      <tr>
          <th>案例</th>
          <th>跟 MySQL 的關係</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix Aurora consolidation</a></td>
          <td>從多套 RDBMS（含 MySQL）統一到 Aurora MySQL</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/zomato-tidb-to-dynamodb-migration/" data-link-title="9.C20 Zomato：從 TiDB 遷移到 DynamoDB、吞吐 4 倍、延遲降 90%、成本減 50%" data-link-desc="Zomato 帳單系統從 TiDB 遷移到 DynamoDB、吞吐 2K→8K RPM、延遲降 90%、成本減 50%">9.C20 Zomato TiDB → DynamoDB</a></td>
          <td>TiDB（MySQL 相容）→ DynamoDB 對比</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/ntt-docomo-lemino-japanese-streaming/" data-link-title="9.C29 NTT DOCOMO Lemino：3 個月達 500 萬 MAU 的串流後端" data-link-desc="Lemino 用 DynamoDB &#43; AWS Media Services 撐 30 channels live &#43; 5M MAU、工程工時下降 90%">9.C29 Lemino RDB connection limit</a></td>
          <td>MySQL connection 限制問題（同 PostgreSQL）</td>
      </tr>
  </tbody>
</table>
<h2 id="真實案例-anchor">真實案例 anchor</h2>
<p>MySQL 真實案例的責任是把大規模 OLTP 的機制壓力放回正文。案例不只證明「某公司使用 MySQL」，而是提供 schema change、CDC、sharding、connection、queue 整合或 managed migration 的壓力來源。</p>
<table>
  <thead>
      <tr>
          <th>案例 / 來源</th>
          <th>回收的工程訊號</th>
          <th>對應正文路由</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/03-message-queue/cases/kafka-shopify-debezium-cdc/" data-link-title="3.C13 Shopify：Debezium CDC over sharded MySQL" data-link-desc="Shopify 100&#43; MySQL shard、150 Debezium connector、Black Friday 100K records/sec P99 &lt; 10s。">Shopify Debezium CDC over sharded MySQL</a></td>
          <td>100+ shard、~150 Debezium connector、BFCM 100K records/sec、snapshot lock 與 oversized payload</td>
          <td><a href="binlog-cdc/">Binary Log + CDC</a>、<a href="/blog/backend/knowledge-cards/database-sharding/" data-link-title="Database Sharding" data-link-desc="說明資料庫如何依 shard key 分散資料、路由請求與承擔跨 shard 查詢成本">Database Sharding</a>、<a href="/blog/backend/03-message-queue/vendors/kafka/" data-link-title="Apache Kafka" data-link-desc="Distributed event streaming platform、log-based 模型">Kafka vendor</a></td>
      </tr>
      <tr>
          <td><a href="/blog/backend/03-message-queue/cases/slack-job-queue-kafka-redis/" data-link-title="3.C5 Slack：Job Queue 演進到 Kafka &#43; Redis" data-link-desc="背景工作通道在成長期如何從單一路徑演進成組合式架構。">Slack Job Queue 演進到 Kafka + Redis</a></td>
          <td>成長期把背景工作拆成多條傳遞路徑，揭露單一資料路徑與 queue 路徑分工</td>
          <td>MySQL 只承擔 OLTP <a href="/blog/backend/knowledge-cards/source-of-truth/" data-link-title="Source of Truth" data-link-desc="說明正式資料來源如何決定資料判斷、修復與一致性責任">source of truth</a>；queue / cache 路徑回 <a href="/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">03 Message Queue</a></td>
      </tr>
      <tr>
          <td>gh-ost / GitHub operation workflow</td>
          <td>大表 schema change 需要 throttle、pause / resume、cutover 控制</td>
          <td><a href="online-schema-change-tools/">Online Schema Change Tools</a></td>
      </tr>
      <tr>
          <td>YouTube / Vitess</td>
          <td>MySQL sharding layer 需要 VTGate、VTTablet、VReplication、VSchema</td>
          <td><a href="vitess-sharding/">Vitess Sharding</a>、<a href="/blog/backend/knowledge-cards/database-sharding/" data-link-title="Database Sharding" data-link-desc="說明資料庫如何依 shard key 分散資料、路由請求與承擔跨 shard 查詢成本">Database Sharding</a>、<a href="migrate-to-planetscale/">→ PlanetScale</a></td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix Aurora consolidation</a></td>
          <td>多套 RDBMS 整併到 managed Aurora，揭露 operation transfer driver</td>
          <td><a href="migrate-to-aurora/">→ Aurora</a>、<a href="/blog/backend/01-database/vendors/aurora/" data-link-title="AWS Aurora" data-link-desc="AWS managed PostgreSQL / MySQL、storage / compute 分離、&#43;75% 效能改善的 production 證據">Aurora vendor</a></td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/ntt-docomo-lemino-japanese-streaming/" data-link-title="9.C29 NTT DOCOMO Lemino：3 個月達 500 萬 MAU 的串流後端" data-link-desc="Lemino 用 DynamoDB &#43; AWS Media Services 撐 30 channels live &#43; 5M MAU、工程工時下降 90%">9.C29 Lemino RDB connection limit</a></td>
          <td>surge 場景 connection limit 讓 RDB 退到 DynamoDB 類 access pattern</td>
          <td><a href="proxysql-config/">ProxySQL Config</a>、<a href="/blog/backend/01-database/kv-document-capacity-planning/" data-link-title="1.10 KV / Document DB 容量規劃" data-link-desc="DynamoDB / Cosmos DB / Bigtable / MongoDB 等 KV / Document DB 的容量設計、partition key 取捨、capacity mode 選擇">1.10 KV / Document DB 容量規劃</a></td>
      </tr>
  </tbody>
</table>
<p>案例下沉規則是先放 overview，再進 deep article。當某個案例只支撐服務定位，留在本頁；當案例提供具體操作訊號，例如 Shopify 的 Debezium connector scaling、GitHub 的 gh-ost workflow 或 YouTube 的 Vitess topology，對應 deep article 要保留 production case 段、讓讀者能從機制直接跳到案例。</p>
<h2 id="常見陷阱">常見陷阱</h2>
<ul>
<li><strong>直接 ALTER TABLE 大表</strong>：lock 表 hours、production 停擺、必須用 online schema change</li>
<li><strong>不用 GTID</strong>：replication topology 變更困難、recover from failure 容易出錯</li>
<li><strong>buffer pool 太小</strong>：cache miss 高、IOPS 飆升</li>
<li><strong>shard key 選錯</strong>：hot shard 出現、整體吞吐達不到名義</li>
<li><strong>connection 沒 pool</strong>：跟 PostgreSQL 同樣問題、用 ProxySQL</li>
<li><strong>semi-sync 對高吞吐 workload</strong>：每次 commit 等 ack、寫吞吐降一半</li>
</ul>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>完整 T1 對照：<a href="/blog/backend/01-database/vendors/" data-link-title="資料庫 Vendor 清單" data-link-desc="規劃 SQL、managed SQL、document、KV 與 distributed SQL 的服務頁撰寫順序與教學大綱">01-database vendors index</a></li>
<li>平行：<a href="/blog/backend/01-database/vendors/postgresql/" data-link-title="PostgreSQL" data-link-desc="多用途 OLTP 主流關聯式資料庫、MVCC、豐富 SQL 特性、是 Aurora / Cosmos DB / Spanner / CockroachDB / Aurora DSQL 的相容目標">PostgreSQL vendor</a>、<a href="/blog/backend/01-database/vendors/aurora/" data-link-title="AWS Aurora" data-link-desc="AWS managed PostgreSQL / MySQL、storage / compute 分離、&#43;75% 效能改善的 production 證據">Aurora vendor</a>（managed MySQL）</li>
<li>操作：<a href="/blog/backend/01-database/vendors/mysql/hands-on/" data-link-title="MySQL Hands-on 操作路線" data-link-desc="MySQL local lab、ProxySQL routing、online schema change、replication failover、backup restore 與 Vitess sandbox 的操作型章節設計">MySQL Hands-on</a>（local lab、ProxySQL、OSC、replication failover、backup restore、Vitess sandbox）</li>
<li>上游：<a href="/blog/backend/01-database/high-concurrency-access/" data-link-title="1.1 高併發下的 SQL 讀寫邊界" data-link-desc="說明高併發服務如何共用資料庫 client、控制 transaction、管理 connection pool、避免資料庫成為瓶頸">1.1 高併發資料存取</a>、<a href="/blog/backend/01-database/transaction-boundary/" data-link-title="1.3 Transaction 與一致性邊界" data-link-desc="交易邊界、isolation level、retry 策略、distributed transaction（2PC、Saga）與跨 region 強一致取捨">1.3 Transaction Boundary</a></li>
<li>下游：<a href="/blog/backend/01-database/kv-document-capacity-planning/" data-link-title="1.10 KV / Document DB 容量規劃" data-link-desc="DynamoDB / Cosmos DB / Bigtable / MongoDB 等 KV / Document DB 的容量設計、partition key 取捨、capacity mode 選擇">1.10 KV / Document DB 容量規劃</a>（MySQL 不適用時的替代）</li>
<li>跨模組：<a href="/blog/backend/09-performance-capacity/bottleneck-localization/" data-link-title="9.5 瓶頸定位流程" data-link-desc="從 app 到 DB / cache / broker / 第三方 quota 的逐層瓶頸定位">9.5 瓶頸定位流程</a> — connection / replication / lock contention 常見 MySQL bottleneck</li>
<li>官方：<a href="https://dev.mysql.com/doc/">MySQL Documentation</a>、<a href="https://vitess.io/">Vitess</a>、<a href="https://planetscale.com/">PlanetScale</a></li>
</ul>
]]></content:encoded></item><item><title>CockroachDB</title><link>https://tarrragon.github.io/blog/backend/01-database/vendors/cockroachdb/</link><pubDate>Wed, 13 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/01-database/vendors/cockroachdb/</guid><description>&lt;p>CockroachDB 是分散式 SQL、PostgreSQL wire protocol 相容、跨 region 強一致。設計理念接近 Spanner（線性化、跨 region &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/quorum/" data-link-title="Quorum" data-link-desc="分散式系統以多數節點同意作為提交或讀取有效性的門檻">quorum&lt;/a>），但採 HLC + Raft 而非 TrueTime hardware，是 open source + 跨雲可用的全球 OLTP 選擇。&lt;/p>
&lt;h2 id="教學路線distributed-sql-與跨雲一致性">教學路線：Distributed SQL 與跨雲一致性&lt;/h2>
&lt;p>CockroachDB 服務頁的教學目標是把 PostgreSQL-like 介面背後的 range sharding、Raft replication、serializable transaction、leaseholder 與 region placement 說清楚。讀者讀完後要能判斷 distributed SQL 何時能取代自管 sharding，何時會把 latency 與 retry 壓力推回應用層。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>學習段&lt;/th>
 &lt;th>核心問題&lt;/th>
 &lt;th>對應段落&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Distributed SQL&lt;/td>
 &lt;td>SQL 介面如何藏住 range sharding 與 Raft replication&lt;/td>
 &lt;td>定位、容量特性&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Serializable default&lt;/td>
 &lt;td>transaction retry、contention、latency 如何影響應用設計&lt;/td>
 &lt;td>容量規劃要點、&lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/isolation-level/" data-link-title="Isolation Level" data-link-desc="說明資料庫交易隔離級別如何影響並發讀寫結果">Isolation Level&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Region placement&lt;/td>
 &lt;td>multi-region table、leaseholder、survival goal 如何服務產品需求&lt;/td>
 &lt;td>適用場景、跟其他 vendor 的取捨&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Migration pressure&lt;/td>
 &lt;td>從 PostgreSQL / MySQL 或自管 sharding 過來時要檢查哪些差異&lt;/td>
 &lt;td>預計實作話題、案例對照&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>替代路由&lt;/td>
 &lt;td>何時留 PostgreSQL、用 Spanner、Aurora DSQL 或 application sharding&lt;/td>
 &lt;td>不適用場景、下一步路由&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="定位spanner-的開源--跨雲替代">定位：Spanner 的開源 / 跨雲替代&lt;/h2>
&lt;p>CockroachDB 跟 Spanner 解決同一個問題（跨 region 強一致 SQL）、但定位不同：&lt;/p>
&lt;ul>
&lt;li>Spanner：GCP managed service、用 TrueTime hardware&lt;/li>
&lt;li>CockroachDB：開源（雙授權）、可自管 + Cockroach Cloud、跨 AWS / GCP / Azure / on-prem、用 HLC + Raft&lt;/li>
&lt;/ul>
&lt;p>選 CockroachDB 的核心訴求：需要跨 region 強一致 SQL + 想避免雲商 lock-in、想自管或跨雲部署。&lt;/p>
&lt;p>詳見 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/global-distributed-oltp/" data-link-title="1.11 全球分散式 OLTP" data-link-desc="Spanner / Aurora DSQL / Cosmos DB multi-region write / CockroachDB / TiDB 的全球一致性取捨">1.11 全球分散式 OLTP&lt;/a> 的 CockroachDB 段。&lt;/p>
&lt;h2 id="容量特性">容量特性&lt;/h2>
&lt;p>&lt;strong>節點即容量單位&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>跟 Spanner 同樣設計、節點數量決定容量&lt;/li>
&lt;li>每節點承擔 query + storage + replication&lt;/li>
&lt;li>線性擴展（理論）、實際依 query pattern&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>跨 region 配置&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>multi-region survival goal（zone-level / region-level）&lt;/li>
&lt;li>跨 region quorum 必要、決定 latency&lt;/li>
&lt;li>跟 Spanner 同樣的物理限制（跨洲 100ms+）&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Replication&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>Raft consensus per range&lt;/li>
&lt;li>預設 3-replica&lt;/li>
&lt;li>可配置每個 region 不同 replica count（Survival Goals）&lt;/li>
&lt;/ul>
&lt;h2 id="適用場景">適用場景&lt;/h2>
&lt;p>&lt;strong>1. 需要跨 region 強一致 SQL + 跨雲&lt;/strong>：&lt;/p></description><content:encoded><![CDATA[<p>CockroachDB 是分散式 SQL、PostgreSQL wire protocol 相容、跨 region 強一致。設計理念接近 Spanner（線性化、跨 region <a href="/blog/backend/knowledge-cards/quorum/" data-link-title="Quorum" data-link-desc="分散式系統以多數節點同意作為提交或讀取有效性的門檻">quorum</a>），但採 HLC + Raft 而非 TrueTime hardware，是 open source + 跨雲可用的全球 OLTP 選擇。</p>
<h2 id="教學路線distributed-sql-與跨雲一致性">教學路線：Distributed SQL 與跨雲一致性</h2>
<p>CockroachDB 服務頁的教學目標是把 PostgreSQL-like 介面背後的 range sharding、Raft replication、serializable transaction、leaseholder 與 region placement 說清楚。讀者讀完後要能判斷 distributed SQL 何時能取代自管 sharding，何時會把 latency 與 retry 壓力推回應用層。</p>
<table>
  <thead>
      <tr>
          <th>學習段</th>
          <th>核心問題</th>
          <th>對應段落</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Distributed SQL</td>
          <td>SQL 介面如何藏住 range sharding 與 Raft replication</td>
          <td>定位、容量特性</td>
      </tr>
      <tr>
          <td>Serializable default</td>
          <td>transaction retry、contention、latency 如何影響應用設計</td>
          <td>容量規劃要點、<a href="/blog/backend/knowledge-cards/isolation-level/" data-link-title="Isolation Level" data-link-desc="說明資料庫交易隔離級別如何影響並發讀寫結果">Isolation Level</a></td>
      </tr>
      <tr>
          <td>Region placement</td>
          <td>multi-region table、leaseholder、survival goal 如何服務產品需求</td>
          <td>適用場景、跟其他 vendor 的取捨</td>
      </tr>
      <tr>
          <td>Migration pressure</td>
          <td>從 PostgreSQL / MySQL 或自管 sharding 過來時要檢查哪些差異</td>
          <td>預計實作話題、案例對照</td>
      </tr>
      <tr>
          <td>替代路由</td>
          <td>何時留 PostgreSQL、用 Spanner、Aurora DSQL 或 application sharding</td>
          <td>不適用場景、下一步路由</td>
      </tr>
  </tbody>
</table>
<h2 id="定位spanner-的開源--跨雲替代">定位：Spanner 的開源 / 跨雲替代</h2>
<p>CockroachDB 跟 Spanner 解決同一個問題（跨 region 強一致 SQL）、但定位不同：</p>
<ul>
<li>Spanner：GCP managed service、用 TrueTime hardware</li>
<li>CockroachDB：開源（雙授權）、可自管 + Cockroach Cloud、跨 AWS / GCP / Azure / on-prem、用 HLC + Raft</li>
</ul>
<p>選 CockroachDB 的核心訴求：需要跨 region 強一致 SQL + 想避免雲商 lock-in、想自管或跨雲部署。</p>
<p>詳見 <a href="/blog/backend/01-database/global-distributed-oltp/" data-link-title="1.11 全球分散式 OLTP" data-link-desc="Spanner / Aurora DSQL / Cosmos DB multi-region write / CockroachDB / TiDB 的全球一致性取捨">1.11 全球分散式 OLTP</a> 的 CockroachDB 段。</p>
<h2 id="容量特性">容量特性</h2>
<p><strong>節點即容量單位</strong>：</p>
<ul>
<li>跟 Spanner 同樣設計、節點數量決定容量</li>
<li>每節點承擔 query + storage + replication</li>
<li>線性擴展（理論）、實際依 query pattern</li>
</ul>
<p><strong>跨 region 配置</strong>：</p>
<ul>
<li>multi-region survival goal（zone-level / region-level）</li>
<li>跨 region quorum 必要、決定 latency</li>
<li>跟 Spanner 同樣的物理限制（跨洲 100ms+）</li>
</ul>
<p><strong>Replication</strong>：</p>
<ul>
<li>Raft consensus per range</li>
<li>預設 3-replica</li>
<li>可配置每個 region 不同 replica count（Survival Goals）</li>
</ul>
<h2 id="適用場景">適用場景</h2>
<p><strong>1. 需要跨 region 強一致 SQL + 跨雲</strong>：</p>
<ul>
<li>multi-region active-active write</li>
<li>GCP-only（Spanner）或 AWS-only（Aurora DSQL）和部署策略不合</li>
<li>對應 <a href="/blog/backend/01-database/global-distributed-oltp/" data-link-title="1.11 全球分散式 OLTP" data-link-desc="Spanner / Aurora DSQL / Cosmos DB multi-region write / CockroachDB / TiDB 的全球一致性取捨">1.11 全球分散式 OLTP</a> 的選型決策</li>
</ul>
<p><strong>2. PostgreSQL wire protocol 相容路徑</strong>：</p>
<ul>
<li>既有 PostgreSQL 應用想升級到分散式</li>
<li>應用層改動小（保留 PostgreSQL driver / ORM）</li>
<li>注意：PostgreSQL 相容要以實際 query、extension 與 migration test 驗證</li>
</ul>
<p><strong>3. 自管 on-prem / hybrid</strong>：</p>
<ul>
<li>金融 / 受監管產業需要 on-prem</li>
<li>Spanner / Aurora DSQL 以 cloud service 為主</li>
<li>CockroachDB 可自管</li>
</ul>
<p><strong>4. 想避免單一 vendor 全球分散式 lock-in</strong>：</p>
<ul>
<li>開源 + 跨雲、可遷移性高</li>
<li>但企業版功能要付費（CockroachDB Cloud 或 Enterprise license）</li>
</ul>
<h2 id="不適用場景">不適用場景</h2>
<p><strong>1. single-region OLTP 夠用</strong>：</p>
<ul>
<li>90% 場景 PostgreSQL / Aurora 已夠</li>
<li>CockroachDB 有分散式 overhead（每個寫經 Raft）</li>
<li>替代：PostgreSQL、Aurora、MySQL</li>
</ul>
<p><strong>2. 極端高吞吐 single-query</strong>：</p>
<ul>
<li>CockroachDB 寫入有 Raft 開銷、單機吞吐 &lt; PostgreSQL</li>
<li>整體吞吐靠 scale-out 達成、單一 query latency 較高</li>
</ul>
<p><strong>3. 跨洲低延遲（&lt; 50ms）</strong>：</p>
<ul>
<li>跟 Spanner 同樣物理限制</li>
<li>跨洲 quorum 100ms+ 是物理成本</li>
</ul>
<p><strong>4. 預算極敏感的小 workload</strong>：</p>
<ul>
<li>CockroachDB 至少 3 個節點（Raft quorum）</li>
<li>跟 single-instance PostgreSQL 比較貴</li>
</ul>
<p><strong>5. 需要 PostgreSQL 進階特性</strong>：</p>
<ul>
<li>部分 PostgreSQL extension 或行為需要替代方案</li>
<li>partial index、exclusion constraint 等可能缺</li>
</ul>
<h2 id="跟其他-vendor-的取捨">跟其他 vendor 的取捨</h2>
<p><strong>vs Spanner（GCP）</strong>：</p>
<ul>
<li>CockroachDB：開源、跨雲、可自管</li>
<li>Spanner：GCP-only、TrueTime hardware、Google 規模驗證</li>
<li>選 CockroachDB：跨雲 / on-prem 需求</li>
<li>選 Spanner：GCP 生態 + managed operation + Google 規模驗證的成熟度</li>
</ul>
<p><strong>vs Aurora DSQL（AWS 2024）</strong>：</p>
<ul>
<li>CockroachDB：跨雲、生產驗證較久</li>
<li>Aurora DSQL：AWS-only、serverless、新（2024）</li>
<li>選 CockroachDB：跨雲、想避免 AWS lock-in</li>
<li>選 Aurora DSQL：AWS 生態 + 已用 PostgreSQL + serverless 訴求</li>
</ul>
<p><strong>vs TiDB</strong>：</p>
<ul>
<li>CockroachDB：PostgreSQL wire、英語 / 歐美生態深</li>
<li>TiDB：MySQL wire、亞洲生態深、HTAP（OLTP + OLAP 同庫）</li>
<li>選 CockroachDB：PostgreSQL 應用、跨雲</li>
<li>選 TiDB：MySQL 應用、需要 OLAP 整合、亞洲市場</li>
</ul>
<p><strong>vs PostgreSQL（傳統）</strong>：</p>
<ul>
<li>CockroachDB：分散式、跨 region 強一致</li>
<li>PostgreSQL：single-primary、跨 region 是 async replication</li>
<li>選 CockroachDB：需要跨 region 強一致</li>
<li>選 PostgreSQL：single-region 夠用（90% 場景）</li>
</ul>
<p><strong>vs Aurora（single-region scaling）</strong>：</p>
<ul>
<li>CockroachDB：multi-region 強一致</li>
<li>Aurora：single-region scaling、跨 region 是 async Global Database</li>
<li>選 CockroachDB：需要 multi-region write</li>
<li>選 Aurora：single-region scaling + AWS 生態</li>
</ul>
<p><strong>vs MySQL + Vitess（self-managed distributed MySQL）</strong>：</p>
<ul>
<li>CockroachDB：PostgreSQL wire、transparent sharding（range-based）、跨 region 強一致內建</li>
<li>MySQL + Vitess：MySQL wire、application 層配 keyspace + shard key、跨 region 靠 application + async replication</li>
<li>選 CockroachDB：PostgreSQL 應用 + transparent multi-region + 想避開 Vitess operation burden</li>
<li>選 MySQL + Vitess：MySQL 應用 + 有 DBA 養 Vitess + 已是 YouTube / Slack 規模</li>
</ul>
<h2 id="容量規劃要點">容量規劃要點</h2>
<p><strong>1. Node count + zone / region 配置</strong>：</p>
<ul>
<li>至少 3 個節點（Raft quorum）</li>
<li>multi-region 通常 9+ 節點（3 region × 3 replica）</li>
<li>Survival Goals 配置決定每 region 復原能力</li>
</ul>
<p><strong>2. Range（CockroachDB 的 partition）</strong>：</p>
<ul>
<li>跟 DynamoDB partition、Spanner split 同類</li>
<li>CockroachDB 自動 split 大 range</li>
<li>application 主要管理 query locality、transaction retry 與 region placement</li>
</ul>
<p><strong>3. Locality 配置</strong>：</p>
<ul>
<li>跟 Spanner 一樣可以指定 voting region</li>
<li>寫入 locality 影響跨 region latency</li>
</ul>
<p><strong>4. Backup / restore</strong>：</p>
<ul>
<li>CockroachDB 原生 backup 支援 cluster-level snapshot</li>
<li>增量 backup 支援</li>
<li>注意：incremental backup chain 可能很長、定期 full backup</li>
</ul>
<p><strong>5. Self-managed vs Cockroach Cloud</strong>：</p>
<ul>
<li>Self-managed：需要 ops team、可跨雲 / on-prem</li>
<li>Cockroach Cloud：managed、跨 cloud（AWS / GCP / Azure）、可考慮 serverless tier</li>
</ul>
<h2 id="deep-article已完成">Deep article（已完成）</h2>
<p>本批 deep article 覆蓋 CockroachDB 從 consensus 機制、multi-region 配置到 managed 形態選型的核心 production 議題：</p>
<table>
  <thead>
      <tr>
          <th>主題</th>
          <th>文章</th>
          <th>對應 production 議題</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>HLC + per-range Raft、leaseholder、寫入 latency 結構</td>
          <td><a href="hlc-raft-consensus/">hlc-raft-consensus</a></td>
          <td>DoorDash Aurora 撞牆訊號（1.636 M QPS）、Netflix 380+ artery of small DBs 容量規劃顆粒</td>
      </tr>
      <tr>
          <td>SURVIVE ZONE / REGION FAILURE 倒推、業務 SLO 決定副本拓樸</td>
          <td><a href="survival-goals/">survival-goals</a></td>
          <td>Hard Rock RPO=0 倒推、Netflix Gaming 48-node 跨 4 region「為求 survival 而非 latency」反直覺</td>
      </tr>
      <tr>
          <td>Serializable default、application 必須包 retry loop、SAVEPOINT 語法</td>
          <td><a href="transaction-retry-pattern/">transaction-retry-pattern</a></td>
          <td>PG → CockroachDB application contract 重塑、5 種 retry failure mode（跨 case 合成 frame）</td>
      </tr>
      <tr>
          <td>REGIONAL BY ROW / TABLE / GLOBAL、跨州合規 + 邏輯一個 cluster</td>
          <td><a href="locality-aware-schema/">locality-aware-schema</a></td>
          <td>Hard Rock 跨 8 州 sportsbook + AWS Outposts、Outposts 是合規工具不是 latency 工具反直覺判讀</td>
      </tr>
      <tr>
          <td>三種 table locality 的選擇與 latency / 一致性取捨、選錯重配代價</td>
          <td><a href="multi-region-table-config/">multi-region-table-config</a></td>
          <td>Netflix multi-region 動機為 survival 非 latency、Hard Rock row-level 歸屬 + 單一邏輯 cluster</td>
      </tr>
      <tr>
          <td>Cockroach Cloud serverless vs dedicated、RU 計費、冷啟動 / scale</td>
          <td><a href="cloud-serverless/">cloud-serverless</a></td>
          <td>Netflix 需 Platform Team 反向 = managed 入口、Hard Rock 可預測賽季擴縮 vs serverless 突發甜蜜區</td>
      </tr>
      <tr>
          <td>Distributed SQL 三選一決策樹：撞牆訊號分型 + 七問題</td>
          <td><a href="aurora-dsql-spanner-decision-tree/">aurora-dsql-spanner-decision-tree</a></td>
          <td>DB4 cross-vendor entry：DoorDash / Netflix / Hard Rock driver path 識別 + sizing barrier</td>
      </tr>
  </tbody>
</table>
<p>DB4 cross-vendor entry：先看 <a href="aurora-dsql-spanner-decision-tree/">aurora-dsql-spanner-decision-tree</a> 識別 driver path、再進個別 vendor 深度。</p>
<p>multi-region-table-config 與 locality-aware-schema 切分：前者主寫「三種 table locality 怎麼選 + 選錯重配代價」、後者主寫「schema 怎麼配合 locality 設計（合規 boundary、跨州業務邏輯、Outposts 拓樸）」、兩者互補、survival goal 機制以 survival-goals 為 SSoT。</p>
<h2 id="後續擴充仍待補">後續擴充（仍待補）</h2>
<ul>
<li>PostgreSQL 相容性 audit（partial index / extension / SQL 行為 gap 清單）</li>
<li>Backup / restore 與 PITR 操作（incremental chain 管理、restore 演練）</li>
<li>Changefeed / CDC 配置（CockroachDB 原生 CDC 到 Kafka / sink）</li>
</ul>
<blockquote>
<p>「從 PostgreSQL 遷到 CockroachDB（playbook）」已由 <a href="/blog/backend/01-database/vendors/postgresql/migrate-to-cockroachdb/" data-link-title="PostgreSQL → CockroachDB：三維皆 High 的多重歸類 migration" data-link-desc="PostgreSQL → CockroachDB 是 Schema / Operational / Paradigm 三維皆 High 的 multi-axis migration、實證 [#127](/report/content-structure-by-max-diff-dimension/) 的「多重歸類跟 tie-breaking」規則；主結構走 Type E paradigm shift、Schema 差 &#43; Operational redesign 抽出獨立段；涵蓋 transaction model 重設計、SQL dialect gap、5 個 production 踩雷">PostgreSQL → CockroachDB migration</a> 涵蓋、不再列為待補。</p></blockquote>
<h2 id="anti-recommendation-與升級路由">Anti-recommendation 與升級路由</h2>
<p>CockroachDB 的 PostgreSQL-like 介面會降低導入門檻，但 distributed SQL 的成本會出現在 transaction retry、range lease、multi-region latency 與操作拓樸。這一段先說何時維持 PostgreSQL / Aurora，再說何時升級 CockroachDB、Cockroach Cloud、Spanner、Aurora DSQL 或 Vitess。</p>
<table>
  <thead>
      <tr>
          <th>機制 / 路線</th>
          <th>維持簡單設計的條件</th>
          <th>升級訊號</th>
          <th>主要引用路徑</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>PostgreSQL / Aurora</td>
          <td>single-region primary、async DR、read replica 已滿足需求</td>
          <td>multi-region write、region failure survival、跨雲部署是硬需求</td>
          <td><a href="/blog/backend/01-database/vendors/postgresql/" data-link-title="PostgreSQL" data-link-desc="多用途 OLTP 主流關聯式資料庫、MVCC、豐富 SQL 特性、是 Aurora / Cosmos DB / Spanner / CockroachDB / Aurora DSQL 的相容目標">PostgreSQL vendor</a>、<a href="/blog/backend/01-database/vendors/aurora/" data-link-title="AWS Aurora" data-link-desc="AWS managed PostgreSQL / MySQL、storage / compute 分離、&#43;75% 效能改善的 production 證據">Aurora vendor</a></td>
      </tr>
      <tr>
          <td>CockroachDB single-region</td>
          <td>需要水平擴容或 future multi-region，但目前在單區運作</td>
          <td>Raft overhead 讓成本高於 PostgreSQL，且沒有 region requirement</td>
          <td><a href="/blog/backend/knowledge-cards/distributed-sql/" data-link-title="Distributed SQL" data-link-desc="把 SQL 與交易語意延伸到多節點與多區域的資料庫形態">Distributed SQL</a></td>
      </tr>
      <tr>
          <td>CockroachDB multi-region</td>
          <td>跨雲 / on-prem、PostgreSQL wire、strong consistency 是主需求</td>
          <td>跨洲 p99 目標過低、transaction retry 影響 user flow</td>
          <td><a href="/blog/backend/knowledge-cards/quorum/" data-link-title="Quorum" data-link-desc="分散式系統以多數節點同意作為提交或讀取有效性的門檻">Quorum</a>、<a href="/blog/backend/knowledge-cards/latency-budget/" data-link-title="Latency Budget" data-link-desc="把 user-perceived latency 拆到每個 stage 的配額、反推架構選擇">Latency Budget</a></td>
      </tr>
      <tr>
          <td>Cockroach Cloud</td>
          <td>團隊仍能自管 Raft、backup、upgrade、node failure</td>
          <td>想把 operation transfer 給 vendor</td>
          <td><a href="/blog/backend/knowledge-cards/rto/" data-link-title="RTO" data-link-desc="說明恢復時間目標如何約束事故回復策略">RTO</a>、<a href="/blog/backend/knowledge-cards/rpo/" data-link-title="RPO" data-link-desc="說明恢復點目標如何定義可接受資料損失範圍">RPO</a></td>
      </tr>
      <tr>
          <td>Spanner</td>
          <td>跨雲或自管是硬需求</td>
          <td>GCP managed、TrueTime 成熟度、Google scale evidence 是主訴求</td>
          <td><a href="/blog/backend/01-database/vendors/spanner/" data-link-title="Google Cloud Spanner" data-link-desc="全球分散式 strong-consistency OLTP、TrueTime API、線性擴展到 10 億 req/sec">Spanner vendor</a></td>
      </tr>
      <tr>
          <td>Aurora DSQL</td>
          <td>跨雲 / on-prem 是硬需求</td>
          <td>AWS-only、serverless、PostgreSQL 相容與 AWS operation model 是主訴求</td>
          <td><a href="/blog/backend/01-database/vendors/postgresql/migrate-to-aurora-dsql/" data-link-title="PostgreSQL → Aurora DSQL Migration：PG wire-compatible Distributed SQL 的 Paradigm Shift" data-link-desc="Aurora DSQL（2024-12 re:Invent preview / 2025-05 GA）是 AWS 推的 PG wire-compatible *active-active distributed SQL*、跟 self-managed PG / Aurora PG 不同 paradigm（OCC &#43; snapshot isolation &#43; multi-region strong consistency）。Migration 結構是 *protocol drop-in &#43; paradigm shift*：app SQL 不太改、但 transaction retry / extension 缺位 / 多 region 一致性需重設計。本文走 DSQL vs Aurora PG vs self-managed PG 三軸對比、為什麼遷的三條 driver（global write / operational zero-touch / region resiliency）、Type E phased plan、5 production 踩雷（transaction retry 沒處理 / extension 缺位 / sequence throughput 限制 / Aurora PG 直升 DSQL 不可行 / region failover semantic）、跟 PG → Aurora 跟 PG → CockroachDB 對比">PG → Aurora DSQL Migration</a></td>
      </tr>
      <tr>
          <td>MySQL + Vitess</td>
          <td>PostgreSQL-like SQL 與 strong consistency 是主需求</td>
          <td>MySQL ecosystem、application sharding 與 Vitess ops 已成熟</td>
          <td><a href="/blog/backend/01-database/vendors/mysql/vitess-sharding/" data-link-title="MySQL Vitess Sharding：VTGate / VTTablet / VReplication / VSchema 四件套協作" data-link-desc="Vitess 不只是 MySQL sharding proxy、是 4 個 component 協作的完整 sharding 系統 — VTGate（query routing layer）、VTTablet（per-MySQL agent）、VReplication（跨 shard 資料移動）、VSchema（sharding metadata）。本文走 4 件套各自責任、keyspace / shard / tablet 架構、shard key 設計（Vindex）、配置 step-by-step、5 production 踩雷（cross-shard transaction / VStream lag / Vindex 不均勻 / resharding 切流 / VReplication 卡住）、跟自管 sharding 跟 PlanetScale 的對比">MySQL Vitess Sharding</a>、<a href="/blog/backend/knowledge-cards/database-sharding/" data-link-title="Database Sharding" data-link-desc="說明資料庫如何依 shard key 分散資料、路由請求與承擔跨 shard 查詢成本">Database Sharding</a></td>
      </tr>
  </tbody>
</table>
<p>CockroachDB 的簡單路徑是先證明 distributed SQL 的價值大於 retry 與 latency 成本。若 workload 仍是 single-region OLTP，PostgreSQL / Aurora 通常提供更低成本；若跨 region 寫入與一致性是產品承諾，CockroachDB 才成為主要候選。</p>
<p>Transaction retry 的升級路徑要進入 application contract。Serializable default 能保護一致性，但 retry 會把 idempotency、timeout、user-visible latency 與 workflow compensation 帶回應用層；這些條件要在 migration playbook 前先盤點。</p>
<h2 id="已知-limitation-與後續路由">已知 limitation 與後續路由</h2>
<p>CockroachDB overview 目前完成 distributed SQL 判斷。下一輪 deep article / playbook 應補 HLC + Raft、range / leaseholder、multi-region table locality、transaction retry pattern、PostgreSQL compatibility audit、Cockroach Cloud operation 與 PostgreSQL → CockroachDB migration。</p>
<h2 id="案例對照">案例對照</h2>
<p>CockroachDB 在 09 案例庫已有三條直接 case 軸線（OLTP 寫入擴展、polyglot 補位、合規邊界），另外兩條對比參考軸線（Spanner 設計理念、受監管金融）一併保留。</p>
<h3 id="direct-casecockroachdb-為主角">Direct case（CockroachDB 為主角）</h3>
<table>
  <thead>
      <tr>
          <th>案例</th>
          <th>主要工程議題</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/doordash-cockroachdb-orders-platform/" data-link-title="9.C39 DoorDash：Aurora Postgres 寫入瓶頸 → CockroachDB 多主寫入" data-link-desc="DoorDash 從 Aurora Postgres 遷到 CockroachDB、解 1.6 M QPS 單主寫入瓶頸、外送平台爆量壓力下重做 OLTP 拓樸">9.C39 DoorDash</a></td>
          <td>Aurora Postgres single-primary 1.6 M QPS 撞牆 → multi-primary 解寫入</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/netflix-cockroachdb-multi-region-fleet/" data-link-title="9.C40 Netflix：380&#43; CockroachDB cluster 的 multi-active 拓樸艦隊" data-link-desc="Netflix 把 Cassandra 不夠用的 transactional workload 移到 CockroachDB、380&#43; cluster / 60&#43; 跨 region、含 Open Connect、studio cloud drive、gaming control plane">9.C40 Netflix</a></td>
          <td>380+ cluster 艦隊、Cassandra 不夠用的 transactional workload 補位</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/hard-rock-digital-cockroachdb-sports-betting/" data-link-title="9.C41 Hard Rock Digital：CockroachDB on AWS Outposts、Wire Act 合規 &#43; 跨州單一邏輯 DB" data-link-desc="Hard Rock Digital 用 CockroachDB 跨 AWS Outposts &#43; US-East-1、Wire Act 強制資料留州、單一邏輯 DB 解多州 sportsbook、100 node 32 vCPU 撐 Super Bowl">9.C41 Hard Rock Digital</a></td>
          <td>AWS Outposts + 跨州單一邏輯 DB、Wire Act 合規 + 賽季型擴縮容</td>
      </tr>
  </tbody>
</table>
<h3 id="對比參考案例">對比參考案例</h3>
<table>
  <thead>
      <tr>
          <th>案例（對比參考）</th>
          <th>跟 CockroachDB 的關係</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">9.C10 Spanner</a></td>
          <td>設計理念對標、CockroachDB 是開源版本</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered</a></td>
          <td>受監管金融、CockroachDB 可作為 on-prem 替代候選</td>
      </tr>
  </tbody>
</table>
<p>CockroachDB direct case 的讀法是「寫入擴展（DoorDash）→ polyglot 補位（Netflix）→ 合規邊界（Hard Rock Digital）」三條軸線；對比案例則提醒讀者：Spanner 提供 global consistency 的成熟對照，受監管金融類案例提醒部署位置、合規邊界與自管能力常和一致性需求同時決定 vendor。</p>
<h2 id="反向-sibling-路由">反向 sibling 路由</h2>
<p>CockroachDB 的反向 sibling 路由用來把 PostgreSQL 相容性和 distributed SQL 責任拆開。若讀者從 PostgreSQL 章節過來，先讀 <a href="/blog/backend/01-database/vendors/postgresql/migrate-to-cockroachdb/" data-link-title="PostgreSQL → CockroachDB：三維皆 High 的多重歸類 migration" data-link-desc="PostgreSQL → CockroachDB 是 Schema / Operational / Paradigm 三維皆 High 的 multi-axis migration、實證 [#127](/report/content-structure-by-max-diff-dimension/) 的「多重歸類跟 tie-breaking」規則；主結構走 Type E paradigm shift、Schema 差 &#43; Operational redesign 抽出獨立段；涵蓋 transaction model 重設計、SQL dialect gap、5 個 production 踩雷">PostgreSQL → CockroachDB migration</a>；若只是要 managed SQL 與 storage autoscale，先回 <a href="/blog/backend/01-database/vendors/aurora/" data-link-title="AWS Aurora" data-link-desc="AWS managed PostgreSQL / MySQL、storage / compute 分離、&#43;75% 效能改善的 production 證據">Aurora vendor</a>；若要 Google Cloud 原生 external consistency 與 fully managed control plane，再對照 <a href="/blog/backend/01-database/vendors/spanner/" data-link-title="Google Cloud Spanner" data-link-desc="全球分散式 strong-consistency OLTP、TrueTime API、線性擴展到 10 億 req/sec">Spanner vendor</a>。</p>
<p>這條路由的判準是「應用是否能承擔 distributed transaction 的語意差異」。SQL dialect 相近只降低 migration entry cost，真正的交付風險在 transaction retry、hot range、survival goal、backup restore 與 locality design。</p>
<h2 id="常見陷阱">常見陷阱</h2>
<ul>
<li><strong>single-region 用 CockroachDB</strong>：浪費分散式開銷、PostgreSQL 便宜很多</li>
<li><strong>跨洲 active-active 期待低延遲</strong>：物理限制、跨洲 quorum 100ms+</li>
<li><strong>PostgreSQL extension 假設</strong>：部分 extension 或 SQL 行為需要替代方案，應用要驗證</li>
<li><strong>不規劃 Survival Goals</strong>：default 配置可能不符合 RTO / RPO 需求</li>
<li><strong>backup chain 過長</strong>：incremental 不 full、recovery time 變長</li>
</ul>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>完整 T1 對照：<a href="/blog/backend/01-database/vendors/" data-link-title="資料庫 Vendor 清單" data-link-desc="規劃 SQL、managed SQL、document、KV 與 distributed SQL 的服務頁撰寫順序與教學大綱">01-database vendors index</a></li>
<li>平行：<a href="/blog/backend/01-database/vendors/spanner/" data-link-title="Google Cloud Spanner" data-link-desc="全球分散式 strong-consistency OLTP、TrueTime API、線性擴展到 10 億 req/sec">Spanner vendor</a>、<a href="/blog/backend/01-database/vendors/aurora/" data-link-title="AWS Aurora" data-link-desc="AWS managed PostgreSQL / MySQL、storage / compute 分離、&#43;75% 效能改善的 production 證據">Aurora vendor</a>、<a href="/blog/backend/01-database/vendors/postgresql/" data-link-title="PostgreSQL" data-link-desc="多用途 OLTP 主流關聯式資料庫、MVCC、豐富 SQL 特性、是 Aurora / Cosmos DB / Spanner / CockroachDB / Aurora DSQL 的相容目標">PostgreSQL vendor</a></li>
<li>上游：<a href="/blog/backend/01-database/global-distributed-oltp/" data-link-title="1.11 全球分散式 OLTP" data-link-desc="Spanner / Aurora DSQL / Cosmos DB multi-region write / CockroachDB / TiDB 的全球一致性取捨">1.11 全球分散式 OLTP</a> — 完整選型對比</li>
<li>跨模組：<a href="/blog/backend/09-performance-capacity/capacity-planning/" data-link-title="9.6 容量規劃模型" data-link-desc="peak forecast、headroom budget、growth curve、autoscaling sizing">9.6 容量規劃模型</a>、<a href="/blog/backend/09-performance-capacity/slo-performance-budget/" data-link-title="9.12 SLO 與 Performance Budget" data-link-desc="performance budget 跟 SLO / error budget 的對接">9.12 SLO 與 Performance Budget</a></li>
<li>Last reviewed：2026-05-22（PostgreSQL compatibility / survival goal / managed offering 屬時間敏感 claim）</li>
<li>官方：<a href="https://www.cockroachlabs.com/docs/">CockroachDB Documentation</a></li>
</ul>
]]></content:encoded></item><item><title>AWS Aurora</title><link>https://tarrragon.github.io/blog/backend/01-database/vendors/aurora/</link><pubDate>Wed, 13 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/01-database/vendors/aurora/</guid><description>&lt;p>Aurora 是 AWS managed PostgreSQL / MySQL、把 storage layer 重寫成跨 AZ 分散式 log service、保留 wire protocol 相容。Netflix 把多套 RDBMS 統一到 Aurora（+75% 效能、-28% 成本）、DraftKings 撐每分鐘 100 萬 ops 體育博彩、Standard Chartered 跨 7 個受監管市場、FanDuel 處理 Super Bowl 5-10 倍峰值 — 是 SQL OLTP managed 服務的代表。&lt;/p>
&lt;h2 id="教學路線managed-sql-與平台責任轉移">教學路線：Managed SQL 與平台責任轉移&lt;/h2>
&lt;p>Aurora 服務頁的教學目標是把 PostgreSQL / MySQL 語意延伸到 AWS managed storage / compute 分離模型。讀者讀完後要能判斷哪些責任交給 Aurora，哪些責任仍留在 schema、query、maintenance window、region 與成本治理。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>學習段&lt;/th>
 &lt;th>核心問題&lt;/th>
 &lt;th>對應段落&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Managed SQL&lt;/td>
 &lt;td>Aurora 如何保留 PostgreSQL / MySQL 語意並改變操作責任&lt;/td>
 &lt;td>定位、適用場景&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Storage / compute&lt;/td>
 &lt;td>分離 storage layer 如何影響 replica、failover、backup&lt;/td>
 &lt;td>容量規劃要點、案例對照&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>AWS operation model&lt;/td>
 &lt;td>parameter group、maintenance、region、cost 如何成為平台責任&lt;/td>
 &lt;td>跟其他 vendor 的取捨、&lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/rto/" data-link-title="RTO" data-link-desc="說明恢復時間目標如何約束事故回復策略">RTO&lt;/a> / &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/rpo/" data-link-title="RPO" data-link-desc="說明恢復點目標如何定義可接受資料損失範圍">RPO&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Peak workload&lt;/td>
 &lt;td>金融、串流、Super Bowl、banking case 如何提供容量判準&lt;/td>
 &lt;td>適用場景、案例對照&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>替代路由&lt;/td>
 &lt;td>何時留 RDS、自管 PostgreSQL / MySQL、轉 Spanner 或 DynamoDB&lt;/td>
 &lt;td>不適用場景、下一步路由&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="定位storage--compute-分離的-sql">定位：storage / compute 分離的 SQL&lt;/h2>
&lt;p>Aurora 跟傳統 PostgreSQL / MySQL primary 最大差異是 &lt;em>storage layer 重寫&lt;/em>。傳統 SQL primary 把 storage 跟 CPU / RAM 綁定、storage 擴容要換 instance、replication lag 受 compute 影響。Aurora 把 storage 拉到分散式 log service、跨 6 個 storage node（3 AZ × 2 node）、storage 跟 compute 獨立擴。&lt;/p>
&lt;p>&lt;strong>容量特性&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>單一 cluster 最高 storage：128 TB&lt;/li>
&lt;li>最多 15 個 read replica（單 region 內）&lt;/li>
&lt;li>read replica replication lag：10-30ms（vs 傳統 PostgreSQL 跨 AZ 可能秒級）&lt;/li>
&lt;li>跨 AZ failover：&amp;lt; 30 秒（promote read replica）&lt;/li>
&lt;li>Aurora Global Database 跨 region replication：&amp;lt; 1 秒典型 lag&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>為什麼這個分離很重要&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>傳統 PostgreSQL primary 上的 read replica 都靠 logical replication、會跟著 primary write load 走慢&lt;/li>
&lt;li>Aurora storage 直接複製到 6 個 storage node、read replica 從 storage 讀、不靠 primary&lt;/li>
&lt;li>→ read replica 大幅減少 lag、可以撐更多 OLTP read traffic&lt;/li>
&lt;li>對應 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &amp;#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix&lt;/a> +75% 效能改善的關鍵原因&lt;/li>
&lt;/ul>
&lt;h2 id="適用場景">適用場景&lt;/h2>
&lt;p>按公開 case 提煉的典型適用場景：&lt;/p></description><content:encoded><![CDATA[<p>Aurora 是 AWS managed PostgreSQL / MySQL、把 storage layer 重寫成跨 AZ 分散式 log service、保留 wire protocol 相容。Netflix 把多套 RDBMS 統一到 Aurora（+75% 效能、-28% 成本）、DraftKings 撐每分鐘 100 萬 ops 體育博彩、Standard Chartered 跨 7 個受監管市場、FanDuel 處理 Super Bowl 5-10 倍峰值 — 是 SQL OLTP managed 服務的代表。</p>
<h2 id="教學路線managed-sql-與平台責任轉移">教學路線：Managed SQL 與平台責任轉移</h2>
<p>Aurora 服務頁的教學目標是把 PostgreSQL / MySQL 語意延伸到 AWS managed storage / compute 分離模型。讀者讀完後要能判斷哪些責任交給 Aurora，哪些責任仍留在 schema、query、maintenance window、region 與成本治理。</p>
<table>
  <thead>
      <tr>
          <th>學習段</th>
          <th>核心問題</th>
          <th>對應段落</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Managed SQL</td>
          <td>Aurora 如何保留 PostgreSQL / MySQL 語意並改變操作責任</td>
          <td>定位、適用場景</td>
      </tr>
      <tr>
          <td>Storage / compute</td>
          <td>分離 storage layer 如何影響 replica、failover、backup</td>
          <td>容量規劃要點、案例對照</td>
      </tr>
      <tr>
          <td>AWS operation model</td>
          <td>parameter group、maintenance、region、cost 如何成為平台責任</td>
          <td>跟其他 vendor 的取捨、<a href="/blog/backend/knowledge-cards/rto/" data-link-title="RTO" data-link-desc="說明恢復時間目標如何約束事故回復策略">RTO</a> / <a href="/blog/backend/knowledge-cards/rpo/" data-link-title="RPO" data-link-desc="說明恢復點目標如何定義可接受資料損失範圍">RPO</a></td>
      </tr>
      <tr>
          <td>Peak workload</td>
          <td>金融、串流、Super Bowl、banking case 如何提供容量判準</td>
          <td>適用場景、案例對照</td>
      </tr>
      <tr>
          <td>替代路由</td>
          <td>何時留 RDS、自管 PostgreSQL / MySQL、轉 Spanner 或 DynamoDB</td>
          <td>不適用場景、下一步路由</td>
      </tr>
  </tbody>
</table>
<h2 id="定位storage--compute-分離的-sql">定位：storage / compute 分離的 SQL</h2>
<p>Aurora 跟傳統 PostgreSQL / MySQL primary 最大差異是 <em>storage layer 重寫</em>。傳統 SQL primary 把 storage 跟 CPU / RAM 綁定、storage 擴容要換 instance、replication lag 受 compute 影響。Aurora 把 storage 拉到分散式 log service、跨 6 個 storage node（3 AZ × 2 node）、storage 跟 compute 獨立擴。</p>
<p><strong>容量特性</strong>：</p>
<ul>
<li>單一 cluster 最高 storage：128 TB</li>
<li>最多 15 個 read replica（單 region 內）</li>
<li>read replica replication lag：10-30ms（vs 傳統 PostgreSQL 跨 AZ 可能秒級）</li>
<li>跨 AZ failover：&lt; 30 秒（promote read replica）</li>
<li>Aurora Global Database 跨 region replication：&lt; 1 秒典型 lag</li>
</ul>
<p><strong>為什麼這個分離很重要</strong>：</p>
<ul>
<li>傳統 PostgreSQL primary 上的 read replica 都靠 logical replication、會跟著 primary write load 走慢</li>
<li>Aurora storage 直接複製到 6 個 storage node、read replica 從 storage 讀、不靠 primary</li>
<li>→ read replica 大幅減少 lag、可以撐更多 OLTP read traffic</li>
<li>對應 <a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix</a> +75% 效能改善的關鍵原因</li>
</ul>
<h2 id="適用場景">適用場景</h2>
<p>按公開 case 提煉的典型適用場景：</p>
<p><strong>1. 既有 PostgreSQL / MySQL 應用想要 managed</strong>：</p>
<ul>
<li>wire protocol 相容，應用層改動通常集中在連線、參數與操作流程</li>
<li>ORM / driver / SQL 多數可保留，但 migration plan 仍要驗證 dialect 與 extension</li>
<li>對應案例：<a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix</a> — 多套 RDBMS（PostgreSQL、MySQL、Oracle）統一到 Aurora、+75% 效能、-28% 成本</li>
</ul>
<p><strong>2. 金融交易 / 體育博彩 OLTP</strong>：</p>
<ul>
<li>強 ACID transaction</li>
<li>多 read replica 處理 query traffic、不影響寫</li>
<li>對應案例：<a href="/blog/backend/09-performance-capacity/cases/draftkings-aurora-financial-ledger/" data-link-title="9.C4 DraftKings：Aurora 撐 100 萬 ops/min 的體育博彩金融帳本" data-link-desc="DraftKings 用 Aurora MySQL 跑體育博彩金融帳本、Super Bowl 流量 &#43;50% 不影響延遲">9.C4 DraftKings</a> — 每分鐘 100 萬 ops、200 個獨立資料庫、Super Bowl 流量 +50% 無影響</li>
</ul>
<p><strong>3. 受監管產業跨市場部署</strong>：</p>
<ul>
<li>每個市場一個獨立 cluster、合規分割</li>
<li>對應案例：<a href="/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered</a> — 7 個受監管市場、各自獨立 Aurora、總吞吐 4000 TPS、10x 提升</li>
</ul>
<p><strong>4. 高峰流量 + 多 read replica 擴容</strong>：</p>
<ul>
<li>read 高峰用 read replica 接、write 走 primary</li>
<li>對應案例：<a href="/blog/backend/09-performance-capacity/cases/fanduel-dual-peak-betting-streaming/" data-link-title="9.C28 FanDuel：體育直播 &#43; 投注的雙重峰值" data-link-desc="FanDuel 3.5M MAU、Super Bowl 期間擴容 5-10 倍、用 AWS Local Zones &#43; Wavelength &#43; Outposts 處理 20&#43; 州的雙重峰值">9.C28 FanDuel</a> — 5-10x Super Bowl 峰值、直播 + 投注雙工作負載</li>
</ul>
<p><strong>5. Aurora Serverless v2 適用場景</strong>：</p>
<ul>
<li>流量 unpredictable + sustained workload</li>
<li>自動 scale CPU / RAM，降低 instance class 管理負擔</li>
<li>適合：dev / test 環境、流量稀疏的多 tenant SaaS</li>
</ul>
<p><strong>6. Aurora Global Database</strong>：</p>
<ul>
<li>跨 region async replication（&lt; 1 秒 typical）</li>
<li>DR + 跨地理 read（write 在 primary region、read 可從 secondary region）</li>
<li>Global Database 是跨 region DR / read route，multi-region active-active write 要改看 Aurora DSQL</li>
</ul>
<h2 id="不適用場景">不適用場景</h2>
<p><strong>1. 跨雲需求</strong>：</p>
<ul>
<li>Aurora 是 AWS-only、wire protocol 相容但 storage 是 AWS 專屬</li>
<li>替代：自管 PostgreSQL / MySQL on Kubernetes</li>
</ul>
<p><strong>2. 需要最新 upstream PostgreSQL / MySQL 特性</strong>：</p>
<ul>
<li>Aurora 通常落後 upstream 1-2 個 major version</li>
<li>替代：RDS PostgreSQL（更接近 upstream）</li>
</ul>
<p><strong>3. 極端寫入吞吐</strong>：</p>
<ul>
<li>單一 primary 寫入受 storage 設計限制（雖然比 PostgreSQL 快）</li>
<li>
<blockquote>
<p>100K WPS 級別、考慮 sharding、CockroachDB、或 DynamoDB</p></blockquote>
</li>
<li>對應 <a href="/blog/backend/09-performance-capacity/cases/ntt-docomo-lemino-japanese-streaming/" data-link-title="9.C29 NTT DOCOMO Lemino：3 個月達 500 萬 MAU 的串流後端" data-link-desc="Lemino 用 DynamoDB &#43; AWS Media Services 撐 30 channels live &#43; 5M MAU、工程工時下降 90%">9.C29 Lemino</a> — RDB connection limit 是 bottleneck、改 DynamoDB</li>
</ul>
<p><strong>4. 全球 multi-region active-active write</strong>：</p>
<ul>
<li>Aurora Global Database 是 async、有 lag，write 仍集中在 primary region</li>
<li>替代：Aurora DSQL（2024 推出）、Spanner、Cosmos DB</li>
</ul>
<p><strong>5. 預算敏感的小 workload</strong>：</p>
<ul>
<li>Aurora 比 self-managed PostgreSQL 貴 20-30%</li>
<li>小流量場景、自管 PostgreSQL on EC2 或 RDS 更便宜</li>
</ul>
<h2 id="跟其他-vendor-的取捨">跟其他 vendor 的取捨</h2>
<p><strong>vs RDS PostgreSQL / MySQL（同 AWS）</strong>：</p>
<ul>
<li>Aurora：storage / compute 分離、更多 read replica、更快 failover、跨 AZ 自動 replication</li>
<li>RDS：純 managed PostgreSQL / MySQL、不重寫 storage、更接近 upstream</li>
<li>選 Aurora：需要 scale read replica 或 cross-AZ failover &lt; 30 秒</li>
<li>選 RDS：需要最新 upstream 特性、預算更敏感</li>
</ul>
<p><strong>vs 自管 PostgreSQL / MySQL</strong>：</p>
<ul>
<li>Aurora：託管、自動 backup / failover，降低日常 database operation</li>
<li>自管：彈性高、可自己 tuning、跨雲可用、預算可控</li>
<li>選 Aurora：團隊想把 DBA / SRE 操作責任轉交 AWS、AWS 生態深</li>
<li>選自管：跨雲需求、需要客製化、預算極敏感</li>
</ul>
<p><strong>vs CockroachDB</strong>：</p>
<ul>
<li>Aurora：single-region scaling（一個 region 內擴）、AWS-only</li>
<li>CockroachDB：multi-region 強一致、跨雲可用、PostgreSQL wire protocol</li>
<li>選 Aurora：AWS-only + single-region OLTP</li>
<li>選 CockroachDB：需要 multi-region 強一致 + 跨雲 / on-prem 彈性</li>
</ul>
<p><strong>vs Aurora DSQL（2024-12 preview / 2025-05 GA）</strong>：</p>
<ul>
<li>Aurora：single-region scaling、傳統 OLTP</li>
<li>Aurora DSQL：multi-region active-active write、serverless、強一致</li>
<li>選 Aurora：流量集中在一個 region</li>
<li>選 Aurora DSQL：需要全球 active-active</li>
<li>從 PG / Aurora PG 遷 DSQL 的完整 playbook 見 <a href="/blog/backend/01-database/vendors/postgresql/migrate-to-aurora-dsql/" data-link-title="PostgreSQL → Aurora DSQL Migration：PG wire-compatible Distributed SQL 的 Paradigm Shift" data-link-desc="Aurora DSQL（2024-12 re:Invent preview / 2025-05 GA）是 AWS 推的 PG wire-compatible *active-active distributed SQL*、跟 self-managed PG / Aurora PG 不同 paradigm（OCC &#43; snapshot isolation &#43; multi-region strong consistency）。Migration 結構是 *protocol drop-in &#43; paradigm shift*：app SQL 不太改、但 transaction retry / extension 缺位 / 多 region 一致性需重設計。本文走 DSQL vs Aurora PG vs self-managed PG 三軸對比、為什麼遷的三條 driver（global write / operational zero-touch / region resiliency）、Type E phased plan、5 production 踩雷（transaction retry 沒處理 / extension 缺位 / sequence throughput 限制 / Aurora PG 直升 DSQL 不可行 / region failover semantic）、跟 PG → Aurora 跟 PG → CockroachDB 對比">PG → Aurora DSQL Migration</a></li>
</ul>
<p><strong>vs DynamoDB</strong>：</p>
<ul>
<li>詳見 <a href="/blog/backend/01-database/vendors/dynamodb/" data-link-title="DynamoDB" data-link-desc="AWS managed key-value、partition-based scaling、9000 萬 RPS sustained 實戰證據">DynamoDB vendor page</a> 對比段。Aurora 是 SQL、DynamoDB 是 KV、適用場景不同。</li>
</ul>
<p><strong>vs Azure SQL Hyperscale</strong>：</p>
<ul>
<li>設計理念類似（storage / compute 分離）</li>
<li>Aurora 在 AWS、Hyperscale 在 Azure</li>
<li>對應案例：<a href="/blog/backend/09-performance-capacity/cases/clearent-azure-sql-hyperscale-payments/" data-link-title="9.C32 Clearent：Azure SQL Hyperscale 撐每年 5 億筆支付交易" data-link-desc="Clearent 在 Azure SQL Hyperscale 上處理每年 5 億筆支付交易、autoscale &#43; 微服務架構">9.C32 Clearent</a> — Azure 生態的同類設計、5 億 payment txn / 年</li>
</ul>
<h2 id="容量規劃要點">容量規劃要點</h2>
<p>從 09 案例庫提煉的 Aurora 容量規劃實踐：</p>
<p><strong>1. read replica 是擴 read traffic 的主要工具</strong>：</p>
<ul>
<li>最多 15 個 read replica、replication lag 10-30ms</li>
<li>read replica autoscaler 按 CPU / connection 自動加減</li>
<li>對應 <a href="/blog/backend/09-performance-capacity/cases/draftkings-aurora-financial-ledger/" data-link-title="9.C4 DraftKings：Aurora 撐 100 萬 ops/min 的體育博彩金融帳本" data-link-desc="DraftKings 用 Aurora MySQL 跑體育博彩金融帳本、Super Bowl 流量 &#43;50% 不影響延遲">9.C4 DraftKings</a> 用多個 read replica 處理「比賽期間用戶查 balance」流量</li>
</ul>
<p><strong>2. 200 個獨立 cluster 模式</strong>：</p>
<ul>
<li>Aurora 的實務設計通常用多個 bounded cluster 控制 blast radius</li>
<li>按業務切多個小 cluster（<a href="/blog/backend/09-performance-capacity/cases/draftkings-aurora-financial-ledger/" data-link-title="9.C4 DraftKings：Aurora 撐 100 萬 ops/min 的體育博彩金融帳本" data-link-desc="DraftKings 用 Aurora MySQL 跑體育博彩金融帳本、Super Bowl 流量 &#43;50% 不影響延遲">9.C4 DraftKings</a> 200 個）、降低 <a href="/blog/backend/knowledge-cards/blast-radius/" data-link-title="Blast Radius" data-link-desc="說明事故影響面如何估算與隔離">blast radius</a></li>
<li>對應 microservice 私有 store（<a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix</a> 同樣思維）</li>
</ul>
<p><strong>3. Aurora I/O-Optimized</strong>：</p>
<ul>
<li>2023-05 推出的 storage 配置</li>
<li>適合 I/O-heavy workload（write 多、scan 多）</li>
<li>比 standard storage 貴、但少 I/O 收費</li>
<li>對應 <a href="/blog/backend/09-performance-capacity/cases/draftkings-aurora-financial-ledger/" data-link-title="9.C4 DraftKings：Aurora 撐 100 萬 ops/min 的體育博彩金融帳本" data-link-desc="DraftKings 用 Aurora MySQL 跑體育博彩金融帳本、Super Bowl 流量 &#43;50% 不影響延遲">9.C4 DraftKings</a> 用 I/O-Optimized 加速</li>
</ul>
<p><strong>4. Aurora Serverless v2</strong>：</p>
<ul>
<li>ACU（Aurora Capacity Unit）為單位、自動 scale 0.5-128 ACU</li>
<li>適合 dev / test、稀疏 workload、unpredictable burst</li>
<li>不適合：sustained predictable high workload（provisioned 便宜）</li>
</ul>
<p><strong>5. Cross-region Global Database</strong>：</p>
<ul>
<li>&lt; 1 秒 typical replication lag、但是 async</li>
<li>secondary region 可 read，write 仍回 primary region</li>
<li>DR 切換通常 1-2 分鐘</li>
<li>對應 <a href="/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered</a> — 跨市場各自獨立 Aurora，合規邊界優先於 Global Database</li>
</ul>
<p><strong>6. Connection pool 仍是隱性限制</strong>：</p>
<ul>
<li>Aurora 跟傳統 PostgreSQL 一樣有 connection pool 上限</li>
<li>應用層 + Aurora 之間建議用 RDS Proxy 做 pool 共享</li>
<li>對應 <a href="/blog/backend/09-performance-capacity/cases/ntt-docomo-lemino-japanese-streaming/" data-link-title="9.C29 NTT DOCOMO Lemino：3 個月達 500 萬 MAU 的串流後端" data-link-desc="Lemino 用 DynamoDB &#43; AWS Media Services 撐 30 channels live &#43; 5M MAU、工程工時下降 90%">9.C29 Lemino</a> — RDB connection limit 是 surge 場景的 bottleneck；Lemino 案例發生在 RDS，但 connection-bound 機制同樣適用 Aurora</li>
</ul>
<h2 id="deep-article已完成">Deep article（已完成）</h2>
<p>本 vendor 現有 deep article 覆蓋 Aurora 從 storage architecture、fleet 治理到容量彈性、連線管理與 distributed 升級門檻的核心 production 議題：</p>
<table>
  <thead>
      <tr>
          <th>主題</th>
          <th>文章</th>
          <th>對應 production 議題</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>quorum-based 分散式 log、韌性即性能、6-way replication</td>
          <td><a href="storage-architecture/">storage-architecture</a></td>
          <td>4-of-6 write / 3-of-6 read、DraftKings 6ms 寫 / &lt;1ms 讀 production reference</td>
      </tr>
      <tr>
          <td>Cross-AZ failover lifecycle、&lt; 30 秒 RTO、endpoint routing</td>
          <td><a href="cross-az-failover-rto/">cross-az-failover-rto</a></td>
          <td>application DNS cache + connection pool 對齊、Standard Chartered 受監管獨立 cluster 而非 Global Database failover</td>
      </tr>
      <tr>
          <td>15 replica 上限、lag profile、headroom 預留、fleet 治理 3 條 driver</td>
          <td><a href="read-replica-scaling/">read-replica-scaling</a></td>
          <td>Aurora fleet 治理 SSoT、DraftKings headroom 預留、FanDuel 雙 SLO 並行</td>
      </tr>
      <tr>
          <td>跨 region async replication、&lt; 1 秒 lag、合規 anti-recommendation</td>
          <td><a href="global-database-multi-region/">global-database-multi-region</a></td>
          <td>planned vs unplanned failover RTO、Standard Chartered 合規禁止跨境複製反指標</td>
      </tr>
      <tr>
          <td>從自管 PostgreSQL / MySQL 遷到 Aurora（Type C operational redesign）</td>
          <td><a href="migrate-from-self-managed-pg-mysql/">migrate-from-self-managed-pg-mysql</a></td>
          <td>Standard Chartered 合規 lead time、Netflix 非 all-purpose store 邊界</td>
      </tr>
      <tr>
          <td>ACU 自動擴縮、min/max 設定、混合 cluster、成本 crossover</td>
          <td><a href="serverless-v2-scaling/">serverless-v2-scaling</a></td>
          <td>離峰浪費 vs 尖峰不足、穩定高負載 serverless 反而更貴</td>
      </tr>
      <tr>
          <td>多 cluster 業務切分、blast radius 隔離、fleet 治理</td>
          <td><a href="multi-cluster-business-split/">multi-cluster-business-split</a></td>
          <td>Netflix 微服務私有 store + DB 種類 consolidation 雙重成立</td>
      </tr>
      <tr>
          <td>RDS Proxy connection multiplexing、pinning 陷阱、failover 加速</td>
          <td><a href="rds-proxy-connection-pooling/">rds-proxy-connection-pooling</a></td>
          <td>Lambda 連線風暴、pinning 讓 multiplexing 失效</td>
      </tr>
      <tr>
          <td>standard Aurora vs Aurora DSQL 升級門檻取捨</td>
          <td><a href="aurora-vs-dsql-tradeoff/">aurora-vs-dsql-tradeoff</a></td>
          <td>single-writer 上限 vs active-active distributed、何時跨 paradigm</td>
      </tr>
  </tbody>
</table>
<p>I/O-Optimized vs Standard 成本對比由 <a href="/blog/backend/01-database/vendors/postgresql/aurora-io-optimized-cost/" data-link-title="Aurora PostgreSQL I/O-Optimized Cost" data-link-desc="Aurora PostgreSQL Standard 與 I/O-Optimized 的成本模型、I/O 壓力、workload 判斷、遷移與回退條件">Aurora PostgreSQL I/O-Optimized Cost</a> 主寫（storage I/O 成本模型 SSoT），本 vendor 各篇提到 storage 成本時 cross-link 它、不重複展開。</p>
<p>跨 vendor entry：先看 <a href="../cockroachdb/aurora-dsql-spanner-decision-tree/">CockroachDB vs Aurora DSQL vs Spanner 決策樹</a>（distributed SQL 三選一 + 撞牆訊號分型），再決定是否進 Aurora overview。</p>
<h2 id="後續擴充仍待補">後續擴充（仍待補）</h2>
<ul>
<li>Aurora Global Database write forwarding 深入</li>
<li>Babelfish（SQL Server 相容層）適用判斷</li>
<li>Blue/Green deployment 做 major version 升級</li>
<li>Backup / PITR restore drill（hands-on lab）</li>
</ul>
<h2 id="anti-recommendation-與升級路由">Anti-recommendation 與升級路由</h2>
<p>Aurora 的 managed SQL 能把大量操作責任交給 AWS，但它仍保留 single-primary SQL 的資料模型與交易邊界。這一段先說何時維持 RDS / Aurora，再說何時升級 Global Database、Serverless v2、RDS Proxy、Aurora DSQL 或 DynamoDB。</p>
<table>
  <thead>
      <tr>
          <th>機制 / 路線</th>
          <th>維持簡單設計的條件</th>
          <th>升級訊號</th>
          <th>主要引用路徑</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>RDS PostgreSQL / MySQL</td>
          <td>upstream 相容、成本、版本節奏比 storage 分離更重要</td>
          <td>read replica lag、backup / failover、storage growth 成主題</td>
          <td><a href="/blog/backend/01-database/vendors/postgresql/" data-link-title="PostgreSQL" data-link-desc="多用途 OLTP 主流關聯式資料庫、MVCC、豐富 SQL 特性、是 Aurora / Cosmos DB / Spanner / CockroachDB / Aurora DSQL 的相容目標">PostgreSQL vendor</a>、<a href="/blog/backend/01-database/vendors/mysql/" data-link-title="MySQL" data-link-desc="高併發網路服務常用關聯式資料庫、Vitess / PlanetScale 分片生態、GitHub / Shopify / Facebook 規模驗證">MySQL vendor</a></td>
      </tr>
      <tr>
          <td>Aurora provisioned</td>
          <td>workload sustained、容量可預測、團隊能管理 instance class</td>
          <td>read replica、fast failover、storage autoscale 是主要需求</td>
          <td><a href="/blog/backend/knowledge-cards/replication-lag/" data-link-title="Replication Lag" data-link-desc="說明資料副本落後正式來源多久，以及它如何影響讀取正確性">Replication Lag</a>、<a href="/blog/backend/knowledge-cards/failover/" data-link-title="Failover" data-link-desc="說明主要服務或節點失效時如何切換到備援能力">Failover</a></td>
      </tr>
      <tr>
          <td>Aurora Serverless v2</td>
          <td>sustained workload 已穩定且 provisioned 成本較低</td>
          <td>稀疏 tenant、dev/test、不可預測 burst</td>
          <td><a href="/blog/backend/knowledge-cards/cost-per-request/" data-link-title="Cost Per Request" data-link-desc="把雲端成本拆到單一 API 請求的 unit economics 模型">Cost Per Request</a>、<a href="/blog/backend/knowledge-cards/scheduled-scaling/" data-link-title="Scheduled Scaling" data-link-desc="說明按已知時間表預先擴容的 autoscaler 模式">Scheduled Scaling</a></td>
      </tr>
      <tr>
          <td>RDS Proxy</td>
          <td>application pool 已能控制 backend connection</td>
          <td>Lambda / surge / connection storm 造成 pool 壓力</td>
          <td><a href="/blog/backend/knowledge-cards/connection-pool/" data-link-title="Connection Pool" data-link-desc="說明連線池如何限制下游資源並影響服務容量">Connection Pool</a></td>
      </tr>
      <tr>
          <td>Global Database</td>
          <td>single-region DR 已符合 RTO/RPO</td>
          <td>跨 region read、regional DR、低 RPO 是產品需求</td>
          <td><a href="/blog/backend/knowledge-cards/rto/" data-link-title="RTO" data-link-desc="說明恢復時間目標如何約束事故回復策略">RTO</a>、<a href="/blog/backend/knowledge-cards/rpo/" data-link-title="RPO" data-link-desc="說明恢復點目標如何定義可接受資料損失範圍">RPO</a>、<a href="/blog/backend/knowledge-cards/stale-read/" data-link-title="Stale Read" data-link-desc="讀取到落後於最新寫入版本的舊資料">Stale Read</a></td>
      </tr>
      <tr>
          <td>Aurora DSQL / Spanner / CockroachDB</td>
          <td>single-primary write 仍足夠</td>
          <td>multi-region active-active write、global strong consistency</td>
          <td><a href="/blog/backend/01-database/global-distributed-oltp/" data-link-title="1.11 全球分散式 OLTP" data-link-desc="Spanner / Aurora DSQL / Cosmos DB multi-region write / CockroachDB / TiDB 的全球一致性取捨">1.11 全球分散式 OLTP</a></td>
      </tr>
      <tr>
          <td>DynamoDB</td>
          <td>SQL query 與 transaction 仍是主要價值</td>
          <td>access pattern 固定、connection-free surge、KV latency 成主題</td>
          <td><a href="/blog/backend/01-database/vendors/dynamodb/" data-link-title="DynamoDB" data-link-desc="AWS managed key-value、partition-based scaling、9000 萬 RPS sustained 實戰證據">DynamoDB vendor</a></td>
      </tr>
  </tbody>
</table>
<p>Aurora 的簡單路徑是先把 operation transfer 寫清楚。Backup、minor upgrade、storage growth、failover 與 read replica lag 交給平台後，schema design、query shape、transaction boundary、connection pool 與 cost guardrail 仍由 application / SRE 共同承擔。</p>
<p>Global Database 的升級路徑要先定義讀寫方向。它適合 DR 與跨地理 read，若業務需要多 region 同時寫入並保持強一致，應直接進入 Aurora DSQL、Spanner 或 CockroachDB 的 distributed SQL 比較。</p>
<h2 id="已知-limitation-與後續路由">已知 limitation 與後續路由</h2>
<p>Aurora overview 目前完成 managed SQL 判斷。下一輪 deep article / playbook 應補 storage architecture、RDS Proxy、Global Database、Serverless v2、I/O-Optimized cost、PostgreSQL / MySQL → Aurora migration 與 Aurora → Aurora DSQL 的分歧路徑。</p>
<h2 id="案例對照">案例對照</h2>
<table>
  <thead>
      <tr>
          <th>案例</th>
          <th>規模</th>
          <th>教學重點</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/draftkings-aurora-financial-ledger/" data-link-title="9.C4 DraftKings：Aurora 撐 100 萬 ops/min 的體育博彩金融帳本" data-link-desc="DraftKings 用 Aurora MySQL 跑體育博彩金融帳本、Super Bowl 流量 &#43;50% 不影響延遲">9.C4 DraftKings</a></td>
          <td>1M ops/min、&lt;1ms reads、6ms writes、200 個 DB</td>
          <td>體育博彩金融帳本、按業務切 cluster</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/standard-chartered-aurora-banking/" data-link-title="9.C14 Standard Chartered：受監管銀行的 Aurora 4000 TPS 容量提升" data-link-desc="Standard Chartered 銀行遷移到 Aurora 後吞吐量提升 10 倍至 4000 TPS、跨 7 個受監管市場">9.C14 Standard Chartered</a></td>
          <td>4000 TPS、7 個受監管市場、10x 提升</td>
          <td>受監管金融跨市場部署</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/netflix-aurora-consolidation/" data-link-title="9.C23 Netflix：把關聯式 DB 統一到 Aurora、效能 &#43;75%、成本 -28%" data-link-desc="Netflix 把多套關聯式 DB 統一到 Aurora、效能提升 75%、成本下降 28%、串流數十億小時">9.C23 Netflix</a></td>
          <td>+75% 效能、-28% 成本</td>
          <td>多套 RDBMS 統一到 Aurora</td>
      </tr>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/fanduel-dual-peak-betting-streaming/" data-link-title="9.C28 FanDuel：體育直播 &#43; 投注的雙重峰值" data-link-desc="FanDuel 3.5M MAU、Super Bowl 期間擴容 5-10 倍、用 AWS Local Zones &#43; Wavelength &#43; Outposts 處理 20&#43; 州的雙重峰值">9.C28 FanDuel</a></td>
          <td>Super Bowl 5-10x peak</td>
          <td>直播 + 投注雙工作負載</td>
      </tr>
  </tbody>
</table>
<p>Aurora case 的讀法是看 operation transfer 如何變成容量與成本結果。DraftKings 與 FanDuel 提供 peak OLTP 訊號，Standard Chartered 提供合規分區訊號，Netflix 則提供多套 RDBMS 整併到 managed SQL 的組織與成本訊號。</p>
<h2 id="反向-sibling-路由">反向 sibling 路由</h2>
<p>Aurora 的反向 sibling 路由用來避免把 managed SQL 誤讀成唯一升級方向。若讀者從 PostgreSQL / MySQL 章節過來，先對照 <a href="/blog/backend/01-database/vendors/postgresql/migrate-to-aurora/" data-link-title="PostgreSQL → Aurora Migration：protocol 相容、operational 重設計" data-link-desc="Aurora 號稱 PostgreSQL-compatible 但 operational model 不同（storage decouple / cluster endpoint / instance class / 自家備份）；遷移流程是混合（protocol drop-in &#43; operational phased）、5 個 production 踩雷（extension 不支援 / replication slot 不直通 / autovacuum 行為差 / IAM 認證強制 / cost model 換算）、跟 Patroni / read replica / DR 對位">PostgreSQL → Aurora</a> 與 <a href="/blog/backend/01-database/vendors/mysql/migrate-to-aurora/" data-link-title="MySQL → Aurora MySQL：storage layer 轉手到 AWS、replication / HA / backup 全部 outsource" data-link-desc="自管 MySQL → Aurora MySQL 是 Type C operational hybrid migration — wire protocol 一致、ops 責任轉到 AWS。本文走 6 維 audit（Operational High）、Aurora storage architecture 衝擊、4-phase migration、5 production 踩雷、何時維持原路線。">MySQL → Aurora</a>；若核心需求是 connection surge，補讀 <a href="/blog/backend/01-database/vendors/dynamodb/" data-link-title="DynamoDB" data-link-desc="AWS managed key-value、partition-based scaling、9000 萬 RPS sustained 實戰證據">DynamoDB vendor</a> 與 <a href="/blog/backend/09-performance-capacity/cases/ntt-docomo-lemino-japanese-streaming/" data-link-title="9.C29 NTT DOCOMO Lemino：3 個月達 500 萬 MAU 的串流後端" data-link-desc="Lemino 用 DynamoDB &#43; AWS Media Services 撐 30 channels live &#43; 5M MAU、工程工時下降 90%">Lemino case</a>；若核心需求是 multi-region active-active write，轉到 <a href="/blog/backend/01-database/vendors/spanner/" data-link-title="Google Cloud Spanner" data-link-desc="全球分散式 strong-consistency OLTP、TrueTime API、線性擴展到 10 億 req/sec">Spanner vendor</a> 或 <a href="/blog/backend/01-database/vendors/cockroachdb/" data-link-title="CockroachDB" data-link-desc="分散式 SQL、PostgreSQL 相容、跨區強一致、Spanner 的開源 / 跨雲替代">CockroachDB vendor</a>。</p>
<p>這條路由的判準是先問「保留 SQL + 轉移 operation」是否足夠。答案成立時，Aurora 是 RDS / 自管 MySQL / 自管 PostgreSQL 的 managed endpoint；答案需要改成 global quorum、partition-key access pattern 或 document API 時，Aurora 應退到對照組，而非成為最後選項。</p>
<h2 id="常見陷阱">常見陷阱</h2>
<ul>
<li><strong>誤以為 Aurora 等於無限擴</strong>：寫吞吐仍受 primary 限制，容量曲線和 distributed SQL 不同</li>
<li><strong>忽略 read replica</strong>：把所有 query 打 primary，會浪費 read replica scaling 能力</li>
<li><strong>跨 region 強一致誤解</strong>：Global Database 是 <em>async</em> 複製，multi-region active-active 要看 Aurora DSQL / Spanner / CockroachDB</li>
<li><strong>connection pool 忽略</strong>：Aurora 仍是 PostgreSQL / MySQL、connection 上限有效</li>
<li><strong>單一巨大 cluster</strong>：把所有業務塞進一個 cluster 會放大 blast radius，通常要按業務切</li>
</ul>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>完整 T1 對照：<a href="/blog/backend/01-database/vendors/" data-link-title="資料庫 Vendor 清單" data-link-desc="規劃 SQL、managed SQL、document、KV 與 distributed SQL 的服務頁撰寫順序與教學大綱">01-database vendors index</a></li>
<li>平行：<a href="/blog/backend/01-database/vendors/dynamodb/" data-link-title="DynamoDB" data-link-desc="AWS managed key-value、partition-based scaling、9000 萬 RPS sustained 實戰證據">DynamoDB vendor page</a>（NoSQL 對比）</li>
<li>上游：<a href="/blog/backend/01-database/transaction-boundary/" data-link-title="1.3 Transaction 與一致性邊界" data-link-desc="交易邊界、isolation level、retry 策略、distributed transaction（2PC、Saga）與跨 region 強一致取捨">1.3 Transaction Boundary</a> / <a href="/blog/backend/01-database/global-distributed-oltp/" data-link-title="1.11 全球分散式 OLTP" data-link-desc="Spanner / Aurora DSQL / Cosmos DB multi-region write / CockroachDB / TiDB 的全球一致性取捨">1.11 全球分散式 OLTP</a></li>
<li>下游：<a href="/blog/backend/01-database/large-scale-db-migration/" data-link-title="1.12 大規模 DB 遷移實戰" data-link-desc="跨 DB 遷移的 dual-write、[shadow read](/backend/knowledge-cards/shadow-read/)、cutover、rollback 流程 — 從實戰案例提煉的工程做法">1.12 大規模 DB 遷移實戰</a>（從 RDS / 自管遷到 Aurora）</li>
<li>跨模組：<a href="/blog/backend/09-performance-capacity/bottleneck-localization/" data-link-title="9.5 瓶頸定位流程" data-link-desc="從 app 到 DB / cache / broker / 第三方 quota 的逐層瓶頸定位">9.5 瓶頸定位流程</a>、<a href="/blog/backend/09-performance-capacity/capacity-planning/" data-link-title="9.6 容量規劃模型" data-link-desc="peak forecast、headroom budget、growth curve、autoscaling sizing">9.6 容量規劃模型</a></li>
<li>Last reviewed：2026-05-22（Aurora storage / Serverless / Global Database / I/O-Optimized 屬時間敏感 claim）</li>
<li>官方：<a href="https://aws.amazon.com/rds/aurora/">Amazon Aurora</a>、<a href="https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/Aurora.Overview.StorageReliability.html">Aurora storage architecture</a></li>
</ul>
]]></content:encoded></item><item><title>Google Cloud Spanner</title><link>https://tarrragon.github.io/blog/backend/01-database/vendors/spanner/</link><pubDate>Wed, 13 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/01-database/vendors/spanner/</guid><description>&lt;p>Cloud Spanner 是 Google 內部 2007 年起跑、2017 年開放為 GCP 服務的 &lt;em>全球分散式 SQL OLTP&lt;/em>。內部撐 Google Ads / Play / Search 計費、外部支援 Blockchain.com、Sharechat、ZEE5 等。它的公開案例重點是每秒 10 億請求等級、線性擴展、強一致與 global distribution 可以同時成為 OLTP 設計目標。&lt;/p>
&lt;h2 id="教學路線全球強一致與-truetime-成本">教學路線：全球強一致與 TrueTime 成本&lt;/h2>
&lt;p>Spanner 服務頁的教學目標是把 global strong consistency、TrueTime、Paxos、region layout 與 processing unit 連成一條產品決策線。讀者讀完後要能判斷何時需要全球一致 SQL，並理解這種能力的 latency、成本與雲平台邊界。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>學習段&lt;/th>
 &lt;th>核心問題&lt;/th>
 &lt;th>對應段落&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Global consistency&lt;/td>
 &lt;td>強一致 SQL 為什麼需要時間邊界與 consensus&lt;/td>
 &lt;td>定位、適用場景、&lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/linearizability/" data-link-title="Linearizability" data-link-desc="每次操作看起來都在單一全域順序中即時生效的一致性語意">Linearizability&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Region layout&lt;/td>
 &lt;td>instance config、leader region、replica 如何影響 latency&lt;/td>
 &lt;td>容量規劃要點、常見陷阱&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Capacity unit&lt;/td>
 &lt;td>node / processing unit 如何取代傳統 shard 心智模型&lt;/td>
 &lt;td>容量特性、案例對照&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Use-case pressure&lt;/td>
 &lt;td>billing、subscription、ticketing、金融交易何時需要 Spanner&lt;/td>
 &lt;td>適用場景、案例對照&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>替代路由&lt;/td>
 &lt;td>何時用 PostgreSQL、CockroachDB、Aurora DSQL、DynamoDB&lt;/td>
 &lt;td>不適用場景、跟其他 vendor 的取捨&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="定位truetime--paxos-的全球線性-sql">定位：TrueTime + Paxos 的全球線性 SQL&lt;/h2>
&lt;p>Spanner 解決的是跨地理位置同時追求 strong consistency、linear scalability 與 global availability 的 OLTP 問題。&lt;/p>
&lt;p>&lt;strong>關鍵設計&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>TrueTime API&lt;/strong>：用 GPS + 原子鐘提供「全球 unambiguous 時間戳」、誤差 &amp;lt; 7ms&lt;/li>
&lt;li>&lt;strong>External consistency&lt;/strong>（線性化）：跨節點交易順序跟 wall clock 一致&lt;/li>
&lt;li>&lt;strong>Paxos-based replication&lt;/strong>：跨 zone / region &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/quorum/" data-link-title="Quorum" data-link-desc="分散式系統以多數節點同意作為提交或讀取有效性的門檻">quorum&lt;/a>&lt;/li>
&lt;li>&lt;strong>線性擴展&lt;/strong>：2 nodes → 45K reads/sec、4 nodes → 90K reads/sec、依此類推&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>容量特性&lt;/strong>（引自 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">9.C10 Spanner 案例&lt;/a>）：&lt;/p>
&lt;ul>
&lt;li>內部峰值：&amp;gt; 10 億 requests / sec&lt;/li>
&lt;li>線性擴展（不像 USL 系統會在某點 plateau）&lt;/li>
&lt;li>跨 region quorum 延遲：50-200ms（視 region 距離）&lt;/li>
&lt;li>最小容量單位：100 processing units（PU）≈ 1/10 node、適合小負載&lt;/li>
&lt;/ul>
&lt;h2 id="適用場景">適用場景&lt;/h2>
&lt;p>&lt;strong>1. 金融交易、ticketing inventory、payment ledger&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>需要強一致，避免 double-spend、oversell 或帳務順序錯亂&lt;/li>
&lt;li>全球用戶但需要原子性&lt;/li>
&lt;li>對應案例：&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">9.C10 Spanner&lt;/a> — Google Ads 計費與 Google Play 訂閱都需要把每次計費事件放進可驗證順序&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>2. 全球用戶的 OLTP（不只 read replica）&lt;/strong>：&lt;/p></description><content:encoded><![CDATA[<p>Cloud Spanner 是 Google 內部 2007 年起跑、2017 年開放為 GCP 服務的 <em>全球分散式 SQL OLTP</em>。內部撐 Google Ads / Play / Search 計費、外部支援 Blockchain.com、Sharechat、ZEE5 等。它的公開案例重點是每秒 10 億請求等級、線性擴展、強一致與 global distribution 可以同時成為 OLTP 設計目標。</p>
<h2 id="教學路線全球強一致與-truetime-成本">教學路線：全球強一致與 TrueTime 成本</h2>
<p>Spanner 服務頁的教學目標是把 global strong consistency、TrueTime、Paxos、region layout 與 processing unit 連成一條產品決策線。讀者讀完後要能判斷何時需要全球一致 SQL，並理解這種能力的 latency、成本與雲平台邊界。</p>
<table>
  <thead>
      <tr>
          <th>學習段</th>
          <th>核心問題</th>
          <th>對應段落</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Global consistency</td>
          <td>強一致 SQL 為什麼需要時間邊界與 consensus</td>
          <td>定位、適用場景、<a href="/blog/backend/knowledge-cards/linearizability/" data-link-title="Linearizability" data-link-desc="每次操作看起來都在單一全域順序中即時生效的一致性語意">Linearizability</a></td>
      </tr>
      <tr>
          <td>Region layout</td>
          <td>instance config、leader region、replica 如何影響 latency</td>
          <td>容量規劃要點、常見陷阱</td>
      </tr>
      <tr>
          <td>Capacity unit</td>
          <td>node / processing unit 如何取代傳統 shard 心智模型</td>
          <td>容量特性、案例對照</td>
      </tr>
      <tr>
          <td>Use-case pressure</td>
          <td>billing、subscription、ticketing、金融交易何時需要 Spanner</td>
          <td>適用場景、案例對照</td>
      </tr>
      <tr>
          <td>替代路由</td>
          <td>何時用 PostgreSQL、CockroachDB、Aurora DSQL、DynamoDB</td>
          <td>不適用場景、跟其他 vendor 的取捨</td>
      </tr>
  </tbody>
</table>
<h2 id="定位truetime--paxos-的全球線性-sql">定位：TrueTime + Paxos 的全球線性 SQL</h2>
<p>Spanner 解決的是跨地理位置同時追求 strong consistency、linear scalability 與 global availability 的 OLTP 問題。</p>
<p><strong>關鍵設計</strong>：</p>
<ul>
<li><strong>TrueTime API</strong>：用 GPS + 原子鐘提供「全球 unambiguous 時間戳」、誤差 &lt; 7ms</li>
<li><strong>External consistency</strong>（線性化）：跨節點交易順序跟 wall clock 一致</li>
<li><strong>Paxos-based replication</strong>：跨 zone / region <a href="/blog/backend/knowledge-cards/quorum/" data-link-title="Quorum" data-link-desc="分散式系統以多數節點同意作為提交或讀取有效性的門檻">quorum</a></li>
<li><strong>線性擴展</strong>：2 nodes → 45K reads/sec、4 nodes → 90K reads/sec、依此類推</li>
</ul>
<p><strong>容量特性</strong>（引自 <a href="/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">9.C10 Spanner 案例</a>）：</p>
<ul>
<li>內部峰值：&gt; 10 億 requests / sec</li>
<li>線性擴展（不像 USL 系統會在某點 plateau）</li>
<li>跨 region quorum 延遲：50-200ms（視 region 距離）</li>
<li>最小容量單位：100 processing units（PU）≈ 1/10 node、適合小負載</li>
</ul>
<h2 id="適用場景">適用場景</h2>
<p><strong>1. 金融交易、ticketing inventory、payment ledger</strong>：</p>
<ul>
<li>需要強一致，避免 double-spend、oversell 或帳務順序錯亂</li>
<li>全球用戶但需要原子性</li>
<li>對應案例：<a href="/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">9.C10 Spanner</a> — Google Ads 計費與 Google Play 訂閱都需要把每次計費事件放進可驗證順序</li>
</ul>
<p><strong>2. 全球用戶的 OLTP（不只 read replica）</strong>：</p>
<ul>
<li>跨 region 寫入、各地用戶寫入本地 region 仍維持全球強一致</li>
<li>它承擔的是 multi-region write path，而非 single primary + 跨 region read replica</li>
<li>對應案例：Blockchain.com（高頻 crypto 交易、強一致）</li>
</ul>
<p><strong>3. 想擺脫 sharding 複雜度</strong>：</p>
<ul>
<li>傳統大規模 SQL 常走應用層 sharding（管 shard key、跨 shard query、resharding）</li>
<li>Spanner 自動 partition，application 主要管理 schema、query shape 與 region layout</li>
<li>對應案例：<a href="/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">9.C10 Spanner 案例</a> — 「節點數量是容量單位」，shard placement 由 Spanner 管理</li>
</ul>
<p><strong>4. PostgreSQL 相容路徑</strong>：</p>
<ul>
<li>2024 後 Spanner 提供 PostgreSQL dialect interface</li>
<li>從 PostgreSQL 應用遷入 Spanner 變得容易</li>
<li>跟 CockroachDB / Aurora DSQL 類似的策略</li>
</ul>
<h2 id="不適用場景">不適用場景</h2>
<p><strong>1. 跨洲低延遲（&lt; 50ms）需求</strong>：</p>
<ul>
<li>跨洲 quorum 物理上 100ms+ 不可壓縮</li>
<li>替代：single-region OLTP（Aurora、Cloud SQL）+ <a href="/blog/backend/knowledge-cards/eventual-consistency/" data-link-title="Eventual Consistency" data-link-desc="允許短暫不一致、最終收斂到同一資料狀態的一致性語意">eventual consistency</a> 跨 region 同步</li>
</ul>
<p><strong>2. 高 throughput 但容忍 eventual consistency</strong>：</p>
<ul>
<li>Spanner 強一致有溢價，eventual consistency workload 通常有更低成本選項</li>
<li>替代：Bigtable（wide-column、eventual）、DynamoDB Global Tables（KV、eventual）</li>
</ul>
<p><strong>3. 小規模 OLTP</strong>：</p>
<ul>
<li>100 PU 起跳、月費約 $65 起、比 Cloud SQL 貴</li>
<li>流量 &lt; 1000 RPS 的場景、Cloud SQL 更划算</li>
<li>Spanner 主要對 <em>中大規模 + 全球</em> workload</li>
</ul>
<p><strong>4. 跨雲需求</strong>：</p>
<ul>
<li>Spanner 是 GCP managed service，cross-cloud / on-prem 需求要看 CockroachDB、TiDB 或其他自管路線</li>
<li>替代：CockroachDB、TiDB（自管、可跨雲）</li>
</ul>
<p><strong>5. 需要 OLAP 分析能力</strong>：</p>
<ul>
<li>Spanner 定位在 OLTP，analytics workload 交給 BigQuery 或其他 OLAP 系統</li>
<li>替代：跟 BigQuery 整合做 ETL、或用 Spanner Graph（2024 推出）</li>
</ul>
<h2 id="跟其他-vendor-的取捨">跟其他 vendor 的取捨</h2>
<p><strong>vs Aurora DSQL（AWS 2024 推出、概念對標 Spanner）</strong>：</p>
<ul>
<li>Spanner：用 TrueTime hardware、生產驗證 17 年（Google 內部）+ 7 年（公開）</li>
<li>Aurora DSQL：新（2024）、PostgreSQL 相容、serverless</li>
<li>選 Spanner：GCP 生態、需要極致成熟度</li>
<li>選 Aurora DSQL：AWS 生態、需要 PostgreSQL ORM 相容</li>
</ul>
<p><strong>vs CockroachDB</strong>：</p>
<ul>
<li>Spanner：managed、TrueTime hardware、GCP 限定</li>
<li>CockroachDB：自管、HLC + Raft（不靠 TrueTime）、跨雲</li>
<li>選 Spanner：想把 operation 交給 GCP managed service，並需要 Google 規模驗證</li>
<li>選 CockroachDB：跨雲 / on-prem、PostgreSQL 相容、自管彈性</li>
</ul>
<p><strong>vs TiDB</strong>：</p>
<ul>
<li>Spanner：GCP-only、PostgreSQL-like</li>
<li>TiDB：可自管 + Cloud、MySQL 相容、中國 / 亞洲生態深</li>
<li>選 Spanner：英語 / 歐美生態</li>
<li>選 TiDB：MySQL 應用、亞洲市場</li>
</ul>
<p><strong>vs Aurora（traditional single-region scaling）</strong>：</p>
<ul>
<li>Spanner：全球分散式</li>
<li>Aurora：single-region scaling</li>
<li>選 Spanner：流量明確跨 region + 需要強一致</li>
<li>選 Aurora：流量集中一個 region（多數情況）</li>
</ul>
<p><strong>vs Cosmos DB（multi-region write）</strong>：</p>
<ul>
<li>Spanner：strong consistency 跨 region</li>
<li>Cosmos DB：5 個 <a href="/blog/backend/knowledge-cards/consistency-level/" data-link-title="Consistency Level" data-link-desc="資料系統對讀寫一致性語意的可選擇層級">consistency level</a>s、AP 系統（含 strong 但語義不同）</li>
<li>選 Spanner：需要 linearizable（金融、ticketing）</li>
<li>選 Cosmos DB：可接受 session / eventual、Azure 生態、需要 multi-model</li>
</ul>
<p><strong>vs Bigtable</strong>：</p>
<ul>
<li>Spanner：SQL、強一致、OLTP</li>
<li>Bigtable：wide-column、eventual replication、時序 / IoT / 大資料</li>
<li>兩者互補：Bigtable 承擔大資料 / wide-column，Spanner 承擔強一致 OLTP</li>
</ul>
<p><strong>vs PostgreSQL（baseline）</strong>：</p>
<ul>
<li>PostgreSQL：single-primary、跨 region async replication、90% 場景夠用</li>
<li>Spanner：全球線性化、強一致跨 region、需要 GCP + 接受 latency / 成本</li>
<li>從 PostgreSQL 升級 Spanner 的判準：流量明確跨 region，且跨 region 一致性是 product requirement</li>
<li>詳見 <a href="/blog/backend/01-database/vendors/postgresql/" data-link-title="PostgreSQL" data-link-desc="多用途 OLTP 主流關聯式資料庫、MVCC、豐富 SQL 特性、是 Aurora / Cosmos DB / Spanner / CockroachDB / Aurora DSQL 的相容目標">PostgreSQL vendor page</a> 取捨段 + <a href="/blog/backend/01-database/global-distributed-oltp/" data-link-title="1.11 全球分散式 OLTP" data-link-desc="Spanner / Aurora DSQL / Cosmos DB multi-region write / CockroachDB / TiDB 的全球一致性取捨">1.11 全球分散式 OLTP</a></li>
</ul>
<h2 id="容量規劃要點">容量規劃要點</h2>
<p>從 09 案例庫 + Spanner 文件提煉：</p>
<p><strong>1. 節點數量 = 容量單位</strong>：</p>
<ul>
<li>節點配置通常用較長週期 review，並在事件高峰前預先調整</li>
<li>線性擴展讓 forecast 簡單（2x 流量 → 2x 節點）</li>
<li>對應 <a href="/blog/backend/09-performance-capacity/capacity-planning/" data-link-title="9.6 容量規劃模型" data-link-desc="peak forecast、headroom budget、growth curve、autoscaling sizing">9.6 容量規劃模型</a> 的「不可水平擴容服務」反向 — Spanner 是 <em>可水平擴容</em> 但需要 <em>提前 provision</em></li>
</ul>
<p><strong>2. 跨 region quorum 配置</strong>：</p>
<ul>
<li>multi-region instance 可選擇哪些 region 是 voting member</li>
<li>voting region 數量決定 failure domain</li>
<li>跨大洲 voting 延遲高、跨大陸內可接受</li>
</ul>
<p><strong>3. 100 PU 起跳的 granular sizing</strong>：</p>
<ul>
<li>早期 Spanner 最小單位 1 node（約 $1000+/month）、中小負載難用</li>
<li>後來推出 100 PU（1/10 node、約 $65/month）、讓小負載也能 evaluate</li>
</ul>
<p><strong>4. 跨環境與新產品能力要查官方文件</strong>：</p>
<ul>
<li>Spanner 的跨環境、graph、PostgreSQL dialect 與 change streams 能力持續演進</li>
<li>實作前要用官方文件確認可用 region、版本、限制與 pricing</li>
</ul>
<p><strong>5. TrueTime 是 Spanner 價值之一</strong>：</p>
<ul>
<li>Spanner 還有 schema migration without downtime、change streams、interleaved tables</li>
<li>評估 Spanner 要同時看跨 region 強一致與整體 SQL 工程能力</li>
</ul>
<h2 id="deep-article已完成">Deep article（已完成）</h2>
<p>本批 4 篇 deep article 已完成、覆蓋 Spanner 從 TrueTime 到 Cloud SQL 遷移的核心 production 議題：</p>
<table>
  <thead>
      <tr>
          <th>主題</th>
          <th>文章</th>
          <th>對應 production 議題</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>TrueTime 是手段、line-rate scaling 才是設計目的、commit wait 數學</td>
          <td><a href="truetime-api-depth/">truetime-api-depth</a></td>
          <td>9.C10 Google internal dogfood 線性擴展模式、ε 暴衝失敗模式、cross-region voting latency 影響</td>
      </tr>
      <tr>
          <td>external consistency / serializability / linearizability 精確定義差異</td>
          <td><a href="consistency-models-comparison/">consistency-models-comparison</a></td>
          <td>PG SSI / CockroachDB / Spanner / Aurora DSQL line-rate scaling 對照、9.C10 cross-region quorum 100-200ms</td>
      </tr>
      <tr>
          <td>Schema migration without downtime + interleaved tables 物理 layout</td>
          <td><a href="schema-migration-interleaved-tables/">schema-migration-interleaved-tables</a></td>
          <td>TrueTime version timestamp、5 production 踩雷、跟 PostgreSQL online schema change 對照</td>
      </tr>
      <tr>
          <td>Cloud SQL for PostgreSQL → Spanner（Type E paradigm shift）playbook</td>
          <td><a href="migrate-from-cloud-sql-pg/">migrate-from-cloud-sql-pg</a></td>
          <td>sizing barrier（100 pu 起跳）+ &lt; 50ms write latency no-go、cost crossover 報告、9.C10 dogfood 邊界</td>
      </tr>
      <tr>
          <td>Change Streams (CDC)：data change record、watch partition、下游整合</td>
          <td><a href="change-streams-cdc/">change-streams-cdc</a></td>
          <td>OLTP 變更餵搜尋 / 快取 / 分析、child partition 接力、retention 失敗、跟 DynamoDB Streams 對照</td>
      </tr>
      <tr>
          <td>PostgreSQL dialect vs GoogleSQL、相容子集邊界、dialect 不可逆</td>
          <td><a href="postgresql-dialect/">postgresql-dialect</a></td>
          <td>PostgreSQL 生態遷入、相容性 audit、dialect 鎖定的高代價回退、何時選 PG dialect</td>
      </tr>
      <tr>
          <td>Spanner Graph (2024)：property graph、跟 relational 共存、GQL</td>
          <td><a href="spanner-graph/">spanner-graph</a></td>
          <td>多跳關係查詢、edge table layout 不可逆設計代價、super node 扇出、何時用專用 graph DB</td>
      </tr>
      <tr>
          <td>Spanner ↔ BigQuery federation：OLTP/OLAP 分工、Data Boost</td>
          <td><a href="bigquery-federation/">bigquery-federation</a></td>
          <td>分析查詢拖垮 OLTP、Data Boost workload 隔離、federation vs change-stream 落地、何時分出去</td>
      </tr>
  </tbody>
</table>
<p>DB4 cross-vendor entry：先看 <a href="../cockroachdb/aurora-dsql-spanner-decision-tree/">CockroachDB / Aurora DSQL / Spanner 決策樹</a> 識別 driver path、再進本 vendor 深度。</p>
<h2 id="後續擴充仍待補">後續擴充（仍待補）</h2>
<ul>
<li>Spanner Graph 進階查詢 lab（GQL pattern、super node 處理、遍歷效能調校）</li>
<li>Data Boost 容量規劃與成本模型 deep dive</li>
<li>Change Streams → Dataflow hands-on lab（建 stream、部署 pipeline、驗證 end-to-end）</li>
<li>Spanner regional → multi-region topology 升級 playbook</li>
</ul>
<h2 id="anti-recommendation-與升級路由">Anti-recommendation 與升級路由</h2>
<p>Spanner 的 global strong consistency 是高價值能力，也會把 latency、region layout 與 GCP lock-in 帶進核心架構。這一段先說何時維持 Cloud SQL / Aurora，再說何時升級 Spanner、CockroachDB、Aurora DSQL 或 Bigtable / DynamoDB。</p>
<table>
  <thead>
      <tr>
          <th>機制 / 路線</th>
          <th>維持簡單設計的條件</th>
          <th>升級訊號</th>
          <th>主要引用路徑</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Cloud SQL / Aurora</td>
          <td>single-region primary 足夠、跨 region 只需 async DR / read</td>
          <td>跨 region 寫入順序是產品契約、double-spend / oversell 代價高</td>
          <td><a href="/blog/backend/01-database/vendors/aurora/" data-link-title="AWS Aurora" data-link-desc="AWS managed PostgreSQL / MySQL、storage / compute 分離、&#43;75% 效能改善的 production 證據">Aurora vendor</a>、<a href="/blog/backend/knowledge-cards/rpo/" data-link-title="RPO" data-link-desc="說明恢復點目標如何定義可接受資料損失範圍">RPO</a></td>
      </tr>
      <tr>
          <td>Spanner regional</td>
          <td>單 region 強一致與水平擴容已足夠</td>
          <td>需要 multi-region availability、regional failure survival</td>
          <td><a href="/blog/backend/knowledge-cards/quorum/" data-link-title="Quorum" data-link-desc="分散式系統以多數節點同意作為提交或讀取有效性的門檻">Quorum</a>、<a href="/blog/backend/knowledge-cards/external-consistency/" data-link-title="External Consistency" data-link-desc="交易可見順序與外部真實時間順序一致的強一致性語意">External Consistency</a></td>
      </tr>
      <tr>
          <td>Spanner multi-region</td>
          <td>GCP 生態、SQL workload、global consistency 是核心需求</td>
          <td>跨洲 p99 目標過低、成本或 GCP lock-in 成為主要風險</td>
          <td><a href="/blog/backend/knowledge-cards/latency-budget/" data-link-title="Latency Budget" data-link-desc="把 user-perceived latency 拆到每個 stage 的配額、反推架構選擇">Latency Budget</a>、<a href="/blog/backend/knowledge-cards/global-oltp/" data-link-title="Global OLTP" data-link-desc="跨地理區域仍維持交易一致性的 OLTP 設計責任與代價">Global OLTP</a></td>
      </tr>
      <tr>
          <td>CockroachDB</td>
          <td>GCP-only managed 服務可接受</td>
          <td>跨雲、on-prem、自管或 PostgreSQL wire 相容是硬需求</td>
          <td><a href="/blog/backend/01-database/vendors/cockroachdb/" data-link-title="CockroachDB" data-link-desc="分散式 SQL、PostgreSQL 相容、跨區強一致、Spanner 的開源 / 跨雲替代">CockroachDB vendor</a></td>
      </tr>
      <tr>
          <td>Aurora DSQL</td>
          <td>團隊已在 GCP 或需要 Spanner 成熟度</td>
          <td>AWS 生態、serverless distributed SQL、PostgreSQL 相容是主訴求</td>
          <td><a href="/blog/backend/01-database/vendors/postgresql/migrate-to-aurora-dsql/" data-link-title="PostgreSQL → Aurora DSQL Migration：PG wire-compatible Distributed SQL 的 Paradigm Shift" data-link-desc="Aurora DSQL（2024-12 re:Invent preview / 2025-05 GA）是 AWS 推的 PG wire-compatible *active-active distributed SQL*、跟 self-managed PG / Aurora PG 不同 paradigm（OCC &#43; snapshot isolation &#43; multi-region strong consistency）。Migration 結構是 *protocol drop-in &#43; paradigm shift*：app SQL 不太改、但 transaction retry / extension 缺位 / 多 region 一致性需重設計。本文走 DSQL vs Aurora PG vs self-managed PG 三軸對比、為什麼遷的三條 driver（global write / operational zero-touch / region resiliency）、Type E phased plan、5 production 踩雷（transaction retry 沒處理 / extension 缺位 / sequence throughput 限制 / Aurora PG 直升 DSQL 不可行 / region failover semantic）、跟 PG → Aurora 跟 PG → CockroachDB 對比">PG → Aurora DSQL Migration</a></td>
      </tr>
      <tr>
          <td>Bigtable / DynamoDB</td>
          <td>workload 可接受 eventual consistency 或 KV / wide-column</td>
          <td>強一致 SQL 的協調成本高於產品收益</td>
          <td><a href="/blog/backend/01-database/vendors/dynamodb/" data-link-title="DynamoDB" data-link-desc="AWS managed key-value、partition-based scaling、9000 萬 RPS sustained 實戰證據">DynamoDB vendor</a></td>
      </tr>
  </tbody>
</table>
<p>Spanner 的簡單路徑是先證明跨 region 一致性是產品需求。若只是想要全球 read latency，read replica、cache、edge KV 或 eventual consistency pipeline 可能更划算；Spanner 適合把「全球寫入順序正確」視為產品承諾的資料。</p>
<p>Region layout 的升級路徑要先定義 leader、voting replica 與使用者地理分布。跨洲 quorum 會把物理延遲放進 transaction path，因此 latency budget、降級策略與 read staleness policy 要一起寫進設計。</p>
<h2 id="已知-limitation-與後續路由">已知 limitation 與後續路由</h2>
<p>Spanner overview 目前完成 global SQL 判斷。下一輪 deep article / playbook 應補 TrueTime、external consistency、PostgreSQL dialect、interleaved tables、change streams、Cloud SQL / PostgreSQL → Spanner migration 與 Spanner / BigQuery federation。</p>
<h2 id="案例對照">案例對照</h2>
<table>
  <thead>
      <tr>
          <th>案例</th>
          <th>規模</th>
          <th>教學重點</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/backend/09-performance-capacity/cases/spanner-planetary-scale-database-gcp/" data-link-title="9.C10 Cloud Spanner：每秒 10 億請求的全球一致性資料庫" data-link-desc="Google Cloud Spanner 內部峰值 10 億 req/sec、跨地區強一致 — 全球分散式 OLTP 容量參考">9.C10 Cloud Spanner</a></td>
          <td>&gt; 10 億 req/sec、線性擴展</td>
          <td>全球強一致 OLTP 標竿</td>
      </tr>
  </tbody>
</table>
<p>Spanner case 的讀法是先看一致性需求，再看容量數字。10 億 req/sec 證明它能水平擴展，但讀者真正要回收的是「計費、訂閱、庫存、交易順序」這類需要 global external consistency 的產品壓力。</p>
<h2 id="反向-sibling-路由">反向 sibling 路由</h2>
<p>Spanner 的反向 sibling 路由用來把 global strong consistency 和雲端代管責任一起判讀。若讀者從 PostgreSQL / MySQL 過來，先確認是否具產品契約等級的 external consistency 需求；若只是 managed SQL 與 replica scaling，回 <a href="/blog/backend/01-database/vendors/aurora/" data-link-title="AWS Aurora" data-link-desc="AWS managed PostgreSQL / MySQL、storage / compute 分離、&#43;75% 效能改善的 production 證據">Aurora vendor</a>；若要 PostgreSQL-like distributed SQL 且需要自管或多雲彈性，對照 <a href="/blog/backend/01-database/vendors/cockroachdb/" data-link-title="CockroachDB" data-link-desc="分散式 SQL、PostgreSQL 相容、跨區強一致、Spanner 的開源 / 跨雲替代">CockroachDB vendor</a>；若 access pattern 是固定 KV / document，先看 <a href="/blog/backend/01-database/vendors/dynamodb/" data-link-title="DynamoDB" data-link-desc="AWS managed key-value、partition-based scaling、9000 萬 RPS sustained 實戰證據">DynamoDB vendor</a> 或 <a href="/blog/backend/01-database/vendors/cosmosdb/" data-link-title="Azure Cosmos DB" data-link-desc="全球分散式 multi-model DB、5 個 consistency levels、Microsoft 自家 dogfood 證據">Cosmos DB vendor</a>。</p>
<p>這條路由的判準是交易順序是否跨 region 影響產品正確性。Spanner 的價值在 external consistency、schema 與 SQL 能力、全球 deployment 與 Google Cloud operation model 的組合；若產品只需要 eventual / session consistency，較輕的 NoSQL 或 managed SQL 常有更低成本。</p>
<h2 id="常見陷阱">常見陷阱</h2>
<ul>
<li><strong>誤以為跨 region 強一致沒有延遲代價</strong>：跨洲 quorum 100-200ms 是物理成本</li>
<li><strong>設計 schema 像傳統 PostgreSQL</strong>：Spanner 有 interleaved tables、適當用能加速查詢</li>
<li><strong>所有讀取都用強一致</strong>：read-only transaction 可選 bounded staleness，reporting 類路徑常能用 <a href="/blog/backend/knowledge-cards/stale-read/" data-link-title="Stale Read" data-link-desc="讀取到落後於最新寫入版本的舊資料">stale read</a> 換較低成本</li>
<li><strong>單 region 用 Spanner</strong>：浪費、Cloud SQL / Aurora 更便宜</li>
<li><strong>不評估 100 PU 起跳</strong>：早年 1 node minimum、現在 100 PU 起、small workload 也可以 POC</li>
</ul>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>完整 T1 對照：<a href="/blog/backend/01-database/vendors/" data-link-title="資料庫 Vendor 清單" data-link-desc="規劃 SQL、managed SQL、document、KV 與 distributed SQL 的服務頁撰寫順序與教學大綱">01-database vendors index</a></li>
<li>平行：<a href="/blog/backend/01-database/vendors/aurora/" data-link-title="AWS Aurora" data-link-desc="AWS managed PostgreSQL / MySQL、storage / compute 分離、&#43;75% 效能改善的 production 證據">Aurora vendor</a>、<a href="/blog/backend/01-database/vendors/dynamodb/" data-link-title="DynamoDB" data-link-desc="AWS managed key-value、partition-based scaling、9000 萬 RPS sustained 實戰證據">DynamoDB vendor</a>、<a href="/blog/backend/01-database/vendors/cockroachdb/" data-link-title="CockroachDB" data-link-desc="分散式 SQL、PostgreSQL 相容、跨區強一致、Spanner 的開源 / 跨雲替代">CockroachDB vendor</a></li>
<li>上游：<a href="/blog/backend/01-database/global-distributed-oltp/" data-link-title="1.11 全球分散式 OLTP" data-link-desc="Spanner / Aurora DSQL / Cosmos DB multi-region write / CockroachDB / TiDB 的全球一致性取捨">1.11 全球分散式 OLTP</a></li>
<li>跨模組：<a href="/blog/backend/09-performance-capacity/capacity-planning/" data-link-title="9.6 容量規劃模型" data-link-desc="peak forecast、headroom budget、growth curve、autoscaling sizing">9.6 容量規劃模型</a> — 全球 OLTP 的容量規劃特殊性</li>
<li>Last reviewed：2026-05-22（processing units / PostgreSQL interface / TrueTime 文件屬時間敏感 claim）</li>
<li>官方：<a href="https://cloud.google.com/spanner">Cloud Spanner</a>、<a href="https://cloud.google.com/spanner/docs/true-time-external-consistency">TrueTime: Time Distributed in Spanner</a></li>
</ul>
]]></content:encoded></item><item><title>終端機 SQL 客戶端：harlequin、lazysql 與 pgcli/litecli 的選型</title><link>https://tarrragon.github.io/blog/linux/tools/cli/sql-database-clients/</link><pubDate>Mon, 15 Jun 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/linux/tools/cli/sql-database-clients/</guid><description>&lt;p>終端機 SQL 客戶端把資料庫的 schema、表格與查詢結果做成可導航的文字介面，讓遠端只有終端機時也能瀏覽資料、跑查詢、看結果，取代把連線資訊餵給桌面 GUI（DBeaver、TablePlus）的需求。在純 SSH 情境下，它補上「連到遠端 DB 做事」這塊，而且全是文字、低頻寬友善。&lt;/p>
&lt;p>本文承接 &lt;a href="https://tarrragon.github.io/blog/linux/tools/cli/cli-graphical-tools-overview/" data-link-title="終端機圖形化工具總覽：遠端操作下的 TUI、文字圖表與多工器" data-link-desc="在純文字終端機裡用 ASCII 與製圖字元做出監控儀表板、資料圖表與多視窗操作的工具總覽，並針對 SSH 伺服器、手機平板、低頻寬三種遠端情境給出選型判讀。">終端機圖形化工具總覽&lt;/a> 的資料庫客戶端分類。工具分兩種範式：全螢幕 TUI 客戶端，與增強型 REPL。&lt;/p>
&lt;h2 id="兩種範式全螢幕-tui-與增強型-repl">兩種範式：全螢幕 TUI 與增強型 REPL&lt;/h2>
&lt;p>全螢幕 TUI（&lt;code>harlequin&lt;/code> / &lt;code>lazysql&lt;/code>）把 schema 樹、查詢編輯器、結果表格排進多個面板，像縮小版的 DBeaver。增強型 REPL（&lt;code>pgcli&lt;/code> / &lt;code>litecli&lt;/code>）仍是一行一行打 SQL，但加上語法高亮、智能補全與表格化輸出，是 &lt;code>psql&lt;/code> / &lt;code>mysql&lt;/code> 原生 client 的升級版。&lt;/p>
&lt;p>選哪種看工作型態：要邊看 schema 邊探索資料，用全螢幕 TUI；要快速接上跑幾條查詢、或塞進腳本，用 REPL。&lt;/p>
&lt;h2 id="全螢幕-tuiide-風與瀏覽器風">全螢幕 TUI：IDE 風與瀏覽器風&lt;/h2>
&lt;p>兩個全螢幕 TUI 的互動模型剛好相反，這是選型最該先分清的一點。&lt;/p>
&lt;p>&lt;code>harlequin&lt;/code> 是 SQL IDE 風：左側 Data Catalog 樹列出 db → schema → table → 欄位（帶型別標記，整數 &lt;code>#&lt;/code>、字串 &lt;code>s&lt;/code>、numeric &lt;code>#.#&lt;/code>），中間是查詢編輯器，寫好 SQL 按 &lt;code>Ctrl+Enter&lt;/code> 執行、結果在下方表格。點表只是把表的限定名稱插進編輯器、輔助組查詢，不會自動顯示資料。它用 Python（Textual）寫，adapter 涵蓋 postgres、mysql、sqlite、duckdb、odbc，預設 adapter 是 duckdb，連別的 DB 用 &lt;code>-a&lt;/code> 指定，例如 &lt;code>harlequin -a postgres &amp;quot;&amp;lt;連線字串&amp;gt;&amp;quot;&lt;/code> 或 &lt;code>harlequin -a sqlite db.sqlite&lt;/code>。&lt;/p>
&lt;p>&lt;code>lazysql&lt;/code> 是瀏覽器風：左側選一個表，右邊直接顯示該表記錄、不必寫 SELECT。上方分頁切 Records / Columns / Constraints / Foreign Keys / Indexes（&lt;code>[&lt;/code> 與 &lt;code>]&lt;/code> 切換）。篩選按 &lt;code>/&lt;/code> 開 WHERE 輸入，帶運算子補全（&lt;code>=&lt;/code>、&lt;code>≠&lt;/code>、&lt;code>&amp;gt;&lt;/code>、&lt;code>between&lt;/code>、&lt;code>ilike&lt;/code>、&lt;code>in&lt;/code>、&lt;code>like&lt;/code>、&lt;code>regexp&lt;/code> 等），只寫條件、不用整句。要跑自訂 SQL 按 &lt;code>Ctrl+E&lt;/code> 開編輯器（vim modal、有 &lt;code>-- INSERT --&lt;/code> 模式）寫完整語句、&lt;code>Ctrl+R&lt;/code> 執行。它用 Go 寫、lazygit 風的鍵盤導航。&lt;/p>
&lt;p>判讀：習慣先寫 query 再看結果的選 &lt;code>harlequin&lt;/code>；習慣點開表瀏覽、偶爾才下複雜 SQL 的選 &lt;code>lazysql&lt;/code>。&lt;/p>
&lt;p>&lt;code>dblab&lt;/code>（Go）與 &lt;code>rainfrog&lt;/code>（Rust）是另外兩個實機驗證過的瀏覽風 TUI。&lt;code>dblab&lt;/code> 走混合型：左側樹（&lt;code>Ctrl+H&lt;/code> 聚焦、&lt;code>j&lt;/code>/&lt;code>k&lt;/code> 移動、&lt;code>Enter&lt;/code> 看表的列）配上方查詢編輯器（&lt;code>Ctrl+E&lt;/code> 執行），瀏覽與寫 query 兩條路都有。它有一個實測 gotcha：編輯器的查詢要 schema 限定（&lt;code>SELECT * FROM public.products&lt;/code> 才行、裸 &lt;code>products&lt;/code> 會報 relation 不存在），因為編輯器連線的 search_path 沒含 public，而樹瀏覽（&lt;code>Enter&lt;/code>）不受這點影響。&lt;code>rainfrog&lt;/code> 專注 Postgres：側欄選表看 rows / columns / constraints / indexes / rls policies，查詢編輯器是 vim modal（&lt;code>i&lt;/code> 進 insert、&lt;code>v&lt;/code> 進 visual），另有 history 與 favorites 分頁。實測它不支援滑鼠操作，面板與分頁一律用 &lt;code>Tab&lt;/code> 切換、其餘靠鍵盤導航。&lt;/p>
&lt;h2 id="增強型-repldbcli-家族">增強型 REPL：dbcli 家族&lt;/h2>
&lt;p>&lt;code>pgcli&lt;/code>（Postgres）、&lt;code>mycli&lt;/code>（MySQL）、&lt;code>litecli&lt;/code>（SQLite）是同一個專案（dbcli）的三個 client，把原生 &lt;code>psql&lt;/code> / &lt;code>mysql&lt;/code> / &lt;code>sqlite3&lt;/code> 補上智能補全（表名、欄位、關鍵字）、語法高亮與對齊的表格化輸出。手感仍是 REPL，但打 SQL 時會即時提示。&lt;/p>
&lt;p>它們也能非互動執行、適合腳本：&lt;code>litecli&lt;/code> 用 &lt;code>-e&lt;/code>（&lt;code>litecli db.sqlite -e &amp;quot;SELECT ...&amp;quot;&lt;/code>），&lt;code>pgcli&lt;/code> 在 stdin 非 TTY 時讀管線（&lt;code>echo &amp;quot;SELECT ...&amp;quot; | pgcli &amp;quot;&amp;lt;連線字串&amp;gt;&amp;quot;&lt;/code>），輸出是對齊的 ASCII 表格。要在腳本裡取一次查詢結果、又想要比 &lt;code>psql -c&lt;/code> 更好的排版時，這條路最直接。&lt;/p></description><content:encoded><![CDATA[<p>終端機 SQL 客戶端把資料庫的 schema、表格與查詢結果做成可導航的文字介面，讓遠端只有終端機時也能瀏覽資料、跑查詢、看結果，取代把連線資訊餵給桌面 GUI（DBeaver、TablePlus）的需求。在純 SSH 情境下，它補上「連到遠端 DB 做事」這塊，而且全是文字、低頻寬友善。</p>
<p>本文承接 <a href="/blog/linux/tools/cli/cli-graphical-tools-overview/" data-link-title="終端機圖形化工具總覽：遠端操作下的 TUI、文字圖表與多工器" data-link-desc="在純文字終端機裡用 ASCII 與製圖字元做出監控儀表板、資料圖表與多視窗操作的工具總覽，並針對 SSH 伺服器、手機平板、低頻寬三種遠端情境給出選型判讀。">終端機圖形化工具總覽</a> 的資料庫客戶端分類。工具分兩種範式：全螢幕 TUI 客戶端，與增強型 REPL。</p>
<h2 id="兩種範式全螢幕-tui-與增強型-repl">兩種範式：全螢幕 TUI 與增強型 REPL</h2>
<p>全螢幕 TUI（<code>harlequin</code> / <code>lazysql</code>）把 schema 樹、查詢編輯器、結果表格排進多個面板，像縮小版的 DBeaver。增強型 REPL（<code>pgcli</code> / <code>litecli</code>）仍是一行一行打 SQL，但加上語法高亮、智能補全與表格化輸出，是 <code>psql</code> / <code>mysql</code> 原生 client 的升級版。</p>
<p>選哪種看工作型態：要邊看 schema 邊探索資料，用全螢幕 TUI；要快速接上跑幾條查詢、或塞進腳本，用 REPL。</p>
<h2 id="全螢幕-tuiide-風與瀏覽器風">全螢幕 TUI：IDE 風與瀏覽器風</h2>
<p>兩個全螢幕 TUI 的互動模型剛好相反，這是選型最該先分清的一點。</p>
<p><code>harlequin</code> 是 SQL IDE 風：左側 Data Catalog 樹列出 db → schema → table → 欄位（帶型別標記，整數 <code>#</code>、字串 <code>s</code>、numeric <code>#.#</code>），中間是查詢編輯器，寫好 SQL 按 <code>Ctrl+Enter</code> 執行、結果在下方表格。點表只是把表的限定名稱插進編輯器、輔助組查詢，不會自動顯示資料。它用 Python（Textual）寫，adapter 涵蓋 postgres、mysql、sqlite、duckdb、odbc，預設 adapter 是 duckdb，連別的 DB 用 <code>-a</code> 指定，例如 <code>harlequin -a postgres &quot;&lt;連線字串&gt;&quot;</code> 或 <code>harlequin -a sqlite db.sqlite</code>。</p>
<p><code>lazysql</code> 是瀏覽器風：左側選一個表，右邊直接顯示該表記錄、不必寫 SELECT。上方分頁切 Records / Columns / Constraints / Foreign Keys / Indexes（<code>[</code> 與 <code>]</code> 切換）。篩選按 <code>/</code> 開 WHERE 輸入，帶運算子補全（<code>=</code>、<code>≠</code>、<code>&gt;</code>、<code>between</code>、<code>ilike</code>、<code>in</code>、<code>like</code>、<code>regexp</code> 等），只寫條件、不用整句。要跑自訂 SQL 按 <code>Ctrl+E</code> 開編輯器（vim modal、有 <code>-- INSERT --</code> 模式）寫完整語句、<code>Ctrl+R</code> 執行。它用 Go 寫、lazygit 風的鍵盤導航。</p>
<p>判讀：習慣先寫 query 再看結果的選 <code>harlequin</code>；習慣點開表瀏覽、偶爾才下複雜 SQL 的選 <code>lazysql</code>。</p>
<p><code>dblab</code>（Go）與 <code>rainfrog</code>（Rust）是另外兩個實機驗證過的瀏覽風 TUI。<code>dblab</code> 走混合型：左側樹（<code>Ctrl+H</code> 聚焦、<code>j</code>/<code>k</code> 移動、<code>Enter</code> 看表的列）配上方查詢編輯器（<code>Ctrl+E</code> 執行），瀏覽與寫 query 兩條路都有。它有一個實測 gotcha：編輯器的查詢要 schema 限定（<code>SELECT * FROM public.products</code> 才行、裸 <code>products</code> 會報 relation 不存在），因為編輯器連線的 search_path 沒含 public，而樹瀏覽（<code>Enter</code>）不受這點影響。<code>rainfrog</code> 專注 Postgres：側欄選表看 rows / columns / constraints / indexes / rls policies，查詢編輯器是 vim modal（<code>i</code> 進 insert、<code>v</code> 進 visual），另有 history 與 favorites 分頁。實測它不支援滑鼠操作，面板與分頁一律用 <code>Tab</code> 切換、其餘靠鍵盤導航。</p>
<h2 id="增強型-repldbcli-家族">增強型 REPL：dbcli 家族</h2>
<p><code>pgcli</code>（Postgres）、<code>mycli</code>（MySQL）、<code>litecli</code>（SQLite）是同一個專案（dbcli）的三個 client，把原生 <code>psql</code> / <code>mysql</code> / <code>sqlite3</code> 補上智能補全（表名、欄位、關鍵字）、語法高亮與對齊的表格化輸出。手感仍是 REPL，但打 SQL 時會即時提示。</p>
<p>它們也能非互動執行、適合腳本：<code>litecli</code> 用 <code>-e</code>（<code>litecli db.sqlite -e &quot;SELECT ...&quot;</code>），<code>pgcli</code> 在 stdin 非 TTY 時讀管線（<code>echo &quot;SELECT ...&quot; | pgcli &quot;&lt;連線字串&gt;&quot;</code>），輸出是對齊的 ASCII 表格。要在腳本裡取一次查詢結果、又想要比 <code>psql -c</code> 更好的排版時，這條路最直接。</p>
<p><code>usql</code> 走另一條路：universal CLI，一個工具用統一介面連 Postgres、MySQL、SQLite 等各種 DB，連線字串以 scheme 區分（<code>postgres://...</code>、<code>sqlite:...</code>），也支援 <code>-c</code> 非互動執行。它不是 TUI，行為像能連多種 DB 的加強版 <code>psql</code>。一台機器要連好幾種不同 DB 時，一個 usql 比每種 DB 各裝一個 client 省事。</p>
<h2 id="遠端連線的一個-gotchassl-模式因-driver-而異">遠端連線的一個 gotcha：SSL 模式因 driver 而異</h2>
<p>同一個 Postgres、同一條連線字串，不同 client 的 SSL 預設不一樣。<code>lazysql</code> 走 Go 的 <code>pq</code> driver、預設要求 SSL，連沒開 SSL 的 DB 會報 <code>pq: SSL is not enabled on the server</code>，要在連線字串加 <code>?sslmode=disable</code>：<code>postgresql://user:pass@host:5432/db?sslmode=disable</code>。<code>pgcli</code> 與 <code>harlequin</code> 走 Python 的 psycopg、預設行為不同，同樣的 DB 不加也能連。遠端連不上、又確定帳密與 port 對的時候，先查的就是 sslmode。</p>
<h2 id="同類其他選擇">同類其他選擇</h2>
<p>同範式還有 <code>gobang</code>（Rust）。它未上 crates.io、Homebrew 也沒有對應 formula，本機未能安裝，列出供參考、未實機驗證。</p>
<h2 id="下一步路由">下一步路由</h2>
<ul>
<li>把 DB client 擺進可持久化的多工器 pane：<a href="/blog/linux/tools/cli/tmux-persistence-and-basics/" data-link-title="tmux 基礎：遠端 session 持久化與基本操作" data-link-desc="tmux 終端機多工器的遠端使用核心：detach/reattach 讓 session 脫離連線生命週期、prefix key 與 window/pane 操作、手機友善的快捷鍵調校，以及 tmux 與 zellij 的選型對照。">tmux 基礎</a>。</li>
<li>編譯型工具（<code>lazysql</code> / <code>dblab</code> / <code>rainfrog</code>）搬到遠端的單一 binary 注意事項：<a href="/blog/linux/tools/cli/git-line-graph-tools-for-remote-cli/" data-link-title="遠端 CLI 開發的 git 線圖工具選型：tig、lazygit、gitui 與管線增強" data-link-desc="純 CLI、遠端開發情境下查看 git 分支線圖的工具地景，從 tig 唯讀瀏覽到 lazygit/gitui 操作中樞的定位差異，含選型判準與 lazygit 上手、delta side-by-side diff 設定。">git 線圖工具選型</a>。</li>
<li>SQL 客戶端在遠端工具分類中的定位：<a href="/blog/linux/tools/cli/cli-graphical-tools-overview/" data-link-title="終端機圖形化工具總覽：遠端操作下的 TUI、文字圖表與多工器" data-link-desc="在純文字終端機裡用 ASCII 與製圖字元做出監控儀表板、資料圖表與多視窗操作的工具總覽，並針對 SSH 伺服器、手機平板、低頻寬三種遠端情境給出選型判讀。">終端機圖形化工具總覽</a>。</li>
</ul>
]]></content:encoded></item><item><title>SQLite SQL Dialect and Index Limits</title><link>https://tarrragon.github.io/blog/backend/01-database/vendors/sqlite/sql-dialect-index-limits/</link><pubDate>Thu, 21 May 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/01-database/vendors/sqlite/sql-dialect-index-limits/</guid><description>&lt;p>SQLite SQL dialect and index limits 的核心責任是說明 SQLite 和 server SQL 的語意差異。SQLite 可以執行大量 SQL，也支援 transaction、index、trigger、view、window function 與 JSON；但它的 typing、constraint、file-level operation、query planner 與 extension model 會影響測試可信度、migration 成本與 production adapter。&lt;/p>
&lt;p>本文的判讀錨點是：SQLite 測過代表某個 repository contract 在 SQLite 語意下成立。當 production target 是 PostgreSQL、MySQL、D1、Turso 或其他 server database 時，測試與 migration 要補上 dialect gap evidence。&lt;/p>
&lt;h2 id="type-affinity">Type Affinity&lt;/h2>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/type-affinity/" data-link-title="Type Affinity" data-link-desc="說明 SQLite 如何用 type affinity 決定欄位的型別傾向與值的儲存方式">Type affinity&lt;/a> 的核心責任是定義資料寫入時如何被保存與比較。SQLite 官方 &lt;a href="https://www.sqlite.org/datatype3.html">Datatypes&lt;/a> 文件說明 SQLite 使用 dynamic typing，型別關聯在 value 層與 column affinity 層共同作用；&lt;a href="https://www.sqlite.org/stricttables.html">STRICT tables&lt;/a> 則提供較嚴格的型別檢查。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>議題&lt;/th>
 &lt;th>SQLite 行為重點&lt;/th>
 &lt;th>Production 影響&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>Integer&lt;/td>
 &lt;td>value type 可依寫入內容變化&lt;/td>
 &lt;td>test fixture 可能放過錯誤型別&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Text&lt;/td>
 &lt;td>collation 與比較語意需明確設定&lt;/td>
 &lt;td>排序、大小寫、unique 判斷要對照 target DB&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Date/time&lt;/td>
 &lt;td>常以 TEXT / REAL / INTEGER 表示&lt;/td>
 &lt;td>timezone、range query、serialization 要一致&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Boolean&lt;/td>
 &lt;td>常以 integer convention 表示&lt;/td>
 &lt;td>adapter 要定義 true / false encoding&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>STRICT&lt;/td>
 &lt;td>提供更接近 server DB 的型別 guard&lt;/td>
 &lt;td>適合作為 fixture 預設，仍需 production test&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>Type affinity 的教學重點是把資料合約放在 application boundary。若 domain 說 &lt;code>created_at&lt;/code> 是 timestamp，就要定義 storage format、timezone、precision、comparison query 與 serialization，而非只讓 SQLite 接受任意 value。&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sql" data-lang="sql">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="k">CREATE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">TABLE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">orders&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">id&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">INTEGER&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">PRIMARY&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">KEY&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">created_at&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">TEXT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">NOT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">NULL&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">total_cents&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">INTEGER&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">NOT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">NULL&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">CHECK&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">total_cents&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">&amp;gt;=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">STRICT&lt;/span>&lt;span class="p">;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>這段 schema 用 &lt;code>STRICT&lt;/code>、&lt;code>NOT NULL&lt;/code> 與 &lt;code>CHECK&lt;/code> 讓 fixture 更接近正式資料合約。Production target 仍要跑 PostgreSQL / MySQL container test，確認 timestamp、integer range 與 constraint error mapping。&lt;/p>
&lt;h2 id="constraint-behavior">Constraint Behavior&lt;/h2>
&lt;p>Constraint behavior 的核心責任是確保資料完整性由 database 和 application 共同維護。SQLite 支援 primary key、unique、check、foreign key 與 deferred constraint，但 foreign key enforcement 需要明確啟用，migration / test runner 也要確認連線設定。&lt;/p></description><content:encoded><![CDATA[<p>SQLite SQL dialect and index limits 的核心責任是說明 SQLite 和 server SQL 的語意差異。SQLite 可以執行大量 SQL，也支援 transaction、index、trigger、view、window function 與 JSON；但它的 typing、constraint、file-level operation、query planner 與 extension model 會影響測試可信度、migration 成本與 production adapter。</p>
<p>本文的判讀錨點是：SQLite 測過代表某個 repository contract 在 SQLite 語意下成立。當 production target 是 PostgreSQL、MySQL、D1、Turso 或其他 server database 時，測試與 migration 要補上 dialect gap evidence。</p>
<h2 id="type-affinity">Type Affinity</h2>
<p><a href="/blog/backend/knowledge-cards/type-affinity/" data-link-title="Type Affinity" data-link-desc="說明 SQLite 如何用 type affinity 決定欄位的型別傾向與值的儲存方式">Type affinity</a> 的核心責任是定義資料寫入時如何被保存與比較。SQLite 官方 <a href="https://www.sqlite.org/datatype3.html">Datatypes</a> 文件說明 SQLite 使用 dynamic typing，型別關聯在 value 層與 column affinity 層共同作用；<a href="https://www.sqlite.org/stricttables.html">STRICT tables</a> 則提供較嚴格的型別檢查。</p>
<table>
  <thead>
      <tr>
          <th>議題</th>
          <th>SQLite 行為重點</th>
          <th>Production 影響</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Integer</td>
          <td>value type 可依寫入內容變化</td>
          <td>test fixture 可能放過錯誤型別</td>
      </tr>
      <tr>
          <td>Text</td>
          <td>collation 與比較語意需明確設定</td>
          <td>排序、大小寫、unique 判斷要對照 target DB</td>
      </tr>
      <tr>
          <td>Date/time</td>
          <td>常以 TEXT / REAL / INTEGER 表示</td>
          <td>timezone、range query、serialization 要一致</td>
      </tr>
      <tr>
          <td>Boolean</td>
          <td>常以 integer convention 表示</td>
          <td>adapter 要定義 true / false encoding</td>
      </tr>
      <tr>
          <td>STRICT</td>
          <td>提供更接近 server DB 的型別 guard</td>
          <td>適合作為 fixture 預設，仍需 production test</td>
      </tr>
  </tbody>
</table>
<p>Type affinity 的教學重點是把資料合約放在 application boundary。若 domain 說 <code>created_at</code> 是 timestamp，就要定義 storage format、timezone、precision、comparison query 與 serialization，而非只讓 SQLite 接受任意 value。</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="ln">1</span><span class="cl"><span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">orders</span><span class="w"> </span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w">  </span><span class="n">id</span><span class="w"> </span><span class="nb">INTEGER</span><span class="w"> </span><span class="k">PRIMARY</span><span class="w"> </span><span class="k">KEY</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w">  </span><span class="n">created_at</span><span class="w"> </span><span class="nb">TEXT</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="w">  </span><span class="n">total_cents</span><span class="w"> </span><span class="nb">INTEGER</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="w"> </span><span class="k">CHECK</span><span class="w"> </span><span class="p">(</span><span class="n">total_cents</span><span class="w"> </span><span class="o">&gt;=</span><span class="w"> </span><span class="mi">0</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span><span class="k">STRICT</span><span class="p">;</span></span></span></code></pre></div><p>這段 schema 用 <code>STRICT</code>、<code>NOT NULL</code> 與 <code>CHECK</code> 讓 fixture 更接近正式資料合約。Production target 仍要跑 PostgreSQL / MySQL container test，確認 timestamp、integer range 與 constraint error mapping。</p>
<h2 id="constraint-behavior">Constraint Behavior</h2>
<p>Constraint behavior 的核心責任是確保資料完整性由 database 和 application 共同維護。SQLite 支援 primary key、unique、check、foreign key 與 deferred constraint，但 foreign key enforcement 需要明確啟用，migration / test runner 也要確認連線設定。</p>
<table>
  <thead>
      <tr>
          <th>Constraint</th>
          <th>SQLite 審查點</th>
          <th>操作判準</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Foreign key</td>
          <td><code>PRAGMA foreign_keys = ON</code></td>
          <td>每個 connection / test setup 都要驗證</td>
      </tr>
      <tr>
          <td>Unique</td>
          <td>NULL、collation、expression</td>
          <td>對照 target DB 的 NULL uniqueness 與 collation</td>
      </tr>
      <tr>
          <td>Check</td>
          <td>type affinity 互動</td>
          <td>用 domain invalid case 驗證</td>
      </tr>
      <tr>
          <td>Deferred</td>
          <td>transaction boundary</td>
          <td>用 multi-step workflow 測 commit-time failure</td>
      </tr>
  </tbody>
</table>
<p>Foreign key 是 SQLite fixture 最常漏掉的設定。每個測試連線開啟後應立刻查 <code>PRAGMA foreign_keys;</code>，並用一個故意違反 FK 的 fixture case 確認錯誤會出現。</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="ln">1</span><span class="cl"><span class="n">PRAGMA</span><span class="w"> </span><span class="n">foreign_keys</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">ON</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w"></span><span class="k">SELECT</span><span class="w"> </span><span class="n">foreign_keys</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">pragma_foreign_keys</span><span class="p">;</span></span></span></code></pre></div><p>Constraint error 要在 repository adapter 層被歸類。若 production target 會把 duplicate key、foreign key、check violation 映射成不同 error code，SQLite fixture 也要至少保留 domain-level classification test。</p>
<h2 id="transaction-behavior">Transaction Behavior</h2>
<p>Transaction behavior 的核心責任是定義讀寫隔離、savepoint、nested workflow 與 retry。SQLite 官方 <a href="https://www.sqlite.org/isolation.html">isolation</a> 文件說明 connection 之間的隔離語意；WAL mode 下 reader / writer behavior 也會影響 concurrent test。</p>
<table>
  <thead>
      <tr>
          <th>行為</th>
          <th>SQLite 判讀</th>
          <th>測試影響</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Single writer</td>
          <td>同一時間只有一個 writer 取得寫鎖</td>
          <td>concurrent writer test 要顯式設計</td>
      </tr>
      <tr>
          <td>Snapshot read</td>
          <td>WAL mode 下 reader 可讀舊 snapshot</td>
          <td>freshness 與 read-after-write 要分開測</td>
      </tr>
      <tr>
          <td>Savepoint</td>
          <td>適合 nested workflow</td>
          <td>repository transaction helper 要支援</td>
      </tr>
      <tr>
          <td>Busy timeout</td>
          <td>lock wait policy</td>
          <td>integration test 要設定固定 timeout</td>
      </tr>
  </tbody>
</table>
<p>Savepoint 可以讓 application 實作可組合的 transaction helper。若上層 workflow 已在 transaction 內，內層 repository 可以使用 savepoint 承接局部 rollback，而非開另一個 database transaction。</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="ln">1</span><span class="cl"><span class="n">SAVEPOINT</span><span class="w"> </span><span class="n">create_order</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w"></span><span class="k">INSERT</span><span class="w"> </span><span class="k">INTO</span><span class="w"> </span><span class="n">orders</span><span class="p">(</span><span class="n">id</span><span class="p">,</span><span class="w"> </span><span class="n">created_at</span><span class="p">,</span><span class="w"> </span><span class="n">total_cents</span><span class="p">)</span><span class="w"> </span><span class="k">VALUES</span><span class="w"> </span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;2026-05-21T00:00:00Z&#39;</span><span class="p">,</span><span class="w"> </span><span class="mi">1200</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w"></span><span class="n">RELEASE</span><span class="w"> </span><span class="n">create_order</span><span class="p">;</span></span></span></code></pre></div><p>Busy timeout 是測試穩定性的關鍵設定。若 fixture 會平行跑測試，應每個 temp DB 獨立，或在專門 concurrency lab 裡測 <code>SQLITE_BUSY</code>；一般 contract test 要追求 deterministic result。</p>
<h2 id="index-model">Index Model</h2>
<p>Index model 的核心責任是把查詢形狀與資料量變成可觀測的計畫。SQLite 支援 B-tree index、covering index、partial index、expression index 與 query planner；但 planner choice、統計資訊與 function support 會和 target DB 不同。</p>
<table>
  <thead>
      <tr>
          <th>Index 類型</th>
          <th>適用情境</th>
          <th>審查問題</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Composite index</td>
          <td>多欄位 equality / range query</td>
          <td>欄位順序是否符合主要 query pattern</td>
      </tr>
      <tr>
          <td>Partial index</td>
          <td>active / pending / soft-delete row</td>
          <td>predicate 是否穩定、target DB 是否支援</td>
      </tr>
      <tr>
          <td>Expression index</td>
          <td>normalized email、date bucket</td>
          <td>function deterministic 與 migration 支援</td>
      </tr>
      <tr>
          <td>Covering index</td>
          <td>read-mostly list page</td>
          <td>index size 與 write overhead</td>
      </tr>
  </tbody>
</table>
<p>Index review 要從 query pattern 開始，而非從「常用欄位」開始。SQLite 可以用 <code>EXPLAIN QUERY PLAN</code> 檢查是否掃 index；production target 要用自己的 explain 工具重跑。</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="ln">1</span><span class="cl"><span class="k">EXPLAIN</span><span class="w"> </span><span class="n">QUERY</span><span class="w"> </span><span class="n">PLAN</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w"></span><span class="k">SELECT</span><span class="w"> </span><span class="n">id</span><span class="p">,</span><span class="w"> </span><span class="n">total_cents</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w"></span><span class="k">FROM</span><span class="w"> </span><span class="n">orders</span><span class="w">
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="w"></span><span class="k">WHERE</span><span class="w"> </span><span class="n">created_at</span><span class="w"> </span><span class="o">&gt;=</span><span class="w"> </span><span class="s1">&#39;2026-05-01T00:00:00Z&#39;</span><span class="w">
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="w"></span><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">created_at</span><span class="w"> </span><span class="k">DESC</span><span class="w">
</span></span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="w"></span><span class="k">LIMIT</span><span class="w"> </span><span class="mi">50</span><span class="p">;</span></span></span></code></pre></div><p>Index drift 是 migration 的常見風險。SQLite fixture 裡的 index 可以讓測試變快，但若 production schema 缺少同等 index，正式服務會在資料量成長後出現 latency spike；因此 index 要進入 schema diff audit。</p>
<h2 id="dialect-gap">Dialect Gap</h2>
<p>Dialect gap 的核心責任是把 SQLite 與 target database 的差異寫成 matrix。這份 matrix 應跟 repository adapter、migration plan 與 CI test suite 綁定。</p>
<table>
  <thead>
      <tr>
          <th>面向</th>
          <th>SQLite 審查點</th>
          <th>對照路由</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>ALTER TABLE</td>
          <td>支援範圍、table rebuild</td>
          <td><a href="/blog/backend/01-database/vendors/sqlite/schema-migration-versioning/" data-link-title="SQLite Schema Migration and Versioning" data-link-desc="SQLite schema migration、user_version、table rebuild、ALTER TABLE 限制、app release compatibility 與 migration evidence">Schema migration / versioning</a></td>
      </tr>
      <tr>
          <td>JSON</td>
          <td>function availability、index support</td>
          <td>production container test</td>
      </tr>
      <tr>
          <td>Generated column</td>
          <td>expression、storage、index</td>
          <td>migration dry run</td>
      </tr>
      <tr>
          <td>Window function</td>
          <td>target DB 支援與 planner</td>
          <td>query compatibility suite</td>
      </tr>
      <tr>
          <td>Extension</td>
          <td>FTS、vector、custom function</td>
          <td>vendor extension policy</td>
      </tr>
  </tbody>
</table>
<p>Dialect matrix 要以 query contract 為單位。每個 repository method 至少列出 SQL feature、SQLite behavior、production behavior、test layer 與 fallback strategy。</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">Contract: Search active documents by tenant and prefix
</span></span><span class="line"><span class="ln">2</span><span class="cl">SQLite: FTS5 virtual table in fixture
</span></span><span class="line"><span class="ln">3</span><span class="cl">PostgreSQL: tsvector + GIN index
</span></span><span class="line"><span class="ln">4</span><span class="cl">Risk: ranking / tokenizer / collation differ
</span></span><span class="line"><span class="ln">5</span><span class="cl">Evidence: golden result set + production container explain</span></span></code></pre></div><p>這種寫法讓測試負責驗證 domain contract，避免把兩個 SQL engine 的搜尋語意視為完全一致。</p>
<h2 id="test--migration-impact">Test / Migration Impact</h2>
<p>Test / migration impact 的核心責任是決定哪些東西可以用 SQLite 快速驗證，哪些東西要交給 production-like database。SQLite 很適合 repository contract、migration fixture、local development 與 file lifecycle drill；涉及 planner、extension、collation、locking、permission、role 與 HA 時，需要追加 target DB evidence。</p>
<table>
  <thead>
      <tr>
          <th>測試層</th>
          <th>SQLite 適合度</th>
          <th>必補 evidence</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Domain repository</td>
          <td>高</td>
          <td>invalid data、constraint、transaction case</td>
      </tr>
      <tr>
          <td>Migration syntax</td>
          <td>中</td>
          <td>target DB dry run</td>
      </tr>
      <tr>
          <td>Query performance</td>
          <td>中</td>
          <td>target DB explain + realistic data volume</td>
      </tr>
      <tr>
          <td>Permission / role</td>
          <td>低</td>
          <td>server DB integration test</td>
      </tr>
      <tr>
          <td>HA / failover</td>
          <td>低</td>
          <td>vendor-specific drill</td>
      </tr>
  </tbody>
</table>
<p>SQLite fixture 的價值在於快、穩、便宜。它應承擔「資料合約是否被 repository 保護」；production container 或 staging database 承擔「正式 engine 是否用同樣方式執行」。</p>
<h2 id="下一步路由">下一步路由</h2>
<p>SQL dialect and index limits 完成後，下一步要把 gap 接到實作層。測試設計讀 <a href="/blog/backend/01-database/vendors/sqlite/test-fixture-best-practice/" data-link-title="SQLite Test Fixture Best Practice" data-link-desc="SQLite 作為 test fixture、repository contract test、production dialect gap、seed data、fixture snapshot 與 CI evidence 的操作判準">Test Fixture Best Practice</a>；migration 實作讀 <a href="/blog/backend/01-database/vendors/sqlite/schema-migration-versioning/" data-link-title="SQLite Schema Migration and Versioning" data-link-desc="SQLite schema migration、user_version、table rebuild、ALTER TABLE 限制、app release compatibility 與 migration evidence">Schema migration / versioning</a>；要升級到 PostgreSQL，讀 <a href="/blog/backend/01-database/vendors/sqlite/migrate-to-postgresql/" data-link-title="SQLite to PostgreSQL Migration" data-link-desc="SQLite 升級到 PostgreSQL 的 driver、schema diff、data copy、dual run、cutover、rollback 與 cleanup">SQLite to PostgreSQL migration</a>。</p>
]]></content:encoded></item></channel></rss>