<?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>Reading-Path on Tarragon</title><link>https://tarrragon.github.io/blog/tags/reading-path/</link><description>Recent content in Reading-Path on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Thu, 24 Sep 2026 00:00:00 +0800</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/reading-path/index.xml" rel="self" type="application/rss+xml"/><item><title>Backend 教材的閱讀路線：教材的分層、依讀者目的排的模組順序與貫穿各模組的 checkout 範例流程</title><link>https://tarrragon.github.io/blog/backend/reading-paths/</link><pubDate>Thu, 24 Sep 2026 00:00:00 +0800</pubDate><guid>https://tarrragon.github.io/blog/backend/reading-paths/</guid><description>&lt;p>這篇整理 Backend 教材各模組之間的閱讀順序：教材分成哪幾層、依讀者手上的目的各走哪一條路線，以及一條把各模組串起來的 checkout 流程。範圍是模組之間的順序，每個模組內部的章節順序在該模組的列表頁。&lt;/p>
&lt;h2 id="backend-教材的分層分類語言服務路徑與具體工具各自回答的問題">Backend 教材的分層：分類語言、服務路徑與具體工具各自回答的問題&lt;/h2>
&lt;p>Backend 教材把後端服務能力分成三層來教。&lt;strong>分類語言&lt;/strong>讓讀者知道資料、快取、事件、觀測、部署、驗證、資安、事故與容量各自承擔什麼責任；&lt;strong>服務路徑&lt;/strong>用一條具體業務流程，演練這些能力之間怎麼交接；&lt;strong>具體工具&lt;/strong>討論 PostgreSQL、Redis、Kafka、Kubernetes、PagerDuty、k6 這些服務落到真實操作時的能力、成本與遷移。&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>分類語言&lt;/td>
 &lt;td>這是哪一類問題&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">後端服務選型模組&lt;/a>與&lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/" data-link-title="Knowledge Cards" data-link-desc="用原子化卡片整理後端服務選型前需要理解的 domain knowhow">前置知識卡片&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>服務路徑&lt;/td>
 &lt;td>一個服務流程怎麼把多個能力接起來&lt;/td>
 &lt;td>資料庫到容量規劃各模組的主章，加上本篇下方的 checkout 流程&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>具體工具&lt;/td>
 &lt;td>要選哪個工具、怎麼遷移&lt;/td>
 &lt;td>各模組的 &lt;code>vendors/&lt;/code> 子目錄；案例庫在&lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/" data-link-title="模組七：資安與資料保護" data-link-desc="以問題驅動方式擴充資安知識網：先定義服務環節問題，再以案例作為觸發式參考">資安與資料保護模組&lt;/a>與&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置在延遲目標內處理得了多少請求、要加多少機器』變成可量化、可驗證、可改進的工程流程">效能工程與容量規劃模組&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>三層的順序是理解的順序：分類語言先建立，服務路徑才有詞彙可以描述交接，具體工具的比較才有一個分類責任可以回扣。已經懂分類、只想比較工具的讀者可以直接從具體工具那一層進來，遇到工具頁回扣分類責任的段落時，再回到分類語言那一層補那一類的定義。&lt;/p>
&lt;h2 id="依讀者目的排的閱讀路線從沒部署過服務到規模成長">依讀者目的排的閱讀路線：從沒部署過服務到規模成長&lt;/h2>
&lt;p>下表每一列是一種讀者目的。建議順序欄的箭頭是閱讀先後，讀完那一欄說的是走完之後能做出的判斷。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>路線&lt;/th>
 &lt;th>適合讀者&lt;/th>
 &lt;th>建議順序&lt;/th>
 &lt;th>讀完能做什麼&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>沒部署過服務&lt;/td>
 &lt;td>會寫程式、但沒把服務上線過&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/devops/going-live/" data-link-title="服務上線：部署、主機形態、域名與 HTTPS、十二要素、自架或託管、備份與還原" data-link-desc="第一次把在本機執行的服務放上網際網路，要決定部署方式、主機形態、域名與 HTTPS、照十二要素分離設定與程式碼、資料庫自架或託管，以及備份還原怎麼做時讀">服務上線：部署、主機形態、域名與 HTTPS、十二要素、自架或託管、備份與還原&lt;/a>（部署是什麼 → 主機形態 → 域名與 HTTPS → 自架或託管 → 備份）→ 回到&lt;a href="https://tarrragon.github.io/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">後端服務選型模組&lt;/a>做選型&lt;/td>
 &lt;td>能把一個服務從本機推上線，並知道接著補哪一塊&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>系統心智模型&lt;/td>
 &lt;td>想理解後端服務怎麼分工&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/00-service-selection/delivery-mode-selection/" data-link-title="0.21 交付形態選型：從全託管到自建的光譜與邊界" data-link-desc="在進入資料庫、快取與部署選型之前、先判斷服務該用託管平台（Wix / Shopify / Google Sites）、辦公生態自動化（Apps Script）、BaaS（Firebase）、半託管 CMS（WordPress）還是自建、並為日後遷往自建保留可遷出路徑">0.21 交付形態選型：從全託管到自建的光譜與邊界&lt;/a> → &lt;a href="https://tarrragon.github.io/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">後端服務選型模組&lt;/a> → &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/" data-link-title="Knowledge Cards" data-link-desc="用原子化卡片整理後端服務選型前需要理解的 domain knowhow">前置知識卡片&lt;/a> → &lt;a href="https://tarrragon.github.io/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">資料庫&lt;/a>、&lt;a href="https://tarrragon.github.io/blog/backend/02-cache-redis/" data-link-title="模組二：快取與 Redis" data-link-desc="整理快取策略、Redis 資料型別與分散式狀態輔助能力">快取&lt;/a>與&lt;a href="https://tarrragon.github.io/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">訊息佇列&lt;/a>三個模組的共同觀念 → &lt;a href="https://tarrragon.github.io/blog/backend/10-system-evolution/service-decomposition-boundaries/" data-link-title="10.1 服務拆分與邊界判讀" data-link-desc="整理 monolith vs microservice 取捨、服務邊界判讀訊號、拆分時機與回退路徑">10.1 服務拆分與邊界判讀&lt;/a>、&lt;a href="https://tarrragon.github.io/blog/backend/00-service-selection/cloud-vendor-capability-mapping/" data-link-title="0.19 雲端服務對照地圖（AWS / GCP / Azure）" data-link-desc="把後端能力分類對照到 AWS / GCP / Azure 的具體服務名稱、保留跨雲遷移與選型差異的判讀重點">0.19 雲端服務對照地圖（AWS / GCP / Azure）&lt;/a>、&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/scaling-axes/" data-link-title="9.13 擴展軸與 Stateless 前提" data-link-desc="整理垂直 / 水平擴展取捨、stateless vs stateful 前提、auto scaling 操作模型與兩種擴展的 hidden cost">9.13 擴展軸與 Stateless 前提&lt;/a>&lt;/td>
 &lt;td>能把需求分類成正式狀態、暫存副本、非同步交接、觀測、部署或可靠性問題，並用服務邊界與擴展軸描述系統往哪裡走&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>API 到資料流&lt;/td>
 &lt;td>想設計 API 的對外契約，以及它背後的資料與事件流程&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/11-api-design/" data-link-title="模組十一：API 設計與對外契約" data-link-desc="整理 API 風格選型、資源建模、錯誤模型、版本與相容策略、冪等與對外流量語意的設計判斷標準；主流做法與各流派的深度論證分層收錄">API 設計與對外契約模組&lt;/a> → &lt;a href="https://tarrragon.github.io/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">資料庫與持久化模組&lt;/a> → &lt;a href="https://tarrragon.github.io/blog/backend/01-database/query-anti-patterns/" data-link-title="1.13 應用層查詢反模式與 Query 預算" data-link-desc="整理 N&amp;#43;1、select *、缺索引、ORM lazy load、long transaction 等查詢反模式與每請求的 query 預算判讀">1.13 應用層查詢反模式與 Query 預算&lt;/a> → &lt;a href="https://tarrragon.github.io/blog/backend/02-cache-redis/" data-link-title="模組二：快取與 Redis" data-link-desc="整理快取策略、Redis 資料型別與分散式狀態輔助能力">快取與 Redis 模組&lt;/a> → &lt;a href="https://tarrragon.github.io/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">訊息佇列與事件傳遞模組&lt;/a> → &lt;a href="https://tarrragon.github.io/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">可觀測性平台模組&lt;/a>的證據整理 → &lt;a href="https://tarrragon.github.io/blog/backend/01-database/production-slow-log-loop/" data-link-title="1.14 Production Slow Log Closed Loop" data-link-desc="把 production slow log 從『偶爾看一下』變成『定期審視 &amp;#43; PR review 整合 &amp;#43; regression 偵測』的閉環、補 1.13 反模式清單後的操作層">1.14 Production Slow Log Closed Loop&lt;/a>&lt;/td>
 &lt;td>能說明一次 checkout 怎麼跨資料庫、快取、佇列與證據整理，並在上線前用 query 預算與 slow log 攔下查詢反模式&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>Production 操作&lt;/td>
 &lt;td>想學上線、觀測、驗證與事故的閉環&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">可觀測性平台模組&lt;/a> → &lt;a href="https://tarrragon.github.io/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">部署平台與網路入口模組&lt;/a>（含 &lt;a href="https://tarrragon.github.io/blog/backend/05-deployment-platform/edge-cdn-static-distribution/" data-link-title="5.9 邊緣分發與靜態資源（CDN / Origin Protection）" data-link-desc="整理 CDN 與 edge cache 在部署平台中的責任邊界、origin protection、purge 與 invalidation 策略">5.9 邊緣分發與靜態資源（CDN / Origin Protection）&lt;/a>）→ &lt;a href="https://tarrragon.github.io/blog/backend/06-reliability/" data-link-title="模組六：可靠性驗證流程" data-link-desc="用 SRE 領域詞彙建問題節點、以服務級案例庫累積驗證脈絡，先建概念與案例庫再進實作交接">可靠性驗證流程模組&lt;/a> → &lt;a href="https://tarrragon.github.io/blog/backend/08-incident-response/" data-link-title="模組八：事故處理與復盤" data-link-desc="用 IR 領域詞彙建問題節點、以服務級案例庫累積事故脈絡，先建概念與案例庫再進實作交接">事故處理與復盤模組&lt;/a>&lt;/td>
 &lt;td>能把 release、alert、gate、邊緣層的 origin protection、事故決策紀錄與事後回寫串成操作閉環&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>資安與資料保護&lt;/td>
 &lt;td>想理解權限、秘密、資料、偵測與回應&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/07-security-data-protection/" data-link-title="模組七：資安與資料保護" data-link-desc="以問題驅動方式擴充資安知識網：先定義服務環節問題，再以案例作為觸發式參考">資安與資料保護模組&lt;/a> → &lt;a href="https://tarrragon.github.io/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">可觀測性平台模組&lt;/a>的稽核證據 → &lt;a href="https://tarrragon.github.io/blog/backend/06-reliability/" data-link-title="模組六：可靠性驗證流程" data-link-desc="用 SRE 領域詞彙建問題節點、以服務級案例庫累積驗證脈絡，先建概念與案例庫再進實作交接">可靠性驗證流程模組&lt;/a>的控制驗證 → &lt;a href="https://tarrragon.github.io/blog/backend/08-incident-response/security-vs-operational-incident/" data-link-title="8.17 Security Incident vs Operational Incident 分流" data-link-desc="把資安事故跟可用性事故的 IR 流程分支點明確化">8.17 Security Incident vs Operational Incident 分流&lt;/a> → &lt;a href="https://tarrragon.github.io/blog/backend/08-incident-response/compromised-build-host-eradication/" data-link-title="8.25 建置主機被入侵後的根除與重建：清查範圍、重建來源、存取憑證撤銷與輪替的先後、多波攻擊的監看、宣告已掌握狀況的條件與承諾賠償的時機" data-link-desc="一台持有程式碼與正式環境存取權的主機（以 CI 建置主機為例）被入侵之後，清查範圍怎麼從它手上的存取憑證、讀寫得到的資料與網路連得到的系統推出來，重建時哪些來源仍可信，存取憑證撤銷與發新的先後，攻擊者回來時的監看與它的結束條件，以及對外宣告已掌握狀況、通報與承諾賠償各要先具備哪些事實">8.25 建置主機被入侵後的根除與重建&lt;/a>&lt;/td>
 &lt;td>能從身份、資料、入口、秘密與稽核證據判讀控制面&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>工具比較與遷移&lt;/td>
 &lt;td>已懂分類、要比較工具或規劃遷移&lt;/td>
 &lt;td>對應模組的主章 → &lt;a href="https://tarrragon.github.io/blog/backend/00-service-selection/cloud-vendor-capability-mapping/" data-link-title="0.19 雲端服務對照地圖（AWS / GCP / Azure）" data-link-desc="把後端能力分類對照到 AWS / GCP / Azure 的具體服務名稱、保留跨雲遷移與選型差異的判讀重點">0.19 雲端服務對照地圖（AWS / GCP / Azure）&lt;/a> → 該模組的 &lt;code>vendors/&lt;/code> → 遷移操作手冊（含 &lt;a href="https://tarrragon.github.io/blog/backend/10-system-evolution/service-decomposition-execution-runbook/" data-link-title="10.2 服務拆分執行 Runbook（Strangler Fig / 雙寫期 / 切流 / 回退）" data-link-desc="10.1 決定該拆之後、實際怎麼動手拆 — Strangler Fig pattern、雙寫期管理、切流策略、回退條件設計">10.2 服務拆分執行 Runbook（Strangler Fig / 雙寫期 / 切流 / 回退）&lt;/a>、&lt;a href="https://tarrragon.github.io/blog/backend/10-system-evolution/managed-platform-exit/" data-link-title="10.3 託管形態遷出：資產線盤點與並行期執行" data-link-desc="0.21 升級自建 tripwire 觸發後的執行劇本 — 把遷出拆成資料、身分、流量、整合各自的可攜性與斷點、設計舊平台與新系統的並行期與回切窗口、用部分遷出作為中繼形態">10.3 託管形態遷出：資產線盤點與並行期執行&lt;/a>）→ 案例（含 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/production-slow-log-loop/" data-link-title="1.14 Production Slow Log Closed Loop" data-link-desc="把 production slow log 從『偶爾看一下』變成『定期審視 &amp;#43; PR review 整合 &amp;#43; regression 偵測』的閉環、補 1.13 反模式清單後的操作層">1.14 Production Slow Log Closed Loop&lt;/a>、&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/connection-pool-amplification/" data-link-title="9.14 連線池放大解法（PgBouncer / RDS Proxy / ProxySQL）" data-link-desc="水平擴展應用層時 DB 連線池放大問題的具體解法、connection pooler 三大選項對比、解 9.13 提出但未深入的隱性成本">9.14 連線池放大解法（PgBouncer / RDS Proxy / ProxySQL）&lt;/a>）&lt;/td>
 &lt;td>能先判斷分類責任，再對照雲端能力、比較具體服務、操作成本與遷移風險&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>規模成長&lt;/td>
 &lt;td>已經做出能跑的服務，要學讓它撐住&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/scale-growth-walls/" data-link-title="服務規模成長的閱讀路線：架構撞到限制的訊號、要補的能力與對應章節" data-link-desc="一個服務從一臺機器演進到多區域多服務的過程裡架構撞到限制的訊號、每個訊號對應要補的能力與章節，以及入門影片常用的比喻各對應到哪一篇">服務規模成長的閱讀路線：架構撞到限制的訊號、要補的能力與對應章節&lt;/a>，那一篇有完整的閱讀順序與各訊號對應的章節&lt;/td>
 &lt;td>能描述一個服務從一臺機器演進到多區域多服務的過程、每一段會撞上什麼、要先補哪一塊能力&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>各條路線共用同一組後端詞彙，所以可以只走一條，也可以從系統心智模型那一條開始，再依工作需求轉進其他路線。表格裡帶編號的連結是單篇文章，只寫模組名的連結是整個模組。&lt;/p></description><content:encoded><![CDATA[<p>這篇整理 Backend 教材各模組之間的閱讀順序：教材分成哪幾層、依讀者手上的目的各走哪一條路線，以及一條把各模組串起來的 checkout 流程。範圍是模組之間的順序，每個模組內部的章節順序在該模組的列表頁。</p>
<h2 id="backend-教材的分層分類語言服務路徑與具體工具各自回答的問題">Backend 教材的分層：分類語言、服務路徑與具體工具各自回答的問題</h2>
<p>Backend 教材把後端服務能力分成三層來教。<strong>分類語言</strong>讓讀者知道資料、快取、事件、觀測、部署、驗證、資安、事故與容量各自承擔什麼責任；<strong>服務路徑</strong>用一條具體業務流程，演練這些能力之間怎麼交接；<strong>具體工具</strong>討論 PostgreSQL、Redis、Kafka、Kubernetes、PagerDuty、k6 這些服務落到真實操作時的能力、成本與遷移。</p>
<table>
  <thead>
      <tr>
          <th>層</th>
          <th>回答的問題</th>
          <th>從哪裡讀起</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>分類語言</td>
          <td>這是哪一類問題</td>
          <td><a href="/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">後端服務選型模組</a>與<a href="/blog/backend/knowledge-cards/" data-link-title="Knowledge Cards" data-link-desc="用原子化卡片整理後端服務選型前需要理解的 domain knowhow">前置知識卡片</a></td>
      </tr>
      <tr>
          <td>服務路徑</td>
          <td>一個服務流程怎麼把多個能力接起來</td>
          <td>資料庫到容量規劃各模組的主章，加上本篇下方的 checkout 流程</td>
      </tr>
      <tr>
          <td>具體工具</td>
          <td>要選哪個工具、怎麼遷移</td>
          <td>各模組的 <code>vendors/</code> 子目錄；案例庫在<a href="/blog/backend/07-security-data-protection/" data-link-title="模組七：資安與資料保護" data-link-desc="以問題驅動方式擴充資安知識網：先定義服務環節問題，再以案例作為觸發式參考">資安與資料保護模組</a>與<a href="/blog/backend/09-performance-capacity/" data-link-title="模組九：效能工程與容量規劃" data-link-desc="把『目前配置在延遲目標內處理得了多少請求、要加多少機器』變成可量化、可驗證、可改進的工程流程">效能工程與容量規劃模組</a></td>
      </tr>
  </tbody>
</table>
<p>三層的順序是理解的順序：分類語言先建立，服務路徑才有詞彙可以描述交接，具體工具的比較才有一個分類責任可以回扣。已經懂分類、只想比較工具的讀者可以直接從具體工具那一層進來，遇到工具頁回扣分類責任的段落時，再回到分類語言那一層補那一類的定義。</p>
<h2 id="依讀者目的排的閱讀路線從沒部署過服務到規模成長">依讀者目的排的閱讀路線：從沒部署過服務到規模成長</h2>
<p>下表每一列是一種讀者目的。建議順序欄的箭頭是閱讀先後，讀完那一欄說的是走完之後能做出的判斷。</p>
<table>
  <thead>
      <tr>
          <th>路線</th>
          <th>適合讀者</th>
          <th>建議順序</th>
          <th>讀完能做什麼</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>沒部署過服務</td>
          <td>會寫程式、但沒把服務上線過</td>
          <td><a href="/blog/devops/going-live/" data-link-title="服務上線：部署、主機形態、域名與 HTTPS、十二要素、自架或託管、備份與還原" data-link-desc="第一次把在本機執行的服務放上網際網路，要決定部署方式、主機形態、域名與 HTTPS、照十二要素分離設定與程式碼、資料庫自架或託管，以及備份還原怎麼做時讀">服務上線：部署、主機形態、域名與 HTTPS、十二要素、自架或託管、備份與還原</a>（部署是什麼 → 主機形態 → 域名與 HTTPS → 自架或託管 → 備份）→ 回到<a href="/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">後端服務選型模組</a>做選型</td>
          <td>能把一個服務從本機推上線，並知道接著補哪一塊</td>
      </tr>
      <tr>
          <td>系統心智模型</td>
          <td>想理解後端服務怎麼分工</td>
          <td><a href="/blog/backend/00-service-selection/delivery-mode-selection/" data-link-title="0.21 交付形態選型：從全託管到自建的光譜與邊界" data-link-desc="在進入資料庫、快取與部署選型之前、先判斷服務該用託管平台（Wix / Shopify / Google Sites）、辦公生態自動化（Apps Script）、BaaS（Firebase）、半託管 CMS（WordPress）還是自建、並為日後遷往自建保留可遷出路徑">0.21 交付形態選型：從全託管到自建的光譜與邊界</a> → <a href="/blog/backend/00-service-selection/" data-link-title="模組零：後端服務選型" data-link-desc="從需求類型判斷資料庫、快取、訊息佇列、觀測與部署平台的選型方向">後端服務選型模組</a> → <a href="/blog/backend/knowledge-cards/" data-link-title="Knowledge Cards" data-link-desc="用原子化卡片整理後端服務選型前需要理解的 domain knowhow">前置知識卡片</a> → <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">資料庫</a>、<a href="/blog/backend/02-cache-redis/" data-link-title="模組二：快取與 Redis" data-link-desc="整理快取策略、Redis 資料型別與分散式狀態輔助能力">快取</a>與<a href="/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">訊息佇列</a>三個模組的共同觀念 → <a href="/blog/backend/10-system-evolution/service-decomposition-boundaries/" data-link-title="10.1 服務拆分與邊界判讀" data-link-desc="整理 monolith vs microservice 取捨、服務邊界判讀訊號、拆分時機與回退路徑">10.1 服務拆分與邊界判讀</a>、<a href="/blog/backend/00-service-selection/cloud-vendor-capability-mapping/" data-link-title="0.19 雲端服務對照地圖（AWS / GCP / Azure）" data-link-desc="把後端能力分類對照到 AWS / GCP / Azure 的具體服務名稱、保留跨雲遷移與選型差異的判讀重點">0.19 雲端服務對照地圖（AWS / GCP / Azure）</a>、<a href="/blog/backend/09-performance-capacity/scaling-axes/" data-link-title="9.13 擴展軸與 Stateless 前提" data-link-desc="整理垂直 / 水平擴展取捨、stateless vs stateful 前提、auto scaling 操作模型與兩種擴展的 hidden cost">9.13 擴展軸與 Stateless 前提</a></td>
          <td>能把需求分類成正式狀態、暫存副本、非同步交接、觀測、部署或可靠性問題，並用服務邊界與擴展軸描述系統往哪裡走</td>
      </tr>
      <tr>
          <td>API 到資料流</td>
          <td>想設計 API 的對外契約，以及它背後的資料與事件流程</td>
          <td><a href="/blog/backend/11-api-design/" data-link-title="模組十一：API 設計與對外契約" data-link-desc="整理 API 風格選型、資源建模、錯誤模型、版本與相容策略、冪等與對外流量語意的設計判斷標準；主流做法與各流派的深度論證分層收錄">API 設計與對外契約模組</a> → <a href="/blog/backend/01-database/" data-link-title="模組一：資料庫與持久化" data-link-desc="整理 SQL、transaction、migration 與 repository adapter 的後端實務">資料庫與持久化模組</a> → <a href="/blog/backend/01-database/query-anti-patterns/" data-link-title="1.13 應用層查詢反模式與 Query 預算" data-link-desc="整理 N&#43;1、select *、缺索引、ORM lazy load、long transaction 等查詢反模式與每請求的 query 預算判讀">1.13 應用層查詢反模式與 Query 預算</a> → <a href="/blog/backend/02-cache-redis/" data-link-title="模組二：快取與 Redis" data-link-desc="整理快取策略、Redis 資料型別與分散式狀態輔助能力">快取與 Redis 模組</a> → <a href="/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">訊息佇列與事件傳遞模組</a> → <a href="/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">可觀測性平台模組</a>的證據整理 → <a href="/blog/backend/01-database/production-slow-log-loop/" data-link-title="1.14 Production Slow Log Closed Loop" data-link-desc="把 production slow log 從『偶爾看一下』變成『定期審視 &#43; PR review 整合 &#43; regression 偵測』的閉環、補 1.13 反模式清單後的操作層">1.14 Production Slow Log Closed Loop</a></td>
          <td>能說明一次 checkout 怎麼跨資料庫、快取、佇列與證據整理，並在上線前用 query 預算與 slow log 攔下查詢反模式</td>
      </tr>
      <tr>
          <td>Production 操作</td>
          <td>想學上線、觀測、驗證與事故的閉環</td>
          <td><a href="/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">可觀測性平台模組</a> → <a href="/blog/backend/05-deployment-platform/" data-link-title="模組五：部署平台與網路入口" data-link-desc="整理 Kubernetes、systemd、load balancer、container 與服務生命週期合約">部署平台與網路入口模組</a>（含 <a href="/blog/backend/05-deployment-platform/edge-cdn-static-distribution/" data-link-title="5.9 邊緣分發與靜態資源（CDN / Origin Protection）" data-link-desc="整理 CDN 與 edge cache 在部署平台中的責任邊界、origin protection、purge 與 invalidation 策略">5.9 邊緣分發與靜態資源（CDN / Origin Protection）</a>）→ <a href="/blog/backend/06-reliability/" data-link-title="模組六：可靠性驗證流程" data-link-desc="用 SRE 領域詞彙建問題節點、以服務級案例庫累積驗證脈絡，先建概念與案例庫再進實作交接">可靠性驗證流程模組</a> → <a href="/blog/backend/08-incident-response/" data-link-title="模組八：事故處理與復盤" data-link-desc="用 IR 領域詞彙建問題節點、以服務級案例庫累積事故脈絡，先建概念與案例庫再進實作交接">事故處理與復盤模組</a></td>
          <td>能把 release、alert、gate、邊緣層的 origin protection、事故決策紀錄與事後回寫串成操作閉環</td>
      </tr>
      <tr>
          <td>資安與資料保護</td>
          <td>想理解權限、秘密、資料、偵測與回應</td>
          <td><a href="/blog/backend/07-security-data-protection/" data-link-title="模組七：資安與資料保護" data-link-desc="以問題驅動方式擴充資安知識網：先定義服務環節問題，再以案例作為觸發式參考">資安與資料保護模組</a> → <a href="/blog/backend/04-observability/" data-link-title="模組四：可觀測性平台" data-link-desc="整理 log、metric、trace、dashboard 與 alert 的後端操作實務">可觀測性平台模組</a>的稽核證據 → <a href="/blog/backend/06-reliability/" data-link-title="模組六：可靠性驗證流程" data-link-desc="用 SRE 領域詞彙建問題節點、以服務級案例庫累積驗證脈絡，先建概念與案例庫再進實作交接">可靠性驗證流程模組</a>的控制驗證 → <a href="/blog/backend/08-incident-response/security-vs-operational-incident/" data-link-title="8.17 Security Incident vs Operational Incident 分流" data-link-desc="把資安事故跟可用性事故的 IR 流程分支點明確化">8.17 Security Incident vs Operational Incident 分流</a> → <a href="/blog/backend/08-incident-response/compromised-build-host-eradication/" data-link-title="8.25 建置主機被入侵後的根除與重建：清查範圍、重建來源、存取憑證撤銷與輪替的先後、多波攻擊的監看、宣告已掌握狀況的條件與承諾賠償的時機" data-link-desc="一台持有程式碼與正式環境存取權的主機（以 CI 建置主機為例）被入侵之後，清查範圍怎麼從它手上的存取憑證、讀寫得到的資料與網路連得到的系統推出來，重建時哪些來源仍可信，存取憑證撤銷與發新的先後，攻擊者回來時的監看與它的結束條件，以及對外宣告已掌握狀況、通報與承諾賠償各要先具備哪些事實">8.25 建置主機被入侵後的根除與重建</a></td>
          <td>能從身份、資料、入口、秘密與稽核證據判讀控制面</td>
      </tr>
      <tr>
          <td>工具比較與遷移</td>
          <td>已懂分類、要比較工具或規劃遷移</td>
          <td>對應模組的主章 → <a href="/blog/backend/00-service-selection/cloud-vendor-capability-mapping/" data-link-title="0.19 雲端服務對照地圖（AWS / GCP / Azure）" data-link-desc="把後端能力分類對照到 AWS / GCP / Azure 的具體服務名稱、保留跨雲遷移與選型差異的判讀重點">0.19 雲端服務對照地圖（AWS / GCP / Azure）</a> → 該模組的 <code>vendors/</code> → 遷移操作手冊（含 <a href="/blog/backend/10-system-evolution/service-decomposition-execution-runbook/" data-link-title="10.2 服務拆分執行 Runbook（Strangler Fig / 雙寫期 / 切流 / 回退）" data-link-desc="10.1 決定該拆之後、實際怎麼動手拆 — Strangler Fig pattern、雙寫期管理、切流策略、回退條件設計">10.2 服務拆分執行 Runbook（Strangler Fig / 雙寫期 / 切流 / 回退）</a>、<a href="/blog/backend/10-system-evolution/managed-platform-exit/" data-link-title="10.3 託管形態遷出：資產線盤點與並行期執行" data-link-desc="0.21 升級自建 tripwire 觸發後的執行劇本 — 把遷出拆成資料、身分、流量、整合各自的可攜性與斷點、設計舊平台與新系統的並行期與回切窗口、用部分遷出作為中繼形態">10.3 託管形態遷出：資產線盤點與並行期執行</a>）→ 案例（含 <a href="/blog/backend/01-database/production-slow-log-loop/" data-link-title="1.14 Production Slow Log Closed Loop" data-link-desc="把 production slow log 從『偶爾看一下』變成『定期審視 &#43; PR review 整合 &#43; regression 偵測』的閉環、補 1.13 反模式清單後的操作層">1.14 Production Slow Log Closed Loop</a>、<a href="/blog/backend/09-performance-capacity/connection-pool-amplification/" data-link-title="9.14 連線池放大解法（PgBouncer / RDS Proxy / ProxySQL）" data-link-desc="水平擴展應用層時 DB 連線池放大問題的具體解法、connection pooler 三大選項對比、解 9.13 提出但未深入的隱性成本">9.14 連線池放大解法（PgBouncer / RDS Proxy / ProxySQL）</a>）</td>
          <td>能先判斷分類責任，再對照雲端能力、比較具體服務、操作成本與遷移風險</td>
      </tr>
      <tr>
          <td>規模成長</td>
          <td>已經做出能跑的服務，要學讓它撐住</td>
          <td><a href="/blog/backend/scale-growth-walls/" data-link-title="服務規模成長的閱讀路線：架構撞到限制的訊號、要補的能力與對應章節" data-link-desc="一個服務從一臺機器演進到多區域多服務的過程裡架構撞到限制的訊號、每個訊號對應要補的能力與章節，以及入門影片常用的比喻各對應到哪一篇">服務規模成長的閱讀路線：架構撞到限制的訊號、要補的能力與對應章節</a>，那一篇有完整的閱讀順序與各訊號對應的章節</td>
          <td>能描述一個服務從一臺機器演進到多區域多服務的過程、每一段會撞上什麼、要先補哪一塊能力</td>
      </tr>
  </tbody>
</table>
<p>各條路線共用同一組後端詞彙，所以可以只走一條，也可以從系統心智模型那一條開始，再依工作需求轉進其他路線。表格裡帶編號的連結是單篇文章，只寫模組名的連結是整個模組。</p>
<h2 id="貫穿各模組的-checkout-範例流程與各模組處理的問題">貫穿各模組的 checkout 範例流程與各模組處理的問題</h2>
<p>各模組可以獨立閱讀，而讀者需要一個共同的場景，才看得出某一章處理的是整個服務的哪一段。Backend 教材用一條簡化的 checkout 流程當這個場景（這個 checkout 與另外三個範例系統的功能、需求與規模假設見 <a href="/blog/backend/case-systems/" data-link-title="Backend 範例系統：短網址、售票搶購、電商 checkout 與交易撮合的功能、需求與規模假設" data-link-desc="Backend 教材幾篇以具體系統走完整條請求路徑的文章共用的四個範例系統：每個系統提供的功能與請求種類、不能讓步與可以讓步的需求、規模假設與起點架構，以及四個系統在成功請求的總數是否有上限、延遲是否改變請求的價值、同一個請求被處理兩次的後果上的差別">Backend 範例系統</a>）：使用者建立訂單、付款服務回應、商品或價格資料被快取、事件送到下游的通知與報表、服務上線時產出觀測與驗證證據、事故發生時留下決策紀錄並回寫改善。</p>
<p>這條流程在演進中會遇到下面這些問題，每一個問題需要好幾個模組一起處理：</p>
<table>
  <thead>
      <tr>
          <th>問題</th>
          <th>一起處理的模組</th>
          <th>產物</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>訂單表新增付款狀態欄位</td>
          <td>資料庫、可觀測性、事故處理</td>
          <td>遷移計畫、驗證查詢、出事時的決策路徑</td>
      </tr>
      <tr>
          <td>商品價格快取失效，回源流量要保護</td>
          <td>快取、可觀測性、可靠性驗證</td>
          <td>快取證據、origin protection gate、預熱計畫</td>
      </tr>
      <tr>
          <td>訂單事件的 consumer 失敗，要重播</td>
          <td>訊息佇列、可靠性驗證、事故處理</td>
          <td>冪等證據、死信佇列的處理方式、重播 runbook</td>
      </tr>
      <tr>
          <td>Checkout 服務發版</td>
          <td>部署平台、可觀測性、事故處理</td>
          <td>發版計畫、canary 證據、drain 訊號、回滾條件</td>
      </tr>
      <tr>
          <td>付款供應商的逾時設定變更</td>
          <td>可靠性驗證、可觀測性、效能與容量</td>
          <td>release gate、SLO 證據、容量基準</td>
      </tr>
      <tr>
          <td>Webhook 的 secret 輪替</td>
          <td>資安與資料保護、可觀測性、事故處理</td>
          <td>影響範圍圖、稽核證據、回滾視窗</td>
      </tr>
      <tr>
          <td>限時搶購的高峰準備</td>
          <td>效能與容量、快取、訊息佇列、可靠性驗證</td>
          <td>負載模型、飽和證據、佇列與快取的容量 gate</td>
      </tr>
  </tbody>
</table>
<p>讀到資料庫模組時，它處理的是訂單表欄位演進那一段；讀到訊息佇列模組時，它處理的是訂單事件在程序之間的交接；讀到事故處理模組時，它收斂的是欄位演進、事件重播、發版與 secret 輪替這幾個問題出事之後的決策與回寫。</p>
]]></content:encoded></item><item><title>SQL.0 一段查詢從需求到上線的決定：追問需求、設定判斷標準、選寫法、補前提、量代價、對邊界與交付</title><link>https://tarrragon.github.io/blog/backend/01-database/sql/decisions-from-requirement-to-shipping/</link><pubDate>Tue, 22 Sep 2026 00:00:00 +0800</pubDate><guid>https://tarrragon.github.io/blog/backend/01-database/sql/decisions-from-requirement-to-shipping/</guid><description>&lt;p>這篇整理一段 SQL 查詢從業務的一句話走到上線之間要做的決定——追問需求、設定判斷標準、選寫法、補前提、量代價、對邊界、交付——每一個決定要決定什麼、決錯之後看到什麼症狀，以及它背後的機制在哪一篇展開。範圍從拿到需求的那一刻開始，到查詢上線、交給下一個環境為止。&lt;/p>
&lt;h2 id="各個決定的內容決錯之後的症狀與機制所在的篇章">各個決定的內容、決錯之後的症狀與機制所在的篇章&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>決定&lt;/th>
 &lt;th>要決定的&lt;/th>
 &lt;th>決錯之後的症狀&lt;/th>
 &lt;th>機制在&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>追問需求&lt;/td>
 &lt;td>這句話真正問的是哪一個資料問題&lt;/td>
 &lt;td>查詢寫對了，而它答的是另一題&lt;/td>
 &lt;td>答案要去問提出需求的人&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>設定判斷標準&lt;/td>
 &lt;td>什麼樣的輸出算對&lt;/td>
 &lt;td>改完查詢不知道有沒有改好&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/01-database/sql/well-formed-is-not-correct/" data-link-title="SQL.13 查詢的合法性與答案的正確性：引擎檢查的範圍、答案錯掉的成因與查證方法" data-link-desc="合法與問對了分別由誰負責、答案錯掉時引擎為什麼不報錯，以及靜態分析、約束與反例資料各自判得出哪些錯">SQL.13 查詢的合法性與答案的正確性：引擎檢查的範圍、答案錯掉的成因與查證方法&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>選寫法&lt;/td>
 &lt;td>除了判斷有沒有，還要不要用到被比對那張表的欄位&lt;/td>
 &lt;td>列數不是預期的，而後面的加總跟著錯&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/01-database/sql/in-exists-join/" data-link-title="SQL.8 IN、EXISTS 與 JOIN：列數、可取用的欄位與 NULL 的處理" data-link-desc="同一個「找出有對應資料的那些」的問題用成員判斷、存在性判斷與連接各寫一次的結果，選用的判斷標準，以及子查詢含 NULL 時 NOT IN 與 NOT EXISTS 的分岔">SQL.8 IN、EXISTS 與 JOIN：列數、可取用的欄位與 NULL 的處理&lt;/a>、&lt;a href="https://tarrragon.github.io/blog/backend/01-database/sql/table-occurrence-and-alias/" data-link-title="SQL.7 表的出現與別名：表名的指稱、別名的作用範圍與自連接" data-link-desc="FROM 裡的表名指的是什麼、同名的兩次出現為什麼被引擎擋下、自連接的前後配對、同組比較與層級關係，以及別名取名的依據">SQL.7 表的出現與別名：表名的指稱、別名的作用範圍與自連接&lt;/a>、&lt;a href="https://tarrragon.github.io/blog/backend/01-database/sql/window-keeps-rows-grouping-collapses/" data-link-title="SQL.10 分組與視窗函數：各自的產出、選用的依據與 LAG、LEAD 的相鄰列" data-link-desc="GROUP BY 與視窗函數算完之後原本的列還在不在、依結果的一列代表什麼選用哪一個、視窗函數的值怎麼拿來當篩選條件，以及 LAG 取相鄰列時分區、排序鍵與距離條件各自要確認的事">SQL.10 分組與視窗函數：各自的產出、選用的依據與 LAG、LEAD 的相鄰列&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>補前提&lt;/td>
 &lt;td>這段寫法默默假設了什麼&lt;/td>
 &lt;td>資料長成某個樣子之後答案就錯，而不報錯&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/01-database/sql/join-changes-rows-and-nulls/" data-link-title="SQL.6 連接之後的列數與空缺：列數膨脹、外連接補的 NULL 與三值邏輯" data-link-desc="連接讓聚合多算的機制與計數、加總、平均、中位數各自的修法，以及外連接補出來的 NULL 在 count、等號比較、NOT IN 與 NOT EXISTS 上的行為">SQL.6 連接之後的列數與空缺：列數膨脹、外連接補的 NULL 與三值邏輯&lt;/a>、&lt;a href="https://tarrragon.github.io/blog/backend/01-database/sql/pagination-needs-a-total-order/" data-link-title="SQL.12 分頁的排序鍵與接續標記：同分的列、全序與 OFFSET 的代價" data-link-desc="每一頁各查一次時同分的列與翻頁途中的寫入怎麼造成重複與遺漏、排序鍵補到兩兩可分的條件、展開式與列值式的接續標記條件在排序方向上的差別，以及 OFFSET 隨頁數成長的代價">SQL.12 分頁的排序鍵與接續標記：同分的列、全序與 OFFSET 的代價&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>量代價&lt;/td>
 &lt;td>這段要跑多久、跑幾次&lt;/td>
 &lt;td>開發時很快，正式資料上拖垮請求&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/01-database/sql/cost-lives-in-the-plan/" data-link-title="SQL.17 查詢的代價：資料分布、索引與寫法各自的影響" data-link-desc="找重複值的分組、自連接與 EXISTS 在有無索引與不同重複次數下的實測時間與計畫，以及比較查詢快慢時要補上的資料量、分布、索引與統計資訊">SQL.17 查詢的代價：資料分布、索引與寫法各自的影響&lt;/a>、&lt;a href="https://tarrragon.github.io/blog/backend/01-database/sql/knowledge-cards/sargable/" data-link-title="Sargable（可走索引的條件形狀）" data-link-desc="索引存在而計畫仍走全表掃描時，查條件的寫法有沒有擋住那個索引">Sargable&lt;/a> 條件的形狀決定索引用不用得上&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>對邊界&lt;/td>
 &lt;td>需求沒說而資料會有的那些&lt;/td>
 &lt;td>平常都對，特定幾筆資料上靜默算錯&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/01-database/sql/relations-have-no-order/" data-link-title="SQL.11 查詢結果的列序：沒有 ORDER BY 時的來源與 ORDER BY 的規定範圍" data-link-desc="同一段查詢在建索引前後回不同順序的機制、ORDER BY 在求值順序的位置，以及空值落在哪一端各家的差別">SQL.11 查詢結果的列序：沒有 ORDER BY 時的來源與 ORDER BY 的規定範圍&lt;/a>、&lt;a href="https://tarrragon.github.io/blog/backend/01-database/sql/well-formed-is-not-correct/" data-link-title="SQL.13 查詢的合法性與答案的正確性：引擎檢查的範圍、答案錯掉的成因與查證方法" data-link-desc="合法與問對了分別由誰負責、答案錯掉時引擎為什麼不報錯，以及靜態分析、約束與反例資料各自判得出哪些錯">SQL.13 查詢的合法性與答案的正確性：引擎檢查的範圍、答案錯掉的成因與查證方法&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>交付&lt;/td>
 &lt;td>換引擎、換資料量、換讀的人之後還成不成立&lt;/td>
 &lt;td>會報錯的差異搬家當天就浮現，不報錯的要等某一筆資料才現形或始終不出聲&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/01-database/sql/engine-leniency-and-portability/" data-link-title="SQL.19 引擎寬鬆度與可攜性：各家對同一組寫法的差異、分級與處理時機" data-link-desc="SQLite、DuckDB、PostgreSQL 與 MySQL 在未分組欄位、WHERE 用別名、同表未取別名、字串比對與空值排序上的實測對照，差異從當場報錯到完全靜默的分級，以及依目標組態數決定哪幾級差異在寫的當下處理">SQL.19 引擎寬鬆度與可攜性：各家對同一組寫法的差異、分級與處理時機&lt;/a> 管換引擎、&lt;a href="https://tarrragon.github.io/blog/backend/01-database/sql/declared-intent-vs-behaviour/" data-link-title="SQL.20 關鍵字的宣告與引擎的行為：宣告落空的形態與查證" data-link-desc="LEFT JOIN、CROSS JOIN、DISTINCT、COALESCE 與表的別名各自對讀的人宣告了什麼、宣告落空時下一個修改的人付出什麼代價，以及把關鍵字換成最弱的版本再跑一次的查證動作">SQL.20 關鍵字的宣告與引擎的行為：宣告落空的形態與查證&lt;/a> 管換讀的人&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>決錯之後的症狀有一個共同點：查詢照跑而答案不對。&lt;/strong> 只有兩個決定決錯時會當場出聲：量代價決錯時查詢慢得看得出來；交付時換了引擎，有一類差異第一次執行就報錯。&lt;a href="https://tarrragon.github.io/blog/backend/01-database/sql/engine-leniency-and-portability/" data-link-title="SQL.19 引擎寬鬆度與可攜性：各家對同一組寫法的差異、分級與處理時機" data-link-desc="SQLite、DuckDB、PostgreSQL 與 MySQL 在未分組欄位、WHERE 用別名、同表未取別名、字串比對與空值排序上的實測對照，差異從當場報錯到完全靜默的分級，以及依目標組態數決定哪幾級差異在寫的當下處理">SQL.19 引擎寬鬆度與可攜性：各家對同一組寫法的差異、分級與處理時機&lt;/a> 把跨引擎的差異按發聲的位置分級，第一次執行就報錯的叫當場報錯，其餘的差異要麼等某一筆資料才報錯、要麼始終靜默。其餘的決定決錯時欄位正常、列數合理，沒有任何東西提示要去檢查。&lt;/p>
&lt;h2 id="最常被跳過的決定追問需求設定判斷標準與對邊界">最常被跳過的決定：追問需求、設定判斷標準與對邊界&lt;/h2>
&lt;p>&lt;strong>追問需求與設定判斷標準。&lt;/strong> 這兩個決定發生在打開編輯器之前，所以不留下任何痕跡——跳過了的查詢跟沒跳過的長得一模一樣。而跳過追問需求的代價是整段查詢答錯題，跳過設定判斷標準的代價是後面每一次修改都不知道有沒有改好。&lt;/p>
&lt;p>&lt;strong>對邊界。&lt;/strong> 一句需求描述的是資料正常時的樣子，而正式資料裡會出現提出需求的人沒想到、所以沒說的情形。以「哪幾天氣溫比前一天高」為例：同一個測站同一天有兩筆紀錄（感測器重送、補登、換設備之後兩套系統各寫一筆）、觀測日存的是哪一個時區的日期、三個月後才補進來的舊資料讓昨天的答案今天變了、同一個測站代號在某一天之後指向另一個地點。對邊界這個決定，就是在查詢寫好之後把這些情形逐一列出來，並決定每一種出現時查詢該回什麼。&lt;/p>
&lt;p>這份清單沒有地方可以查。需求裡沒有它，schema 也只記下有哪些欄位、各是什麼型別，不記下資料在現實中會怎麼偏離預期。列得出幾種，取決於看過多少這個領域的資料：看過感測器重送，才會想到同一天可能有兩筆；看過補登，才會想到歷史答案會變。所以這一步的能力靠經驗累積，每在正式資料上遇到一種新的情形，就把它加進這個領域的查詢的檢查清單。&lt;/p>
&lt;p>跳過它的症狀最難察覺：查詢在大部分資料上都對，只在碰到那幾筆特殊資料時算錯，而且不報錯。那幾筆往往要到有人拿結果去對帳，才被發現。&lt;/p>
&lt;h2 id="決定的前提建表時定下的表的形狀">決定的前提：建表時定下的表的形狀&lt;/h2>
&lt;p>從追問需求到交付，每一個決定都做在一組已經建好的表上，而表的形狀是&lt;strong>建表時的決定&lt;/strong>造出來的：欄位允不允許為空、鍵唯不唯一、長欄位放哪一張表、常一起取的資料切在幾張表、字串的比較規則寫在哪一層、外鍵生不生效。選寫法、補前提的時候，鍵唯不唯一、欄位允不允許為空已經定了；量代價的時候，長欄位放哪一張表、常一起取的資料切在幾張表也已經定了。這些建表時的決定替往後每一段查詢定了價——手上要交的是一份 schema 設計而不是一段查詢時，問題落在追問需求之前。以鍵唯不唯一為例：「哪幾天氣溫比前一天高」用自連接、視窗函數與相關子查詢三種寫法，共同押的前提，是同一個測站同一天只有一筆；表上有 &lt;code>UNIQUE (測站, 觀測日)&lt;/code> 時這個前提由資料庫保證，沒有的話每一段查詢都得自己處理重複，否則自連接會把一列配成多列。每一個決定各自替查詢定了什麼代價，實測在 &lt;a href="https://tarrragon.github.io/blog/backend/01-database/design-decisions-price-every-query/" data-link-title="1.16 Schema 設計決定的查詢代價：可空性、排序鍵唯一性、表寬、一對多的切法、比較規則與外鍵執法" data-link-desc="建表時每一個決定有哪些選法、選了之後查詢要多做什麼、代價在什麼條件下才浮現、改回來要付的遷移成本，以及設計當下就能問的問題；輸出為 SQLite 與 PostgreSQL 的實測">backend 1.16 Schema 設計決定的查詢代價&lt;/a>。&lt;/p>
&lt;h2 id="在哪幾天氣溫比前一天高這句需求上做完全部決定的示範">在「哪幾天氣溫比前一天高」這句需求上做完全部決定的示範&lt;/h2>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/backend/01-database/sql/requirement-to-shipped-query/" data-link-title="SQL.22 查詢設計的完整示範：把「哪幾天氣溫比前一天高」從需求做到上線" data-link-desc="以「哪幾天氣溫比前一天高」為例，把一句業務的話追問成可驗收的資料問題，比較自連接、視窗函數與相關子查詢各自押的前提與實測代價，以及需求沒說而資料會有的重複紀錄、時區與補登">SQL.22 查詢設計的完整示範：把「哪幾天氣溫比前一天高」從需求做到上線&lt;/a> 拿「哪幾天氣溫比前一天高」這句需求從頭做完這些決定：把「前一天」追問成日曆上的前一天還是資料上的前一筆；用自連接、視窗函數與相關子查詢各寫一次，找出三者共同押的前提（同一個測站同一天只有一筆）；看漏掉相隔天數與漏掉分區的兩個錯誤版本：漏掉相隔天數的多報，漏掉分區的錯在哪個方向要看同一天兩個測站誰排在前面；把自連接再分成日期差與等值兩種寫法，在同一組資料上量這兩種自連接、視窗函數與相關子查詢的時間，差到三個量級，其中一種加了索引反而變慢；最後列出重複紀錄、時區、補登與測站搬家這幾種需求沒說的情形。&lt;/p></description><content:encoded><![CDATA[<p>這篇整理一段 SQL 查詢從業務的一句話走到上線之間要做的決定——追問需求、設定判斷標準、選寫法、補前提、量代價、對邊界、交付——每一個決定要決定什麼、決錯之後看到什麼症狀，以及它背後的機制在哪一篇展開。範圍從拿到需求的那一刻開始，到查詢上線、交給下一個環境為止。</p>
<h2 id="各個決定的內容決錯之後的症狀與機制所在的篇章">各個決定的內容、決錯之後的症狀與機制所在的篇章</h2>
<table>
  <thead>
      <tr>
          <th>決定</th>
          <th>要決定的</th>
          <th>決錯之後的症狀</th>
          <th>機制在</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>追問需求</td>
          <td>這句話真正問的是哪一個資料問題</td>
          <td>查詢寫對了，而它答的是另一題</td>
          <td>答案要去問提出需求的人</td>
      </tr>
      <tr>
          <td>設定判斷標準</td>
          <td>什麼樣的輸出算對</td>
          <td>改完查詢不知道有沒有改好</td>
          <td><a href="/blog/backend/01-database/sql/well-formed-is-not-correct/" data-link-title="SQL.13 查詢的合法性與答案的正確性：引擎檢查的範圍、答案錯掉的成因與查證方法" data-link-desc="合法與問對了分別由誰負責、答案錯掉時引擎為什麼不報錯，以及靜態分析、約束與反例資料各自判得出哪些錯">SQL.13 查詢的合法性與答案的正確性：引擎檢查的範圍、答案錯掉的成因與查證方法</a></td>
      </tr>
      <tr>
          <td>選寫法</td>
          <td>除了判斷有沒有，還要不要用到被比對那張表的欄位</td>
          <td>列數不是預期的，而後面的加總跟著錯</td>
          <td><a href="/blog/backend/01-database/sql/in-exists-join/" data-link-title="SQL.8 IN、EXISTS 與 JOIN：列數、可取用的欄位與 NULL 的處理" data-link-desc="同一個「找出有對應資料的那些」的問題用成員判斷、存在性判斷與連接各寫一次的結果，選用的判斷標準，以及子查詢含 NULL 時 NOT IN 與 NOT EXISTS 的分岔">SQL.8 IN、EXISTS 與 JOIN：列數、可取用的欄位與 NULL 的處理</a>、<a href="/blog/backend/01-database/sql/table-occurrence-and-alias/" data-link-title="SQL.7 表的出現與別名：表名的指稱、別名的作用範圍與自連接" data-link-desc="FROM 裡的表名指的是什麼、同名的兩次出現為什麼被引擎擋下、自連接的前後配對、同組比較與層級關係，以及別名取名的依據">SQL.7 表的出現與別名：表名的指稱、別名的作用範圍與自連接</a>、<a href="/blog/backend/01-database/sql/window-keeps-rows-grouping-collapses/" data-link-title="SQL.10 分組與視窗函數：各自的產出、選用的依據與 LAG、LEAD 的相鄰列" data-link-desc="GROUP BY 與視窗函數算完之後原本的列還在不在、依結果的一列代表什麼選用哪一個、視窗函數的值怎麼拿來當篩選條件，以及 LAG 取相鄰列時分區、排序鍵與距離條件各自要確認的事">SQL.10 分組與視窗函數：各自的產出、選用的依據與 LAG、LEAD 的相鄰列</a></td>
      </tr>
      <tr>
          <td>補前提</td>
          <td>這段寫法默默假設了什麼</td>
          <td>資料長成某個樣子之後答案就錯，而不報錯</td>
          <td><a href="/blog/backend/01-database/sql/join-changes-rows-and-nulls/" data-link-title="SQL.6 連接之後的列數與空缺：列數膨脹、外連接補的 NULL 與三值邏輯" data-link-desc="連接讓聚合多算的機制與計數、加總、平均、中位數各自的修法，以及外連接補出來的 NULL 在 count、等號比較、NOT IN 與 NOT EXISTS 上的行為">SQL.6 連接之後的列數與空缺：列數膨脹、外連接補的 NULL 與三值邏輯</a>、<a href="/blog/backend/01-database/sql/pagination-needs-a-total-order/" data-link-title="SQL.12 分頁的排序鍵與接續標記：同分的列、全序與 OFFSET 的代價" data-link-desc="每一頁各查一次時同分的列與翻頁途中的寫入怎麼造成重複與遺漏、排序鍵補到兩兩可分的條件、展開式與列值式的接續標記條件在排序方向上的差別，以及 OFFSET 隨頁數成長的代價">SQL.12 分頁的排序鍵與接續標記：同分的列、全序與 OFFSET 的代價</a></td>
      </tr>
      <tr>
          <td>量代價</td>
          <td>這段要跑多久、跑幾次</td>
          <td>開發時很快，正式資料上拖垮請求</td>
          <td><a href="/blog/backend/01-database/sql/cost-lives-in-the-plan/" data-link-title="SQL.17 查詢的代價：資料分布、索引與寫法各自的影響" data-link-desc="找重複值的分組、自連接與 EXISTS 在有無索引與不同重複次數下的實測時間與計畫，以及比較查詢快慢時要補上的資料量、分布、索引與統計資訊">SQL.17 查詢的代價：資料分布、索引與寫法各自的影響</a>、<a href="/blog/backend/01-database/sql/knowledge-cards/sargable/" data-link-title="Sargable（可走索引的條件形狀）" data-link-desc="索引存在而計畫仍走全表掃描時，查條件的寫法有沒有擋住那個索引">Sargable</a> 條件的形狀決定索引用不用得上</td>
      </tr>
      <tr>
          <td>對邊界</td>
          <td>需求沒說而資料會有的那些</td>
          <td>平常都對，特定幾筆資料上靜默算錯</td>
          <td><a href="/blog/backend/01-database/sql/relations-have-no-order/" data-link-title="SQL.11 查詢結果的列序：沒有 ORDER BY 時的來源與 ORDER BY 的規定範圍" data-link-desc="同一段查詢在建索引前後回不同順序的機制、ORDER BY 在求值順序的位置，以及空值落在哪一端各家的差別">SQL.11 查詢結果的列序：沒有 ORDER BY 時的來源與 ORDER BY 的規定範圍</a>、<a href="/blog/backend/01-database/sql/well-formed-is-not-correct/" data-link-title="SQL.13 查詢的合法性與答案的正確性：引擎檢查的範圍、答案錯掉的成因與查證方法" data-link-desc="合法與問對了分別由誰負責、答案錯掉時引擎為什麼不報錯，以及靜態分析、約束與反例資料各自判得出哪些錯">SQL.13 查詢的合法性與答案的正確性：引擎檢查的範圍、答案錯掉的成因與查證方法</a></td>
      </tr>
      <tr>
          <td>交付</td>
          <td>換引擎、換資料量、換讀的人之後還成不成立</td>
          <td>會報錯的差異搬家當天就浮現，不報錯的要等某一筆資料才現形或始終不出聲</td>
          <td><a href="/blog/backend/01-database/sql/engine-leniency-and-portability/" data-link-title="SQL.19 引擎寬鬆度與可攜性：各家對同一組寫法的差異、分級與處理時機" data-link-desc="SQLite、DuckDB、PostgreSQL 與 MySQL 在未分組欄位、WHERE 用別名、同表未取別名、字串比對與空值排序上的實測對照，差異從當場報錯到完全靜默的分級，以及依目標組態數決定哪幾級差異在寫的當下處理">SQL.19 引擎寬鬆度與可攜性：各家對同一組寫法的差異、分級與處理時機</a> 管換引擎、<a href="/blog/backend/01-database/sql/declared-intent-vs-behaviour/" data-link-title="SQL.20 關鍵字的宣告與引擎的行為：宣告落空的形態與查證" data-link-desc="LEFT JOIN、CROSS JOIN、DISTINCT、COALESCE 與表的別名各自對讀的人宣告了什麼、宣告落空時下一個修改的人付出什麼代價，以及把關鍵字換成最弱的版本再跑一次的查證動作">SQL.20 關鍵字的宣告與引擎的行為：宣告落空的形態與查證</a> 管換讀的人</td>
      </tr>
  </tbody>
</table>
<p><strong>決錯之後的症狀有一個共同點：查詢照跑而答案不對。</strong> 只有兩個決定決錯時會當場出聲：量代價決錯時查詢慢得看得出來；交付時換了引擎，有一類差異第一次執行就報錯。<a href="/blog/backend/01-database/sql/engine-leniency-and-portability/" data-link-title="SQL.19 引擎寬鬆度與可攜性：各家對同一組寫法的差異、分級與處理時機" data-link-desc="SQLite、DuckDB、PostgreSQL 與 MySQL 在未分組欄位、WHERE 用別名、同表未取別名、字串比對與空值排序上的實測對照，差異從當場報錯到完全靜默的分級，以及依目標組態數決定哪幾級差異在寫的當下處理">SQL.19 引擎寬鬆度與可攜性：各家對同一組寫法的差異、分級與處理時機</a> 把跨引擎的差異按發聲的位置分級，第一次執行就報錯的叫當場報錯，其餘的差異要麼等某一筆資料才報錯、要麼始終靜默。其餘的決定決錯時欄位正常、列數合理，沒有任何東西提示要去檢查。</p>
<h2 id="最常被跳過的決定追問需求設定判斷標準與對邊界">最常被跳過的決定：追問需求、設定判斷標準與對邊界</h2>
<p><strong>追問需求與設定判斷標準。</strong> 這兩個決定發生在打開編輯器之前，所以不留下任何痕跡——跳過了的查詢跟沒跳過的長得一模一樣。而跳過追問需求的代價是整段查詢答錯題，跳過設定判斷標準的代價是後面每一次修改都不知道有沒有改好。</p>
<p><strong>對邊界。</strong> 一句需求描述的是資料正常時的樣子，而正式資料裡會出現提出需求的人沒想到、所以沒說的情形。以「哪幾天氣溫比前一天高」為例：同一個測站同一天有兩筆紀錄（感測器重送、補登、換設備之後兩套系統各寫一筆）、觀測日存的是哪一個時區的日期、三個月後才補進來的舊資料讓昨天的答案今天變了、同一個測站代號在某一天之後指向另一個地點。對邊界這個決定，就是在查詢寫好之後把這些情形逐一列出來，並決定每一種出現時查詢該回什麼。</p>
<p>這份清單沒有地方可以查。需求裡沒有它，schema 也只記下有哪些欄位、各是什麼型別，不記下資料在現實中會怎麼偏離預期。列得出幾種，取決於看過多少這個領域的資料：看過感測器重送，才會想到同一天可能有兩筆；看過補登，才會想到歷史答案會變。所以這一步的能力靠經驗累積，每在正式資料上遇到一種新的情形，就把它加進這個領域的查詢的檢查清單。</p>
<p>跳過它的症狀最難察覺：查詢在大部分資料上都對，只在碰到那幾筆特殊資料時算錯，而且不報錯。那幾筆往往要到有人拿結果去對帳，才被發現。</p>
<h2 id="決定的前提建表時定下的表的形狀">決定的前提：建表時定下的表的形狀</h2>
<p>從追問需求到交付，每一個決定都做在一組已經建好的表上，而表的形狀是<strong>建表時的決定</strong>造出來的：欄位允不允許為空、鍵唯不唯一、長欄位放哪一張表、常一起取的資料切在幾張表、字串的比較規則寫在哪一層、外鍵生不生效。選寫法、補前提的時候，鍵唯不唯一、欄位允不允許為空已經定了；量代價的時候，長欄位放哪一張表、常一起取的資料切在幾張表也已經定了。這些建表時的決定替往後每一段查詢定了價——手上要交的是一份 schema 設計而不是一段查詢時，問題落在追問需求之前。以鍵唯不唯一為例：「哪幾天氣溫比前一天高」用自連接、視窗函數與相關子查詢三種寫法，共同押的前提，是同一個測站同一天只有一筆；表上有 <code>UNIQUE (測站, 觀測日)</code> 時這個前提由資料庫保證，沒有的話每一段查詢都得自己處理重複，否則自連接會把一列配成多列。每一個決定各自替查詢定了什麼代價，實測在 <a href="/blog/backend/01-database/design-decisions-price-every-query/" data-link-title="1.16 Schema 設計決定的查詢代價：可空性、排序鍵唯一性、表寬、一對多的切法、比較規則與外鍵執法" data-link-desc="建表時每一個決定有哪些選法、選了之後查詢要多做什麼、代價在什麼條件下才浮現、改回來要付的遷移成本，以及設計當下就能問的問題；輸出為 SQLite 與 PostgreSQL 的實測">backend 1.16 Schema 設計決定的查詢代價</a>。</p>
<h2 id="在哪幾天氣溫比前一天高這句需求上做完全部決定的示範">在「哪幾天氣溫比前一天高」這句需求上做完全部決定的示範</h2>
<p><a href="/blog/backend/01-database/sql/requirement-to-shipped-query/" data-link-title="SQL.22 查詢設計的完整示範：把「哪幾天氣溫比前一天高」從需求做到上線" data-link-desc="以「哪幾天氣溫比前一天高」為例，把一句業務的話追問成可驗收的資料問題，比較自連接、視窗函數與相關子查詢各自押的前提與實測代價，以及需求沒說而資料會有的重複紀錄、時區與補登">SQL.22 查詢設計的完整示範：把「哪幾天氣溫比前一天高」從需求做到上線</a> 拿「哪幾天氣溫比前一天高」這句需求從頭做完這些決定：把「前一天」追問成日曆上的前一天還是資料上的前一筆；用自連接、視窗函數與相關子查詢各寫一次，找出三者共同押的前提（同一個測站同一天只有一筆）；看漏掉相隔天數與漏掉分區的兩個錯誤版本：漏掉相隔天數的多報，漏掉分區的錯在哪個方向要看同一天兩個測站誰排在前面；把自連接再分成日期差與等值兩種寫法，在同一組資料上量這兩種自連接、視窗函數與相關子查詢的時間，差到三個量級，其中一種加了索引反而變慢；最後列出重複紀錄、時區、補登與測站搬家這幾種需求沒說的情形。</p>
]]></content:encoded></item><item><title>服務規模成長的閱讀路線：架構撞到限制的訊號、要補的能力與對應章節</title><link>https://tarrragon.github.io/blog/backend/scale-growth-walls/</link><pubDate>Thu, 24 Sep 2026 00:00:00 +0800</pubDate><guid>https://tarrragon.github.io/blog/backend/scale-growth-walls/</guid><description>&lt;p>這篇整理一個已經能跑的服務，在流量與業務長大之後會依序撞上哪些限制、每一種限制要補哪一塊能力，以及 Backend 教材裡對應的章節。範圍從一臺機器開始，到多區域、多服務為止；還沒把服務做出來的讀者，先走&lt;a href="https://tarrragon.github.io/blog/backend/reading-paths/" data-link-title="Backend 教材的閱讀路線：教材的分層、依讀者目的排的模組順序與貫穿各模組的 checkout 範例流程" data-link-desc="Backend 教材各模組之間的閱讀順序：分類語言、服務路徑與具體工具的分層，依讀者目的（把服務上線、設計 API、學 production 操作、看懂資安控制、比較工具、讓服務撐住成長）排的路線，以及各模組在一條 checkout 流程裡處理的問題">閱讀路線&lt;/a>裡「沒部署過服務」或「API 到資料流」那兩條。&lt;/p>
&lt;h2 id="架構調整的時機與架構撞到限制的訊號">架構調整的時機與架構撞到限制的訊號&lt;/h2>
&lt;p>服務的架構會長出新的部分，是因為現有的形狀承受不了某一種壓力，而那種壓力在監控或使用者回報裡有一個可辨認的樣子，本篇稱它為架構撞到限制的訊號：單一服務承載不了業務分化、單機規格撞到天花板、應用層的查詢變慢、單一資料庫成為瓶頸、源站被流量打爆、同步呼叫卡住整條交易流程、可預期的活動高峰需要事前準備。&lt;/p>
&lt;p>所以這一組章節的讀法是&lt;strong>先認出手上是哪一種訊號，再讀那一種訊號對應的能力&lt;/strong>，而不是照模組編號順讀。同一個訊號過早處理，付的是用不到的複雜度；過晚處理，付的是事故。&lt;/p>
&lt;p>這條路線和閱讀路線裡的「API 到資料流」分工不同：那一條教怎麼把功能做出來，這一條教做出來之後怎麼撐住。兩條可以分開讀，也可以寫完第一個 MVP 之後回到這一篇盤點。MVP 如果是用託管平台或 BaaS 做的，先用 &lt;a href="https://tarrragon.github.io/blog/backend/00-service-selection/delivery-mode-selection/" data-link-title="0.21 交付形態選型：從全託管到自建的光譜與邊界" data-link-desc="在進入資料庫、快取與部署選型之前、先判斷服務該用託管平台（Wix / Shopify / Google Sites）、辦公生態自動化（Apps Script）、BaaS（Firebase）、半託管 CMS（WordPress）還是自建、並為日後遷往自建保留可遷出路徑">0.21 交付形態選型：從全託管到自建的光譜與邊界&lt;/a> 的升級自建 tripwire 判斷該不該啟動自建評估；評估成立的話，遷出的執行在 &lt;a href="https://tarrragon.github.io/blog/backend/10-system-evolution/managed-platform-exit/" data-link-title="10.3 託管形態遷出：資產線盤點與並行期執行" data-link-desc="0.21 升級自建 tripwire 觸發後的執行劇本 — 把遷出拆成資料、身分、流量、整合各自的可攜性與斷點、設計舊平台與新系統的並行期與回切窗口、用部分遷出作為中繼形態">10.3 託管形態遷出：資產線盤點與並行期執行&lt;/a>，遷入之後再照下面的訊號走。&lt;/p>
&lt;h2 id="各種架構撞到限制的訊號與要補的能力">各種架構撞到限制的訊號與要補的能力&lt;/h2>
&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>一臺機器的 CPU 或記憶體吃滿&lt;/td>
 &lt;td>評估垂直或水平擴展，確認服務是 stateless&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/scaling-axes/" data-link-title="9.13 擴展軸與 Stateless 前提" data-link-desc="整理垂直 / 水平擴展取捨、stateless vs stateful 前提、auto scaling 操作模型與兩種擴展的 hidden cost">9.13 擴展軸與 Stateless 前提&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>資料庫變慢，加機器看起來只是暫時止血&lt;/td>
 &lt;td>先用查詢反模式清單收回單機容量，再考慮升級規格或換服務&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/01-database/query-anti-patterns/" data-link-title="1.13 應用層查詢反模式與 Query 預算" data-link-desc="整理 N&amp;#43;1、select *、缺索引、ORM lazy load、long transaction 等查詢反模式與每請求的 query 預算判讀">1.13 應用層查詢反模式與 Query 預算&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>資料庫寫入正常，但讀取把主庫壓垮&lt;/td>
 &lt;td>開 read replica，應用層配讀寫路由，並加快取&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/01-database/high-concurrency-access/" data-link-title="1.1 高併發下的 SQL 讀寫邊界" data-link-desc="說明高併發服務如何共用資料庫 client、控制 transaction、管理 connection pool、避免資料庫成為瓶頸">1.1 高併發下的 SQL 讀寫邊界&lt;/a>、&lt;a href="https://tarrragon.github.io/blog/backend/02-cache-redis/cache-aside/" data-link-title="2.2 cache aside 與失效策略" data-link-desc="整理 read-through 思路、cache miss 與 invalidation">2.2 cache aside 與失效策略&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>活動或引流時，源站被靜態資源請求打爆&lt;/td>
 &lt;td>把靜態與半靜態內容放到邊緣層，保護源站&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/05-deployment-platform/edge-cdn-static-distribution/" data-link-title="5.9 邊緣分發與靜態資源（CDN / Origin Protection）" data-link-desc="整理 CDN 與 edge cache 在部署平台中的責任邊界、origin protection、purge 與 invalidation 策略">5.9 邊緣分發與靜態資源（CDN / Origin Protection）&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>同步呼叫卡住交易流程，付款與通知互相阻塞&lt;/td>
 &lt;td>拆成事件、非同步化，加上冪等&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">訊息佇列與事件傳遞模組&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>業務分化，團隊之間的發版互相阻擋&lt;/td>
 &lt;td>沿真實的邊界拆服務（資料、團隊、部署或流量）&lt;/td>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/backend/10-system-evolution/service-decomposition-boundaries/" data-link-title="10.1 服務拆分與邊界判讀" data-link-desc="整理 monolith vs microservice 取捨、服務邊界判讀訊號、拆分時機與回退路徑">10.1 服務拆分與邊界判讀&lt;/a>&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>表格由上往下大致是一個服務撞到這些訊號的常見先後，而先後不是固定的：有的團隊在單機容量用完之前就先拆服務，有的團隊一直不需要拆。源站被打爆之後如果還要應付可預期的活動高峰（雙 11、新片上線、推廣活動），加讀 &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/peak-event-readiness/" data-link-title="9.11 高峰事件準備" data-link-desc="可預期峰值從 T-90 到 T-0 的準備時程：容量計畫、quota 申請、壓測、game day 與 pre-scaling 各排在事件前幾天、排在那裡的理由與項目之間的依賴，pre-scaling 的做法、watch room、event tier 分級與準備時間不夠時被壓縮的部分，以及事後 retro">9.11 高峰事件準備&lt;/a>；平日的容量規劃在 &lt;a href="https://tarrragon.github.io/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 容量規劃模型&lt;/a>。&lt;/p>
&lt;h2 id="規模成長路線從頭讀的章節順序">規模成長路線從頭讀的章節順序&lt;/h2>
&lt;p>要把整條路線從頭讀一次，順序是：&lt;a href="https://tarrragon.github.io/blog/backend/00-service-selection/delivery-mode-selection/" data-link-title="0.21 交付形態選型：從全託管到自建的光譜與邊界" data-link-desc="在進入資料庫、快取與部署選型之前、先判斷服務該用託管平台（Wix / Shopify / Google Sites）、辦公生態自動化（Apps Script）、BaaS（Firebase）、半託管 CMS（WordPress）還是自建、並為日後遷往自建保留可遷出路徑">0.21 交付形態選型：從全託管到自建的光譜與邊界&lt;/a>的升級 tripwire → &lt;a href="https://tarrragon.github.io/blog/backend/00-service-selection/backend-demand-taxonomy/" data-link-title="0.0 後端需求分類地圖" data-link-desc="先從需求形狀辨識狀態、讀取、非同步、即時、診斷、交付與可靠性問題">0.0 後端需求分類地圖&lt;/a> → &lt;a href="https://tarrragon.github.io/blog/backend/10-system-evolution/managed-platform-exit/" data-link-title="10.3 託管形態遷出：資產線盤點與並行期執行" data-link-desc="0.21 升級自建 tripwire 觸發後的執行劇本 — 把遷出拆成資料、身分、流量、整合各自的可攜性與斷點、設計舊平台與新系統的並行期與回切窗口、用部分遷出作為中繼形態">10.3 託管形態遷出：資產線盤點與並行期執行&lt;/a>（從託管平台出身的服務才需要）→ &lt;a href="https://tarrragon.github.io/blog/backend/10-system-evolution/service-decomposition-boundaries/" data-link-title="10.1 服務拆分與邊界判讀" data-link-desc="整理 monolith vs microservice 取捨、服務邊界判讀訊號、拆分時機與回退路徑">10.1 服務拆分與邊界判讀&lt;/a> → &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/scaling-axes/" data-link-title="9.13 擴展軸與 Stateless 前提" data-link-desc="整理垂直 / 水平擴展取捨、stateless vs stateful 前提、auto scaling 操作模型與兩種擴展的 hidden cost">9.13 擴展軸與 Stateless 前提&lt;/a> → &lt;a href="https://tarrragon.github.io/blog/backend/01-database/query-anti-patterns/" data-link-title="1.13 應用層查詢反模式與 Query 預算" data-link-desc="整理 N&amp;#43;1、select *、缺索引、ORM lazy load、long transaction 等查詢反模式與每請求的 query 預算判讀">1.13 應用層查詢反模式與 Query 預算&lt;/a> → &lt;a href="https://tarrragon.github.io/blog/backend/01-database/high-concurrency-access/" data-link-title="1.1 高併發下的 SQL 讀寫邊界" data-link-desc="說明高併發服務如何共用資料庫 client、控制 transaction、管理 connection pool、避免資料庫成為瓶頸">1.1 高併發下的 SQL 讀寫邊界&lt;/a> → &lt;a href="https://tarrragon.github.io/blog/backend/02-cache-redis/cache-aside/" data-link-title="2.2 cache aside 與失效策略" data-link-desc="整理 read-through 思路、cache miss 與 invalidation">2.2 cache aside 與失效策略&lt;/a> → &lt;a href="https://tarrragon.github.io/blog/backend/05-deployment-platform/edge-cdn-static-distribution/" data-link-title="5.9 邊緣分發與靜態資源（CDN / Origin Protection）" data-link-desc="整理 CDN 與 edge cache 在部署平台中的責任邊界、origin protection、purge 與 invalidation 策略">5.9 邊緣分發與靜態資源（CDN / Origin Protection）&lt;/a> → &lt;a href="https://tarrragon.github.io/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">訊息佇列與事件傳遞模組&lt;/a> → &lt;a href="https://tarrragon.github.io/blog/backend/09-performance-capacity/peak-event-readiness/" data-link-title="9.11 高峰事件準備" data-link-desc="可預期峰值從 T-90 到 T-0 的準備時程：容量計畫、quota 申請、壓測、game day 與 pre-scaling 各排在事件前幾天、排在那裡的理由與項目之間的依賴，pre-scaling 的做法、watch room、event tier 分級與準備時間不夠時被壓縮的部分，以及事後 retro">9.11 高峰事件準備&lt;/a>。&lt;/p></description><content:encoded><![CDATA[<p>這篇整理一個已經能跑的服務，在流量與業務長大之後會依序撞上哪些限制、每一種限制要補哪一塊能力，以及 Backend 教材裡對應的章節。範圍從一臺機器開始，到多區域、多服務為止；還沒把服務做出來的讀者，先走<a href="/blog/backend/reading-paths/" data-link-title="Backend 教材的閱讀路線：教材的分層、依讀者目的排的模組順序與貫穿各模組的 checkout 範例流程" data-link-desc="Backend 教材各模組之間的閱讀順序：分類語言、服務路徑與具體工具的分層，依讀者目的（把服務上線、設計 API、學 production 操作、看懂資安控制、比較工具、讓服務撐住成長）排的路線，以及各模組在一條 checkout 流程裡處理的問題">閱讀路線</a>裡「沒部署過服務」或「API 到資料流」那兩條。</p>
<h2 id="架構調整的時機與架構撞到限制的訊號">架構調整的時機與架構撞到限制的訊號</h2>
<p>服務的架構會長出新的部分，是因為現有的形狀承受不了某一種壓力，而那種壓力在監控或使用者回報裡有一個可辨認的樣子，本篇稱它為架構撞到限制的訊號：單一服務承載不了業務分化、單機規格撞到天花板、應用層的查詢變慢、單一資料庫成為瓶頸、源站被流量打爆、同步呼叫卡住整條交易流程、可預期的活動高峰需要事前準備。</p>
<p>所以這一組章節的讀法是<strong>先認出手上是哪一種訊號，再讀那一種訊號對應的能力</strong>，而不是照模組編號順讀。同一個訊號過早處理，付的是用不到的複雜度；過晚處理，付的是事故。</p>
<p>這條路線和閱讀路線裡的「API 到資料流」分工不同：那一條教怎麼把功能做出來，這一條教做出來之後怎麼撐住。兩條可以分開讀，也可以寫完第一個 MVP 之後回到這一篇盤點。MVP 如果是用託管平台或 BaaS 做的，先用 <a href="/blog/backend/00-service-selection/delivery-mode-selection/" data-link-title="0.21 交付形態選型：從全託管到自建的光譜與邊界" data-link-desc="在進入資料庫、快取與部署選型之前、先判斷服務該用託管平台（Wix / Shopify / Google Sites）、辦公生態自動化（Apps Script）、BaaS（Firebase）、半託管 CMS（WordPress）還是自建、並為日後遷往自建保留可遷出路徑">0.21 交付形態選型：從全託管到自建的光譜與邊界</a> 的升級自建 tripwire 判斷該不該啟動自建評估；評估成立的話，遷出的執行在 <a href="/blog/backend/10-system-evolution/managed-platform-exit/" data-link-title="10.3 託管形態遷出：資產線盤點與並行期執行" data-link-desc="0.21 升級自建 tripwire 觸發後的執行劇本 — 把遷出拆成資料、身分、流量、整合各自的可攜性與斷點、設計舊平台與新系統的並行期與回切窗口、用部分遷出作為中繼形態">10.3 託管形態遷出：資產線盤點與並行期執行</a>，遷入之後再照下面的訊號走。</p>
<h2 id="各種架構撞到限制的訊號與要補的能力">各種架構撞到限制的訊號與要補的能力</h2>
<table>
  <thead>
      <tr>
          <th>架構撞到限制的訊號</th>
          <th>要補的能力</th>
          <th>對應章節</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>一臺機器的 CPU 或記憶體吃滿</td>
          <td>評估垂直或水平擴展，確認服務是 stateless</td>
          <td><a href="/blog/backend/09-performance-capacity/scaling-axes/" data-link-title="9.13 擴展軸與 Stateless 前提" data-link-desc="整理垂直 / 水平擴展取捨、stateless vs stateful 前提、auto scaling 操作模型與兩種擴展的 hidden cost">9.13 擴展軸與 Stateless 前提</a></td>
      </tr>
      <tr>
          <td>資料庫變慢，加機器看起來只是暫時止血</td>
          <td>先用查詢反模式清單收回單機容量，再考慮升級規格或換服務</td>
          <td><a href="/blog/backend/01-database/query-anti-patterns/" data-link-title="1.13 應用層查詢反模式與 Query 預算" data-link-desc="整理 N&#43;1、select *、缺索引、ORM lazy load、long transaction 等查詢反模式與每請求的 query 預算判讀">1.13 應用層查詢反模式與 Query 預算</a></td>
      </tr>
      <tr>
          <td>資料庫寫入正常，但讀取把主庫壓垮</td>
          <td>開 read replica，應用層配讀寫路由，並加快取</td>
          <td><a href="/blog/backend/01-database/high-concurrency-access/" data-link-title="1.1 高併發下的 SQL 讀寫邊界" data-link-desc="說明高併發服務如何共用資料庫 client、控制 transaction、管理 connection pool、避免資料庫成為瓶頸">1.1 高併發下的 SQL 讀寫邊界</a>、<a href="/blog/backend/02-cache-redis/cache-aside/" data-link-title="2.2 cache aside 與失效策略" data-link-desc="整理 read-through 思路、cache miss 與 invalidation">2.2 cache aside 與失效策略</a></td>
      </tr>
      <tr>
          <td>活動或引流時，源站被靜態資源請求打爆</td>
          <td>把靜態與半靜態內容放到邊緣層，保護源站</td>
          <td><a href="/blog/backend/05-deployment-platform/edge-cdn-static-distribution/" data-link-title="5.9 邊緣分發與靜態資源（CDN / Origin Protection）" data-link-desc="整理 CDN 與 edge cache 在部署平台中的責任邊界、origin protection、purge 與 invalidation 策略">5.9 邊緣分發與靜態資源（CDN / Origin Protection）</a></td>
      </tr>
      <tr>
          <td>同步呼叫卡住交易流程，付款與通知互相阻塞</td>
          <td>拆成事件、非同步化，加上冪等</td>
          <td><a href="/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">訊息佇列與事件傳遞模組</a></td>
      </tr>
      <tr>
          <td>業務分化，團隊之間的發版互相阻擋</td>
          <td>沿真實的邊界拆服務（資料、團隊、部署或流量）</td>
          <td><a href="/blog/backend/10-system-evolution/service-decomposition-boundaries/" data-link-title="10.1 服務拆分與邊界判讀" data-link-desc="整理 monolith vs microservice 取捨、服務邊界判讀訊號、拆分時機與回退路徑">10.1 服務拆分與邊界判讀</a></td>
      </tr>
  </tbody>
</table>
<p>表格由上往下大致是一個服務撞到這些訊號的常見先後，而先後不是固定的：有的團隊在單機容量用完之前就先拆服務，有的團隊一直不需要拆。源站被打爆之後如果還要應付可預期的活動高峰（雙 11、新片上線、推廣活動），加讀 <a href="/blog/backend/09-performance-capacity/peak-event-readiness/" data-link-title="9.11 高峰事件準備" data-link-desc="可預期峰值從 T-90 到 T-0 的準備時程：容量計畫、quota 申請、壓測、game day 與 pre-scaling 各排在事件前幾天、排在那裡的理由與項目之間的依賴，pre-scaling 的做法、watch room、event tier 分級與準備時間不夠時被壓縮的部分，以及事後 retro">9.11 高峰事件準備</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>。</p>
<h2 id="規模成長路線從頭讀的章節順序">規模成長路線從頭讀的章節順序</h2>
<p>要把整條路線從頭讀一次，順序是：<a href="/blog/backend/00-service-selection/delivery-mode-selection/" data-link-title="0.21 交付形態選型：從全託管到自建的光譜與邊界" data-link-desc="在進入資料庫、快取與部署選型之前、先判斷服務該用託管平台（Wix / Shopify / Google Sites）、辦公生態自動化（Apps Script）、BaaS（Firebase）、半託管 CMS（WordPress）還是自建、並為日後遷往自建保留可遷出路徑">0.21 交付形態選型：從全託管到自建的光譜與邊界</a>的升級 tripwire → <a href="/blog/backend/00-service-selection/backend-demand-taxonomy/" data-link-title="0.0 後端需求分類地圖" data-link-desc="先從需求形狀辨識狀態、讀取、非同步、即時、診斷、交付與可靠性問題">0.0 後端需求分類地圖</a> → <a href="/blog/backend/10-system-evolution/managed-platform-exit/" data-link-title="10.3 託管形態遷出：資產線盤點與並行期執行" data-link-desc="0.21 升級自建 tripwire 觸發後的執行劇本 — 把遷出拆成資料、身分、流量、整合各自的可攜性與斷點、設計舊平台與新系統的並行期與回切窗口、用部分遷出作為中繼形態">10.3 託管形態遷出：資產線盤點與並行期執行</a>（從託管平台出身的服務才需要）→ <a href="/blog/backend/10-system-evolution/service-decomposition-boundaries/" data-link-title="10.1 服務拆分與邊界判讀" data-link-desc="整理 monolith vs microservice 取捨、服務邊界判讀訊號、拆分時機與回退路徑">10.1 服務拆分與邊界判讀</a> → <a href="/blog/backend/09-performance-capacity/scaling-axes/" data-link-title="9.13 擴展軸與 Stateless 前提" data-link-desc="整理垂直 / 水平擴展取捨、stateless vs stateful 前提、auto scaling 操作模型與兩種擴展的 hidden cost">9.13 擴展軸與 Stateless 前提</a> → <a href="/blog/backend/01-database/query-anti-patterns/" data-link-title="1.13 應用層查詢反模式與 Query 預算" data-link-desc="整理 N&#43;1、select *、缺索引、ORM lazy load、long transaction 等查詢反模式與每請求的 query 預算判讀">1.13 應用層查詢反模式與 Query 預算</a> → <a href="/blog/backend/01-database/high-concurrency-access/" data-link-title="1.1 高併發下的 SQL 讀寫邊界" data-link-desc="說明高併發服務如何共用資料庫 client、控制 transaction、管理 connection pool、避免資料庫成為瓶頸">1.1 高併發下的 SQL 讀寫邊界</a> → <a href="/blog/backend/02-cache-redis/cache-aside/" data-link-title="2.2 cache aside 與失效策略" data-link-desc="整理 read-through 思路、cache miss 與 invalidation">2.2 cache aside 與失效策略</a> → <a href="/blog/backend/05-deployment-platform/edge-cdn-static-distribution/" data-link-title="5.9 邊緣分發與靜態資源（CDN / Origin Protection）" data-link-desc="整理 CDN 與 edge cache 在部署平台中的責任邊界、origin protection、purge 與 invalidation 策略">5.9 邊緣分發與靜態資源（CDN / Origin Protection）</a> → <a href="/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">訊息佇列與事件傳遞模組</a> → <a href="/blog/backend/09-performance-capacity/peak-event-readiness/" data-link-title="9.11 高峰事件準備" data-link-desc="可預期峰值從 T-90 到 T-0 的準備時程：容量計畫、quota 申請、壓測、game day 與 pre-scaling 各排在事件前幾天、排在那裡的理由與項目之間的依賴，pre-scaling 的做法、watch room、event tier 分級與準備時間不夠時被壓縮的部分，以及事後 retro">9.11 高峰事件準備</a>。</p>
<p>這個順序把判斷放在動手之前：先確認要不要自建、需求屬於哪一類、邊界在哪裡，再依擴展、查詢、讀取、邊緣、非同步、高峰的次序補能力。各篇結尾的「規模成長路線下一站」指的就是這個順序裡的下一篇。</p>
<h2 id="入門影片用詞與-backend-教材章節的對照">入門影片用詞與 Backend 教材章節的對照</h2>
<p>講 SaaS 擴展的入門影片常用生活比喻解釋這些概念（把快取說成保溫桶、把 CDN 說成物料配送）。比喻傳達的是形狀，操作時需要的是工程術語與判斷條件，下表把常見的影片用詞接到對應的章節：</p>
<table>
  <thead>
      <tr>
          <th>影片用詞</th>
          <th>對應章節</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Scale up / Scale out</td>
          <td><a href="/blog/backend/09-performance-capacity/scaling-axes/" data-link-title="9.13 擴展軸與 Stateless 前提" data-link-desc="整理垂直 / 水平擴展取捨、stateless vs stateful 前提、auto scaling 操作模型與兩種擴展的 hidden cost">9.13 擴展軸與 Stateless 前提</a></td>
      </tr>
      <tr>
          <td>CDN、邊緣節點、物料配送</td>
          <td><a href="/blog/backend/05-deployment-platform/edge-cdn-static-distribution/" data-link-title="5.9 邊緣分發與靜態資源（CDN / Origin Protection）" data-link-desc="整理 CDN 與 edge cache 在部署平台中的責任邊界、origin protection、purge 與 invalidation 策略">5.9 邊緣分發與靜態資源（CDN / Origin Protection）</a></td>
      </tr>
      <tr>
          <td>微服務、拆分</td>
          <td><a href="/blog/backend/10-system-evolution/service-decomposition-boundaries/" data-link-title="10.1 服務拆分與邊界判讀" data-link-desc="整理 monolith vs microservice 取捨、服務邊界判讀訊號、拆分時機與回退路徑">10.1 服務拆分與邊界判讀</a></td>
      </tr>
      <tr>
          <td>Read replica、主從複製</td>
          <td><a href="/blog/backend/01-database/high-concurrency-access/" data-link-title="1.1 高併發下的 SQL 讀寫邊界" data-link-desc="說明高併發服務如何共用資料庫 client、控制 transaction、管理 connection pool、避免資料庫成為瓶頸">1.1 高併發下的 SQL 讀寫邊界</a>，以及 <a href="/blog/backend/09-performance-capacity/scaling-axes/" data-link-title="9.13 擴展軸與 Stateless 前提" data-link-desc="整理垂直 / 水平擴展取捨、stateless vs stateful 前提、auto scaling 操作模型與兩種擴展的 hidden cost">9.13 擴展軸與 Stateless 前提</a>裡講有狀態服務的那一段</td>
      </tr>
      <tr>
          <td>快取、保溫桶</td>
          <td><a href="/blog/backend/02-cache-redis/" data-link-title="模組二：快取與 Redis" data-link-desc="整理快取策略、Redis 資料型別與分散式狀態輔助能力">快取與 Redis 模組</a></td>
      </tr>
      <tr>
          <td>Queue、Rate limiter</td>
          <td><a href="/blog/backend/03-message-queue/" data-link-title="模組三：訊息佇列與事件傳遞" data-link-desc="整理 durable queue、broker、retry、outbox 與 idempotency 的後端實務">訊息佇列與事件傳遞模組</a>、<a href="/blog/backend/09-performance-capacity/peak-event-readiness/" data-link-title="9.11 高峰事件準備" data-link-desc="可預期峰值從 T-90 到 T-0 的準備時程：容量計畫、quota 申請、壓測、game day 與 pre-scaling 各排在事件前幾天、排在那裡的理由與項目之間的依賴，pre-scaling 的做法、watch room、event tier 分級與準備時間不夠時被壓縮的部分，以及事後 retro">9.11 高峰事件準備</a></td>
      </tr>
      <tr>
          <td>索引、N+1、倉庫整理</td>
          <td><a href="/blog/backend/01-database/query-anti-patterns/" data-link-title="1.13 應用層查詢反模式與 Query 預算" data-link-desc="整理 N&#43;1、select *、缺索引、ORM lazy load、long transaction 等查詢反模式與每請求的 query 預算判讀">1.13 應用層查詢反模式與 Query 預算</a></td>
      </tr>
      <tr>
          <td>雲端服務（RDS / ECS / S3）</td>
          <td><a href="/blog/backend/00-service-selection/cloud-vendor-capability-mapping/" data-link-title="0.19 雲端服務對照地圖（AWS / GCP / Azure）" data-link-desc="把後端能力分類對照到 AWS / GCP / Azure 的具體服務名稱、保留跨雲遷移與選型差異的判讀重點">0.19 雲端服務對照地圖（AWS / GCP / Azure）</a></td>
      </tr>
  </tbody>
</table>
]]></content:encoded></item></channel></rss>