Community程式設計與開發github.com

bentoms-dev/postgres-migrations-engineer

設計 PostgreSQL 資料庫結構、撰寫零停機遷移並修復慢查詢。適用於新增資料表、欄位、索引或約束、在線上資料庫中變更資料、審查遷移的鎖定風險、解讀 EXPLAIN ANALYZE 輸出,或使用 Prisma、Drizzle、Knex、TypeORM、Rails 及 Django 遷移時。

postgres-migrations-engineer 是什麼?

此技能專為需要安全、零停機地管理 PostgreSQL 資料庫變更的開發者與 AI 代理(如 Claude Code、Cursor 或 Codex)所設計。它將資料視為不可取代的資產,強調每一項結構變更都必須在應用程式持續服務的同時安全執行。技能涵蓋三個核心領域:資料庫結構設計(例如選擇正確的主鍵類型、強制在資料庫層級驗證完整性)、零停機遷移策略(例如使用 CONCURRENTLY 建立索引、透過 NOT VALID 約束逐步新增外鍵、以及採用「展開與收縮」模式來安全地重新命名或刪除欄位)、以及查詢效能最佳化(例如解讀 EXPLAIN ANALYZE 輸出、建立適當的索引、避免 N+1 查詢)。此外,它還提供了並行性與正確性準則,例如使用交易與樂觀鎖定來避免遺失更新。輸出要求對於每一次遷移,明確陳述其變更內容、所取的鎖定類型與預期時間、與當前部署程式碼的相容性、復原計畫,以及後續所需的收縮遷移。這套技能文件是平台中立的,因此可以運用於任何支援 SQL 遷移的工具或 ORM。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/bentoms-dev/skills/tree/HEAD/skills/applications/postgres-migrations-engineer

Installed? Explore more 程式設計與開發 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

Postgres 與遷移工程師

您將生產資料視為不可取代。每一次結構變更都必須能在應用程式提供服務的同時安全執行,且每一個查詢都必須有支援它的索引。

資料庫結構設計

  • 主鍵:使用 bigint generated always as identity,或是在 ID 會暴露或用戶端產生時使用 UUID v7。在非常大且寫入量大的資料表上避免使用隨機的 UUID v4(索引碎片化)。
  • 使用正確的類型:timestamptz(絕不使用不帶時區的 timestamp)、numeric 或整數小單位來表示金額(絕不使用 float)、使用帶有長度 CHECK 的 text 而非 varchar(n),jsonb 僅用於真正無結構的資料。
  • 在資料庫中強制資料完整性,而不僅僅在應用程式中:NOT NULL、外部鍵、UNIQUE、CHECK 約束。在並行環境下,僅靠應用程式的驗證是不夠的。
  • 為 created_at 和 updated_at 加入預設值。審慎決定使用軟刪除或硬刪除;軟刪除需要部分唯一索引(WHERE deleted_at IS NULL)。
  • 明確命名約束和索引,以便遷移和錯誤訊息易於閱讀。

零停機遷移規則

大多數由遷移導致的停機都來自鎖定。一個等待 ACCESS EXCLUSIVE 鎖定的陳述式會阻塞其後的所有查詢。

  • 在遷移中務必設定 SET lock_timeout = '5s';(以及合理的 statement_timeout),以便快速失敗,而不是讓流量排隊等候。
  • 索引:使用 CREATE INDEX CONCURRENTLY(在交易外部)。使用 DROP INDEX CONCURRENTLY 刪除。
  • 新增欄位:可為空,或帶有常數預設值(自 Postgres 11 起快速)。在大型資料表上避免使用變動性預設值。
  • 對現有欄位設定 NOT NULL:新增 CHECK (col IS NOT NULL) NOT VALID,回填資料,VALIDATE CONSTRAINT,然後 SET NOT NULL(Postgres 12+ 會使用已驗證的檢查並跳過掃描)。
  • 外部鍵:使用 NOT VALID 新增,然後在單獨的步驟中 VALIDATE CONSTRAINT。
  • 變更欄位類型:不要在大型資料表上使用 ALTER TYPE。新增一個新欄位、雙重寫入、回填、切換讀取、刪除舊欄位。
  • 重新命名欄位或資料表:使用展開與收縮模式。新增新結構、雙重寫入、遷移讀取端,然後在後續部署中移除舊結構。
  • 刪除欄位:首先部署不再讀取或寫入該欄位的程式碼(並從 ORM 模型中移除),然後再刪除。
  • 回填:分批進行(例如,按主鍵範圍每次 1,000 到 10,000 筆資料列),每批在其自己的短交易中執行,冪等且可恢復,並進行限流。絕不使用一個巨大的 UPDATE。

展開與收縮

  1. 展開:新增向後相容於當前部署程式碼的新結構。
  2. 遷移:部署同時寫入兩者並讀取新結構的程式碼;回填資料。
  3. 收縮:一旦沒有任何東西使用舊結構,在後續版本中將其移除。

每一步都必須在部署被回滾時仍然安全。

查詢效能

  • 在逼真的資料量上執行 EXPLAIN (ANALYZE, BUFFERS)。尋找大型資料表上的循序掃描、10 倍或以上的資料列估算誤差、遍歷大量資料列的巢狀迴圈,以及溢出到磁碟的排序操作。
  • 為查詢建立索引:先放等值條件欄位,再放範圍或排序欄位。使用部分索引處理熱點子集,使用覆蓋索引(INCLUDE)以實現僅索引掃描。
  • 透過聯結或批次 WHERE id = ANY($1) 載入來消除 N+1 查詢。
  • 使用鍵集分頁(WHERE (created_at, id) < ($1, $2) ORDER BY created_at DESC, id DESC LIMIT 50)進行分頁,避免使用大型 OFFSET。
  • 每個索引都會減慢寫入速度並耗用記憶體;移除未使用的索引(pg_stat_user_indexes.idx_scan = 0)。
  • 使用 pg_stat_statements 來找出總耗時最長的查詢。

並行性與正確性

  • 將多步驟寫入包裝在交易中。使用 SELECT ... FOR UPDATE 或原子性的 UPDATE ... SET qty = qty - 1 WHERE qty > 0 來避免遺失更新。
  • 使用 INSERT ... ON CONFLICT 搭配唯一約束來實現冪等 upsert。
  • 始終使用參數化查詢。絕不將使用者輸入內插到 SQL 中。
  • 對於無伺服器和高並行性的應用程式,使用連線池(PgBouncer 或平台提供的)。

輸出

對於每一次遷移,請說明:其變更內容、它將對生產資料列數取得的鎖定類型與預期持續時間、它是否與當前部署的程式碼相容、復原計畫,以及任何後續需要的收縮遷移。


深入探討: Scale & Load Engineer 和 Stripe Billing Engineer 是高級技能包,內含相關技能、生產範本、腳本和評估提示。

Individual skills in this repo

This repo contains 5 individual skills — each has its own dedicated page.

bentoms-dev/ai-feature-engineer

Build reliable, safe and affordable LLM-powered features in real products. Use when adding chat, summarisation, extraction, classification, RAG search, tool calling or agents to an app, when writing prompts or evals, choosing models, controlling cost and latency, or defending against prompt injection.

bentoms-dev/docs-readme-writer

Write developer documentation people actually read and trust. Use when creating or improving a README, getting-started guide, API reference, architecture decision record (ADR), runbook, onboarding guide, changelog or contributing guide, or when docs are outdated, confusing or missing.

bentoms-dev/github-actions-cicd-engineer

Build fast, secure and maintainable CI/CD pipelines with GitHub Actions. Use when creating or fixing workflows, speeding up slow CI, adding caching, matrices or deployments, managing secrets and environments, hardening workflows against supply-chain attacks, or setting up releases and preview deployments.

bentoms-dev/shopify-theme-architect

Build, refactor and review Shopify Online Store 2.0 themes. Use when creating or editing Liquid sections, blocks, snippets, templates, theme settings, locales, or theme CSS/JS, and when reviewing a theme for performance, accessibility or merchant editability.

bentoms-dev/test-engineer

Write tests that catch real bugs and survive refactors. Use when adding tests to new or existing code, choosing between unit, integration and end-to-end tests, fixing flaky tests, setting up Vitest, Jest or Playwright, or reviewing a test suite for gaps and brittleness.

相關技能