<?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>Googlesql on Tarragon</title><link>https://tarrragon.github.io/blog/tags/googlesql/</link><description>Recent content in Googlesql on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Tue, 02 Jun 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/googlesql/index.xml" rel="self" type="application/rss+xml"/><item><title>Spanner PostgreSQL dialect：PG-compatible interface vs GoogleSQL、相容子集邊界、何時選 PG dialect</title><link>https://tarrragon.github.io/blog/backend/01-database/vendors/spanner/postgresql-dialect/</link><pubDate>Tue, 02 Jun 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/backend/01-database/vendors/spanner/postgresql-dialect/</guid><description>&lt;blockquote>
&lt;p>本文是 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/vendors/spanner/" data-link-title="Google Cloud Spanner" data-link-desc="全球分散式 strong-consistency OLTP、TrueTime API、線性擴展到 10 億 req/sec">Cloud Spanner&lt;/a> overview 的 implementation-layer deep article、寫作參照 &lt;a href="https://tarrragon.github.io/blog/posts/vendor-%E6%B7%B1%E5%BA%A6%E6%8A%80%E8%A1%93%E6%96%87%E7%AB%A0%E6%96%B9%E6%B3%95%E8%AB%96%E7%9A%84%E6%BC%94%E5%8C%96%E7%B4%80%E9%8C%84%E5%90%8C-vendor-%E7%B3%BB%E5%88%97%E7%9A%84%E9%96%8B%E5%A0%B4%E8%BC%AA%E6%9B%BF%E9%A9%97%E8%AD%89/" data-link-title="Vendor 深度技術文章方法論的演化紀錄：同 vendor 系列的開場輪替驗證" data-link-desc="vendor overview 飽和後要寫單一功能深度文章、需要選題與結構依據時回來。這套方法論的驗證來源與 cadence variant 在高風險場景（同 vendor sub-tool 系列）的實證。">vendor deep article methodology&lt;/a>。Overview 已說明 Spanner 在全球 OLTP 譜系的定位、本文聚焦 &lt;em>PostgreSQL dialect&lt;/em> — Spanner 為降低 PostgreSQL 生態遷入門檻提供的 PG-compatible 介面、跟原生 GoogleSQL dialect 的差異與邊界。&lt;/p>&lt;/blockquote>
&lt;hr>
&lt;h2 id="核心定位pg-dialect-是介面層不是換引擎">核心定位：PG dialect 是介面層、不是換引擎&lt;/h2>
&lt;p>Spanner PostgreSQL dialect 的責任是讓 PostgreSQL 生態的語法、型別系統與 wire protocol 能跑在 Spanner 的分散式引擎之上、降低團隊既有 PostgreSQL 知識與工具的遷移成本。它改變的是 &lt;em>query 語言與 client 介面&lt;/em>、不改變底層的 split-based 儲存、Paxos 複製、TrueTime commit 與 external consistency — 這些 Spanner 的分散式語意在兩種 dialect 下完全一致。&lt;/p>
&lt;p>把這條定位放在最前面、是因為最常見的誤解是「選了 PG dialect 就等於用 PostgreSQL」。實際上 PG dialect 是「用 PostgreSQL 的方言跟 Spanner 對話」、不是「在 Spanner 裡裝一個 PostgreSQL」。team 帶著 PostgreSQL 的 &lt;code>psql&lt;/code>、libpq driver、PG 語法進來、但要寫的仍是 Spanner — 一個沒有 single-primary、沒有本地 sequence、partition 由系統管理的分散式 SQL。&lt;/p>
&lt;p>GoogleSQL dialect 是 Spanner 原生方言、語法接近 BigQuery 的 GoogleSQL、攜帶 Spanner-specific 的 &lt;code>INTERLEAVE IN PARENT&lt;/code>、array 型別、&lt;code>PENDING_COMMIT_TIMESTAMP&lt;/code> 等原生概念。兩種 dialect 是 instance / database 建立時就固定的選擇、之後不可變更。&lt;/p>
&lt;h2 id="問題情境postgresql-團隊想遷入-spanner但不想重寫所有-sql">問題情境：PostgreSQL 團隊想遷入 Spanner、但不想重寫所有 SQL&lt;/h2>
&lt;p>PostgreSQL dialect 的存在價值、在「既有 PostgreSQL 應用要拿到 Spanner 的全球強一致與線性擴展、但團隊的 SQL、ORM、tooling、人員技能都綁在 PostgreSQL」這個壓力下浮現。讀者徵兆：團隊評估 Spanner 時發現 GoogleSQL 語法陌生、ORM（如 SQLAlchemy、Hibernate）的 PostgreSQL dialect 已深度整合、DBA 熟悉 &lt;code>psql&lt;/code> 與 PG 工具鏈、不想為了遷移把整套 SQL 知識重學。&lt;/p>
&lt;p>真實壓力場景：一個建在 Cloud SQL for PostgreSQL 上的金融 ledger、撞到 single-primary 寫入上限、需要遷到 Spanner 拿跨 region 強一致;團隊有數萬行 PostgreSQL SQL、用 libpq-based driver、若 target 是 GoogleSQL、application 層改動範圍會大到讓遷移 ROI 不成立。PG dialect 把這個改動範圍縮小到「相容子集邊界內的 SQL 多數可沿用、邊界外的功能需要改寫」。&lt;/p>
&lt;p>Case anchor：本主題在 case 庫覆蓋稀薄。9.C10 是 Google internal dogfood case、未展開 dialect 選擇細節、且不是 customer-facing 參考。本文 dialect 機制、相容子集邊界、wire protocol 行為均以 GCP vendor 規格 + 通用遷移工程展開、case 僅作「為什麼 PostgreSQL 團隊要遷 Spanner」的壓力 anchor。延伸的遷移流程在 sibling &lt;a href="../migrate-from-cloud-sql-pg/">migrate-from-cloud-sql-pg&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<blockquote>
<p>本文是 <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">Cloud Spanner</a> overview 的 implementation-layer deep article、寫作參照 <a href="/blog/posts/vendor-%E6%B7%B1%E5%BA%A6%E6%8A%80%E8%A1%93%E6%96%87%E7%AB%A0%E6%96%B9%E6%B3%95%E8%AB%96%E7%9A%84%E6%BC%94%E5%8C%96%E7%B4%80%E9%8C%84%E5%90%8C-vendor-%E7%B3%BB%E5%88%97%E7%9A%84%E9%96%8B%E5%A0%B4%E8%BC%AA%E6%9B%BF%E9%A9%97%E8%AD%89/" data-link-title="Vendor 深度技術文章方法論的演化紀錄：同 vendor 系列的開場輪替驗證" data-link-desc="vendor overview 飽和後要寫單一功能深度文章、需要選題與結構依據時回來。這套方法論的驗證來源與 cadence variant 在高風險場景（同 vendor sub-tool 系列）的實證。">vendor deep article methodology</a>。Overview 已說明 Spanner 在全球 OLTP 譜系的定位、本文聚焦 <em>PostgreSQL dialect</em> — Spanner 為降低 PostgreSQL 生態遷入門檻提供的 PG-compatible 介面、跟原生 GoogleSQL dialect 的差異與邊界。</p></blockquote>
<hr>
<h2 id="核心定位pg-dialect-是介面層不是換引擎">核心定位：PG dialect 是介面層、不是換引擎</h2>
<p>Spanner PostgreSQL dialect 的責任是讓 PostgreSQL 生態的語法、型別系統與 wire protocol 能跑在 Spanner 的分散式引擎之上、降低團隊既有 PostgreSQL 知識與工具的遷移成本。它改變的是 <em>query 語言與 client 介面</em>、不改變底層的 split-based 儲存、Paxos 複製、TrueTime commit 與 external consistency — 這些 Spanner 的分散式語意在兩種 dialect 下完全一致。</p>
<p>把這條定位放在最前面、是因為最常見的誤解是「選了 PG dialect 就等於用 PostgreSQL」。實際上 PG dialect 是「用 PostgreSQL 的方言跟 Spanner 對話」、不是「在 Spanner 裡裝一個 PostgreSQL」。team 帶著 PostgreSQL 的 <code>psql</code>、libpq driver、PG 語法進來、但要寫的仍是 Spanner — 一個沒有 single-primary、沒有本地 sequence、partition 由系統管理的分散式 SQL。</p>
<p>GoogleSQL dialect 是 Spanner 原生方言、語法接近 BigQuery 的 GoogleSQL、攜帶 Spanner-specific 的 <code>INTERLEAVE IN PARENT</code>、array 型別、<code>PENDING_COMMIT_TIMESTAMP</code> 等原生概念。兩種 dialect 是 instance / database 建立時就固定的選擇、之後不可變更。</p>
<h2 id="問題情境postgresql-團隊想遷入-spanner但不想重寫所有-sql">問題情境：PostgreSQL 團隊想遷入 Spanner、但不想重寫所有 SQL</h2>
<p>PostgreSQL dialect 的存在價值、在「既有 PostgreSQL 應用要拿到 Spanner 的全球強一致與線性擴展、但團隊的 SQL、ORM、tooling、人員技能都綁在 PostgreSQL」這個壓力下浮現。讀者徵兆：團隊評估 Spanner 時發現 GoogleSQL 語法陌生、ORM（如 SQLAlchemy、Hibernate）的 PostgreSQL dialect 已深度整合、DBA 熟悉 <code>psql</code> 與 PG 工具鏈、不想為了遷移把整套 SQL 知識重學。</p>
<p>真實壓力場景：一個建在 Cloud SQL for PostgreSQL 上的金融 ledger、撞到 single-primary 寫入上限、需要遷到 Spanner 拿跨 region 強一致;團隊有數萬行 PostgreSQL SQL、用 libpq-based driver、若 target 是 GoogleSQL、application 層改動範圍會大到讓遷移 ROI 不成立。PG dialect 把這個改動範圍縮小到「相容子集邊界內的 SQL 多數可沿用、邊界外的功能需要改寫」。</p>
<p>Case anchor：本主題在 case 庫覆蓋稀薄。9.C10 是 Google internal dogfood case、未展開 dialect 選擇細節、且不是 customer-facing 參考。本文 dialect 機制、相容子集邊界、wire protocol 行為均以 GCP vendor 規格 + 通用遷移工程展開、case 僅作「為什麼 PostgreSQL 團隊要遷 Spanner」的壓力 anchor。延伸的遷移流程在 sibling <a href="../migrate-from-cloud-sql-pg/">migrate-from-cloud-sql-pg</a>。</p>
<h2 id="相容子集邊界哪些-postgresql-功能不在範圍內">相容子集邊界：哪些 PostgreSQL 功能不在範圍內</h2>
<p>PG dialect 提供 PostgreSQL 語法、型別、function 與 wire protocol 的 <em>一個子集</em>、邊界由「Spanner 分散式引擎能不能支援該語意」決定、不是 PostgreSQL 有什麼就有什麼。理解邊界的關鍵是分清三類：相容沿用的、Spanner 用不同方式達成的、根本不存在的。</p>
<h3 id="相容沿用多數標準-sql">相容沿用：多數標準 SQL</h3>
<p>標準 DML（<code>SELECT</code> / <code>INSERT</code> / <code>UPDATE</code> / <code>DELETE</code>）、多數 JOIN、聚合、CTE、常見型別（<code>bigint</code> / <code>text</code> / <code>numeric</code> / <code>timestamptz</code> / <code>bool</code> / <code>jsonb</code>）、prepared statement、parameterized query 在 PG dialect 下沿用 PostgreSQL 語法。libpq-based driver 與 <code>psql</code> 可直接連、wire protocol 相容讓 PostgreSQL client 工具多數可用。</p>
<h3 id="spanner-用不同方式達成sequenceschema-changepk">Spanner 用不同方式達成：sequence、schema change、PK</h3>
<p>PostgreSQL 的 <code>SERIAL</code> / <code>bigserial</code> 在分散式系統下會製造熱點（單調遞增的 PK 集中寫到同一個 split）、Spanner 引導用 UUID 或 bit-reversed sequence 分散寫入。schema change 在 PG dialect 下仍是 Spanner 的 long-running operation、不是 PostgreSQL 的同步 DDL — DDL 語法是 PG 風格、但執行語意是 Spanner 的（見 <a href="../schema-migration-interleaved-tables/">schema-migration-interleaved-tables</a>）。primary key 設計直接決定資料分布、跟 PostgreSQL 把 PK 當邏輯約束的心智不同。</p>
<h3 id="根本不存在postgresql-重度功能">根本不存在：PostgreSQL 重度功能</h3>
<p>部分 PostgreSQL 的進階功能不在 PG dialect 範圍內、團隊若依賴它們、遷移要先找替代路徑。常見的缺口包含：自訂 extension（PostGIS、pgvector 等需另尋路徑）、stored procedure / 觸發器生態、部分 window function 與進階型別、<code>LISTEN</code> / <code>NOTIFY</code>、以及 PostgreSQL 特有的 lock 與 vacuum 心智。這些缺口不是 bug、是「Spanner 不是 PostgreSQL」的直接後果。</p>
<blockquote>
<p><strong>Scope warning</strong>：PG dialect 的具體支援清單（支援哪些型別、function、語法）逐版本擴充、本文列舉的相容子集邊界屬 GCP 規格、實作前必須 cross-verify <a href="https://cloud.google.com/spanner/docs/postgresql-interface">Spanner PostgreSQL dialect 官方文件</a> 的當前支援矩陣、不能依本文清單當最終依據。</p></blockquote>
<h2 id="操作流程建立-pg-dialect-database連線驗證相容性">操作流程：建立 PG dialect database、連線、驗證相容性</h2>
<h3 id="step-1建立-pg-dialect-database">Step 1：建立 PG dialect database</h3>
<p>dialect 在建立 database 時指定、不可事後變更。建立時明確選 PostgreSQL dialect：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl">gcloud spanner databases create my-pg-db <span class="se">\
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="se"></span>  --instance<span class="o">=</span>my-instance <span class="se">\
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="se"></span>  --database-dialect<span class="o">=</span>POSTGRESQL</span></span></code></pre></div><p>驗證：查 database metadata 確認 dialect 是 POSTGRESQL。這步若選錯、唯一修法是建新 database 重遷、沒有 in-place 轉換 — 這是本文反覆強調的不可逆決策。</p>
<h3 id="step-2用-postgresql-client-連線">Step 2：用 PostgreSQL client 連線</h3>
<p>PG dialect 接受 PostgreSQL wire protocol、可用 <code>psql</code> 或 libpq-based driver 連線（透過 PGAdapter proxy 或支援的 client library）。</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 透過 PGAdapter 用 psql 連線</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">psql -h localhost -p <span class="m">5432</span> -d my-pg-db</span></span></code></pre></div><p>驗證：跑一個簡單 <code>SELECT 1</code>、確認 wire protocol 通;再跑一個帶 PG 型別的 query、確認型別映射正確。</p>
<h3 id="step-3相容性-audit--跑既有-sql-測邊界">Step 3：相容性 audit — 跑既有 SQL 測邊界</h3>
<p>把既有 PostgreSQL application 的 SQL 集合在 PG dialect database 上跑一遍、標出哪些直接通過、哪些報不支援。這步是遷移評估的核心 evidence — 它把「相容子集邊界」從文件文字變成「我的 SQL 有多少落在邊界內」的具體數字。</p>
<p>驗證點：統計通過率、把不通過的 SQL 分類（用 different way 達成 vs 根本不支援）、對「根本不支援」的部分評估改寫成本。若改寫成本過高、這是 PG dialect 路徑的 no-go 訊號。</p>
<h3 id="step-4rollback-boundary">Step 4：rollback boundary</h3>
<p>dialect 不可變更、所以 rollback boundary 在「遷移評估階段」、不在「上線後」。決策樹是：相容性 audit 通過率高 + 改寫成本可控 → 選 PG dialect;通過率低 + 大量 Spanner-only 優化需求 → 直接學 GoogleSQL。一旦 database 建好、dialect 就鎖定、rollback 等於重建 database 重遷。</p>
<h2 id="失敗模式把-pg-dialect-當完整-postgresql與-dialect-鎖定">失敗模式：把 PG dialect 當完整 PostgreSQL、與 dialect 鎖定</h2>
<h3 id="把-pg-dialect-當完整-postgresql-用">把 PG dialect 當完整 PostgreSQL 用</h3>
<p>團隊假設「PG dialect = PostgreSQL」、直接把依賴 extension、stored procedure、<code>SERIAL</code> PK 的應用搬過來、上線後發現 extension 不存在、<code>SERIAL</code> 製造熱點、p99 write latency 因 PK 集中而退化。徵兆是特定 PK range 的 split CPU 飆高、其餘 split 閒置。修法是審查 PK 設計改用分散式友善的 key（UUID / bit-reversed sequence）、把 extension 依賴改成 application 層或外部服務。這個失敗的根因是心智模型錯位、不是 bug。</p>
<h3 id="dialect-鎖定後才發現需要另一種-dialect">Dialect 鎖定後才發現需要另一種 dialect</h3>
<p>dialect 是 database 建立時的不可逆選擇、團隊選了 PG dialect、後續發現需要 GoogleSQL 才有的某個原生能力（或反之）、唯一路徑是建新 database 重遷全部資料。這個失敗的代價遠高於一般 config 錯誤 — 它不是改一行設定、是一次完整的資料遷移 + application cutover + 驗證 + rollback 規劃。回退路徑是把它當成一次 Type E migration（見 <a href="../migrate-from-cloud-sql-pg/">migrate-from-cloud-sql-pg</a> 的 paradigm shift 結構）、不能當成 hotfix。預防勝於回退：在 Step 3 的相容性 audit 階段就要把「未來可能需要哪種 dialect 的能力」一起評估、而不是只看當下的 SQL 通過率。</p>
<h3 id="以為換了-pg-dialect-就不用懂-spanner-分散式語意">以為換了 PG dialect 就不用懂 Spanner 分散式語意</h3>
<p>PG dialect 降低語法門檻、但 Spanner 的 split、hot range、interleaved table、commit wait、cross-region quorum 在 PG dialect 下完全一樣。團隊若以為「用 PG 語法就能當 PostgreSQL 維運」、會在 hot partition、跨 region latency、schema change 是 long-running operation 這些 Spanner-specific 議題上踩雷。修法是不論選哪種 dialect、Spanner 的分散式機制都要懂 — dialect 是介面、不是引擎。</p>
<h2 id="容量與觀測dialect-不改變容量模型">容量與觀測：dialect 不改變容量模型</h2>
<p>PG dialect 跟 GoogleSQL 共用同一個 Spanner 引擎、容量模型、metric、sizing 完全一致 — 選 dialect 不影響容量規劃。核心觀測仍是 Spanner instance 的 CPU、split distribution、commit latency、跟原生 GoogleSQL database 沒有差別。</p>
<p>需要額外觀測的是 PG dialect 特有的接入層：若透過 PGAdapter proxy 連線、proxy 本身是一跳、要監控 proxy 的延遲與可用性、避免它成為單點。</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">Spanner CPU utilization        → 跟 dialect 無關、共用引擎指標
</span></span><span class="line"><span class="ln">2</span><span class="cl">split / hot range distribution → PK 設計（含 SERIAL 熱點）直接反映在這
</span></span><span class="line"><span class="ln">3</span><span class="cl">PGAdapter proxy latency        → PG dialect 接入層的額外一跳（若使用）
</span></span><span class="line"><span class="ln">4</span><span class="cl">commit_latencies               → external consistency 的 commit wait、兩 dialect 一致</span></span></code></pre></div><p>容量規劃路由回 <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> — sizing 邏輯跟 dialect 無關。觀測接 <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>。</p>
<blockquote>
<p><strong>Scope warning</strong>：PGAdapter 的部署模型（sidecar / standalone proxy）與其延遲特性屬 GCP 規格、cross-verify 官方文件、非 9.C10 case 揭露。</p></blockquote>
<h2 id="邊界與整合何時選-pg-dialect何時選-googlesql">邊界與整合：何時選 PG dialect、何時選 GoogleSQL</h2>
<h3 id="選-pg-dialect-的條件">選 PG dialect 的條件</h3>
<p>既有 PostgreSQL 應用要遷入、SQL / ORM / tooling 深度綁 PostgreSQL、相容性 audit 通過率高、且不需要大量 Spanner-only 原生優化 — 這是 PG dialect 的適用條件。它讓遷移的 application 層改動最小化、保留團隊既有 PostgreSQL 技能。</p>
<h3 id="選-googlesql-的條件">選 GoogleSQL 的條件</h3>
<p>全新專案、團隊願意學 Spanner 原生方言、需要深度用 interleaved table、array 型別、Spanner-specific 優化、或想跟 BigQuery 的 GoogleSQL 生態對齊 — 選 GoogleSQL。它是 Spanner 的一等公民方言、新功能通常先在 GoogleSQL 落地。</p>
<h3 id="何時兩者都不選不該升-spanner">何時兩者都不選（不該升 Spanner）</h3>
<p>若 workload 是單 region、不需要全球強一致、PostgreSQL dialect 的相容性吸引力不該成為升 Spanner 的理由 — Cloud SQL for PostgreSQL 是真正的 PostgreSQL、相容性 100%、成本更低。Anti-recommendation 的判準是：PG dialect 的價值在「已經要遷 Spanner、想降低遷移成本」、不在「因為它像 PostgreSQL 所以選 Spanner」。把 dialect 相容性當升級理由是把次要因素當主要決策。</p>
<h3 id="sibling-deep-articles-路由">Sibling deep articles 路由</h3>
<ul>
<li><a href="../migrate-from-cloud-sql-pg/">migrate-from-cloud-sql-pg</a>：PG dialect 是 Cloud SQL → Spanner 遷移降低改動成本的關鍵、本文的相容子集邊界對應該 playbook 的 diff audit</li>
<li><a href="../schema-migration-interleaved-tables/">schema-migration-interleaved-tables</a>：PG dialect 下 DDL 仍是 Spanner long-running operation、interleaved table 在兩 dialect 都要懂</li>
<li><a href="../consistency-models-comparison/">consistency-models-comparison</a>：兩 dialect 共用 external consistency、dialect 不改變一致性語意</li>
</ul>
<h3 id="跟-knowledge-card-的互引">跟 knowledge card 的互引</h3>
<ul>
<li><a href="/blog/backend/knowledge-cards/distributed-sql/" data-link-title="Distributed SQL" data-link-desc="把 SQL 與交易語意延伸到多節點與多區域的資料庫形態">distributed-sql</a> — PG dialect 是 distributed SQL 上的相容介面、不改變 distributed SQL 的本質</li>
<li><a href="/blog/backend/knowledge-cards/isolation-level/" data-link-title="Isolation Level" data-link-desc="說明資料庫交易隔離級別如何影響並發讀寫結果">isolation-level</a> — 兩 dialect 共用 Spanner 的 external consistency、isolation 語意一致</li>
</ul>
<h3 id="跟其他-vendor-的對照路由">跟其他 vendor 的對照路由</h3>
<ul>
<li><a href="/blog/backend/01-database/vendors/cockroachdb/" data-link-title="CockroachDB" data-link-desc="分散式 SQL、PostgreSQL 相容、跨區強一致、Spanner 的開源 / 跨雲替代">CockroachDB vendor</a>：CockroachDB 走 PostgreSQL wire 相容是其核心策略、跟 Spanner PG dialect 是兩種「PostgreSQL 相容的 distributed SQL」路線、相容程度與邊界不同</li>
</ul>
]]></content:encoded></item></channel></rss>