database-designer
alirezarezvani/claude-skills
運用專業分析與自動化工具,設計資料庫結構、規劃資料遷移、優化查詢,並建模資料間的關聯性。
...展開全部資料庫設計師 — 精通多層架構技能
概述
一項全面性的資料庫設計技能,針對現代資料庫系統提供專家級的分析、優化與遷移能力。此技能結合理論原則與實用工具,協助架構師與開發人員建立可擴展、高效能且易於維護的資料庫模式。
核心能力
模式設計與分析
- 正規化分析:自動偵測正規化層級(從 1NF 到 BCNF)
- 去正規化策略:針對效能優化提供智慧型建議
- 資料類型優化:識別不當的資料類型與大小問題
- 約束分析:外鍵缺失、唯一性約束及空值檢查
- 命名規範驗證:確保資料表與欄位命名模式的一致性
- ERD 生成:根據 DDL 自動建立 Mermaid 圖表
索引優化
- 索引缺口分析:識別外鍵及查詢模式上缺失的索引
- 複合索引策略:針對多欄位索引的最佳欄位排序
- 索引冗餘檢測:消除重複及閒置索引
- 效能影響建模:選擇性估算與查詢成本分析
- 索引類型選取:B-樹、雜湊、部分、覆蓋及專用索引
遷移管理
- 零停機遷移:擴展-收縮模式的實作
- 模式演進:安全地新增、刪除欄位及變更資料型別
- 資料遷移腳本:自動化資料轉換與驗證
- 回滾策略:具備驗證功能的完整回滾能力
- 執行規劃:具備依賴關係解析的有序遷移步驟
工具工作流程(請執行以下步驟 — 切勿手動分析資料結構)
所有路徑皆以本技能資料夾為基準;範例輸入位於 assets/.
1. 分析模式
python3 schema_analyzer.py --input schema.sql --generate-erd --output-format json -o analysis.json
接受 SQL DDL 或 JSON 模式(assets/sample_schema.sql / sample_schema.json)。輸出內容包含正規化分析結果、缺失的約束條件、命名問題,以及一份 Mermaid ERD —— 請先向使用者展示 ERD 並修正標記出的問題,再進行優化。
2. 根據實際查詢模式優化索引
python3 index_optimizer.py --schema assets/sample_schema.json --queries assets/sample_query_patterns.json --analyze-existing --format json -o indexes.json
首先將使用者的熱門查詢寫入查詢模式 JSON 檔案中(複製 assets/sample_query_patterns.json)。輸出結果為按優先順序排列的 CREATE INDEX 建議清單,以及冗餘索引的移除建議。
3. 產生遷移方案
python3 migration_generator.py --current current_schema.json --target target_schema.json --zero-downtime --format sql -o migration.sql
--zero-downtime 會產生一個擴展-收縮計畫; --validate-only 在不產生 SQL 的情況下檢查可行性。
4. 驗證循環
在目標模式上重新執行步驟 1,並驗證首次執行時發現的問題已不復存在;執行 migration_generator.py --validate-only 後再移交遷移方案。
資料庫設計原則
→ 詳情請參閱 references/database-design-reference.md
最佳實務
模式設計
- 使用有意義的名稱:清晰且一致的命名規範
- 選擇適當的資料類型:為提升儲存效率,為欄位選擇合適的資料類型
- 定義適當的限制條件:外鍵、檢查限制、唯一索引
- 考量未來擴展需求:從一開始就規劃可擴展性
- 記錄關聯關係:明確的外鍵關聯與業務規則
效能優化
- 策略性地建立索引:涵蓋常見的查詢模式,同時避免過度建立索引
- 監控查詢效能:定期分析緩慢的查詢
- 將大型資料表進行分區:提升查詢效能與維護效率
- 使用適當的隔離級別:在一致性與效能之間取得平衡
- 實作連線池:有效利用資源
安全性考量
- 最小權限原則:僅授予最低必要的權限
- 加密敏感資料:無論是靜態儲存或傳輸中
- 稽核存取模式:監控並記錄資料庫存取
- 驗證輸入資料:防止 SQL 注入攻擊
- 定期進行安全性更新:保持資料庫軟體為最新版本
查詢生成模式
帶有 JOIN 的 SELECT 語句
-- INNER JOIN: only matching rows
SELECT o.id, c.name, o.total
FROM orders o
INNER JOIN customers c ON c.id = o.customer_id;
-- LEFT JOIN: all left rows, NULLs for non-matches
SELECT c.name, COUNT(o.id) AS order_count
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
GROUP BY c.name;
-- Self-join: hierarchical data (employees/managers)
SELECT e.name AS employee, m.name AS manager
FROM employees e
LEFT JOIN employees m ON m.id = e.manager_id;
共通表式 (CTE)
-- Recursive CTE for org chart
WITH RECURSIVE org AS (
SELECT id, name, manager_id, 1 AS depth
FROM employees WHERE manager_id IS NULL
UNION ALL
SELECT e.id, e.name, e.manager_id, o.depth + 1
FROM employees e INNER JOIN org o ON o.id = e.manager_id
)
SELECT * FROM org ORDER BY depth, name;
視窗函數
-- ROW_NUMBER for pagination / dedup
SELECT *, ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY created_at DESC) AS rn
FROM orders;
-- RANK with gaps, DENSE_RANK without gaps
SELECT name, score, RANK() OVER (ORDER BY score DESC) AS rank FROM leaderboard;
-- LAG/LEAD for comparing adjacent rows
SELECT date, revenue,
revenue - LAG(revenue) OVER (ORDER BY date) AS daily_change
FROM daily_sales;
彙總模式
-- FILTER clause (PostgreSQL) for conditional aggregation
SELECT
COUNT(*) AS total,
COUNT(*) FILTER (WHERE status = 'active') AS active,
AVG(amount) FILTER (WHERE amount > 0) AS avg_positive
FROM accounts;
-- GROUPING SETS for multi-level rollups
SELECT region, product, SUM(revenue)
FROM sales
GROUP BY GROUPING SETS ((region, product), (region), ());
遷移模式
向上/向下遷移腳本
每次遷移都必須有可逆的對應操作。為便於排序,請在檔案名稱前加上時間戳記前綴:
migrations/
├── 20260101_000001_create_users.up.sql
├── 20260101_000001_create_users.down.sql
├── 20260115_000002_add_users_email_index.up.sql
└── 20260115_000002_add_users_email_index.down.sql
零停機遷移(擴展/收縮)
使用擴展/縮減模式以避免鎖定或破壞正在執行的程式碼:
- 擴展 — 新增欄位/資料表(可為 null,並設定預設值)
- 資料遷移 — 分批回填;由應用程式進行雙重寫入
- 過渡 — 應用程式從新欄位讀取資料;停止寫入舊欄位
- 縮減 — 在後續遷移中刪除舊欄位
資料回填策略
-- Batch update to avoid long-running locks
UPDATE users SET email_normalized = LOWER(email)
WHERE id IN (SELECT id FROM users WHERE email_normalized IS NULL LIMIT 5000);
-- Repeat in a loop until 0 rows affected
回滾程序
- 務必在部署前
down.sql在預備環境中測試up.sql至生產環境前 - 請將回滾時間窗設定得盡可能短 — 若合約步驟已執行,則回滾需進行新的向前遷移
- 對於不可逆的變更(例如刪除含有資料的欄位),請先執行邏輯備份
效能優化
索引策略
| 索引類型 | 使用案例 | 範例 |
|---|---|---|
| B-樹(預設) | 等值、範圍、ORDER BY | CREATE INDEX idx_users_email ON users(email); |
| GIN | 全文搜尋、JSONB、陣列 | CREATE INDEX idx_docs_body ON docs USING gin(to_tsvector('english', body)); |
| GiST | 幾何、範圍型別、最近鄰 | CREATE INDEX idx_locations ON places USING gist(coords); |
| 部分 | 資料列子集(縮小規模) | CREATE INDEX idx_active ON users(email) WHERE active = true; |
| 覆蓋 | 僅索引掃描 | CREATE INDEX idx_cov ON orders(customer_id) INCLUDE (total, created_at); |
EXPLAIN 執行計畫解讀
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT) SELECT ...;
需注意的關鍵訊號:
- 對大型資料表進行順序掃描 — 缺少索引
- 嵌套迴圈且行數估計值過高 — 考慮使用雜湊/合併聯結或新增索引
- 共享緩衝區的讀取次數遠高於命中率 — 工作集超出記憶體容量
N+1 查詢偵測
症狀:應用程式針對每筆資料行發出一次查詢(例如,在迴圈中擷取相關記錄)。
解決方案:
- 使用
JOIN或子查詢以單次往返完成擷取 - ORM 預載(
select_related/includes/with) - GraphQL 解析器的 DataLoader 模式
連線池
| 工具 | 通訊協定 | 最適合 |
|---|---|---|
| PgBouncer | PostgreSQL | 事務/語句池化,低開銷 |
| ProxySQL | MySQL | 查詢路由、讀寫分離 |
| 內建池(HikariCP、SQLAlchemy 池) | 任意 | 應用程式層級的連接池 |
經驗法則:將池大小設定為 (2 * CPU cores) + disk spindles。對於雲端 SSD,建議從 2 * vCPUs ,並進行調整。
讀取副本與查詢路由
- 將所有
SELECT查詢路由至複本;寫入則路由至主節點 - 需考量複製延遲(非同步模式通常 <1 秒,同步模式為 0)
- 使用
pg_last_wal_replay_lsn()在讀取關鍵資料前檢測延遲
多資料庫決策矩陣
| 準則 | PostgreSQL | MySQL | SQLite | SQL Server |
|---|---|---|---|---|
| 最適合 | 複雜查詢、JSONB、擴充套件 | Web 應用程式、以讀取為主的工作負載 | 嵌入式、開發/測試、邊緣運算 | 企業級 .NET 技術堆疊 |
| JSON 支援 | 優異(JSONB + GIN) | 良好(JSON 類型) | 基本 | 良好(OPENJSON) |
| 複製 | 串流、邏輯 | 群組複製,InnoDB 叢集 | 不適用 | Always On AG |
| 授權 | 開源(PostgreSQL 授權) | 開源(GPL)/商用 | 公有領域 | 商業版 |
| 最大實際容量 | 數 TB | 數 TB | 約 1 TB(單一寫入者) | 數 TB |
何時選擇:
- PostgreSQL — 新專案的首選;具備最佳的可擴展性與標準遵循性
- MySQL — 現有的 MySQL 生態系統;適用於簡單的讀取密集型網頁應用程式
- SQLite — 行動應用程式、命令列工具、單元測試資料庫、物聯網/邊緣運算
- SQL Server — 受企業政策規範;與 .NET/Azure 深度整合
NoSQL 考量事項
| 資料庫 | 模型 | 適用情境 |
|---|---|---|
| MongoDB | 文件 | 模式靈活性、快速原型開發、內容管理 |
| Redis | 鍵值對/快取 | 會話儲存、速率限制、排行榜、發佈/訂閱 |
| DynamoDB | 寬欄位 | 無伺服器 AWS 應用程式,無論規模大小皆可實現個位數毫秒的延遲 |
預設使用 SQL。僅當存取模式能明顯從 NoSQL 中獲益時,才採用 NoSQL。
分片與複製
水平分區與垂直分區
- 垂直分區:將欄位拆分至不同資料表(例如,將 BLOB 欄位分開存放)。可減少窄範圍查詢的 I/O 負載。
- 水平分區(分片):將資料列分散至不同資料庫/伺服器。當單一節點無法容納資料集或處理所需吞吐量時,必須採用此方式。
分片策略
| 策略 | 運作原理 | 優點 | 缺點 |
|---|---|---|---|
| 雜湊 | shard = hash(key) % N |
均勻分配 | 重新分片成本高 |
| 範圍 | 依日期或 ID 範圍進行分片 | 簡單,適用於時間序列 | 最新分片上出現熱點 |
| 地理 | 依使用者地區進行分片 | 資料本地化、合規性 | 跨區域查詢較為困難 |
複製模式
| 模式 | 一致性 | 延遲 | 用例 |
|---|---|---|---|
| 同步 | 強 | 較高的寫入延遲 | 金融交易 |
| 非同步 | 最終 | 低寫入延遲 | 以讀取為主的網頁應用程式 |
| 半同步 | 至少一個副本已確認 | 中等 | 安全性與速度的平衡 |
相關參考
- sql-database-assistant — 適用於日常 SQL 工作的查詢編寫、優化與除錯
- database-schema-designer — 實體關係圖(ERD)建模、正規化分析及資料庫架構生成
- migration-architect — 跨資料庫引擎的大規模遷移規劃或主要架構全面改造
- 資深後端工程師 — 應用層模式(連線池、ORM 最佳實務)
- 資深 DevOps — 資料庫叢集與複本的基礎架構配置
---
name: database-designer
description: Design database schemas, plan data migrations, optimize queries, and model data relationships using expert analysis and automated tools.
---
# Database Designer - POWERFUL Tier Skill
## Overview
A comprehensive database design skill that provides expert-level analysis, optimization, and migration capabilities for modern database systems. This skill combines theoretical principles with practical tools to help architects and developers create scalable, performant, and maintainable database schemas.
## Core Competencies
### Schema Design & Analysis
- **Normalization Analysis**: Automated detection of normalization levels (1NF through BCNF)
- **Denormalization Strategy**: Smart recommendations for performance optimization
- **Data Type Optimization**: Identification of inappropriate types and size issues
- **Constraint Analysis**: Missing foreign keys, unique constraints, and null checks
- **Naming Convention Validation**: Consistent table and column naming patterns
- **ERD Generation**: Automatic Mermaid diagram creation from DDL
### Index Optimization
- **Index Gap Analysis**: Identification of missing indexes on foreign keys and query patterns
- **Composite Index Strategy**: Optimal column ordering for multi-column indexes
- **Index Redundancy Detection**: Elimination of overlapping and unused indexes
- **Performance Impact Modeling**: Selectivity estimation and query cost analysis
- **Index Type Selection**: B-tree, hash, partial, covering, and specialized indexes
### Migration Management
- **Zero-Downtime Migrations**: Expand-contract pattern implementation
- **Schema Evolution**: Safe column additions, deletions, and type changes
- **Data Migration Scripts**: Automated data transformation and validation
- **Rollback Strategy**: Complete reversal capabilities with validation
- **Execution Planning**: Ordered migration steps with dependency resolution
## Tool Workflow (run these — do not analyze schemas by hand)
All paths relative to this skill folder; sample inputs in `assets/`.
### 1. Analyze the schema
```bash
python3 schema_analyzer.py --input schema.sql --generate-erd --output-format json -o analysis.json
```
Accepts SQL DDL or JSON schema (`assets/sample_schema.sql` / `sample_schema.json`). Output includes normalization findings, missing constraints, naming issues, and a Mermaid ERD — show the ERD to the user and fix flagged issues before optimizing.
### 2. Optimize indexes against real query patterns
```bash
python3 index_optimizer.py --schema assets/sample_schema.json --queries assets/sample_query_patterns.json --analyze-existing --format json -o indexes.json
```
Write the user's hot queries into a query-patterns JSON first (copy `assets/sample_query_patterns.json`). Output is a priority-ordered list of CREATE INDEX recommendations plus redundant-index removals.
### 3. Generate the migration
```bash
python3 migration_generator.py --current current_schema.json --target target_schema.json --zero-downtime --format sql -o migration.sql
```
`--zero-downtime` emits an expand-contract plan; `--validate-only` checks feasibility without generating SQL.
### 4. Verification loop
Re-run step 1 on the *target* schema and assert the issues found in the first pass are gone; run `migration_generator.py --validate-only` before handing over the migration.
## Database Design Principles
→ See references/database-design-reference.md for details
## Best Practices
### Schema Design
1. **Use meaningful names**: Clear, consistent naming conventions
2. **Choose appropriate data types**: Right-sized columns for storage efficiency
3. **Define proper constraints**: Foreign keys, check constraints, unique indexes
4. **Consider future growth**: Plan for scale from the beginning
5. **Document relationships**: Clear foreign key relationships and business rules
### Performance Optimization
1. **Index strategically**: Cover common query patterns without over-indexing
2. **Monitor query performance**: Regular analysis of slow queries
3. **Partition large tables**: Improve query performance and maintenance
4. **Use appropriate isolation levels**: Balance consistency with performance
5. **Implement connection pooling**: Efficient resource utilization
### Security Considerations
1. **Principle of least privilege**: Grant minimal necessary permissions
2. **Encrypt sensitive data**: At rest and in transit
3. **Audit access patterns**: Monitor and log database access
4. **Validate inputs**: Prevent SQL injection attacks
5. **Regular security updates**: Keep database software current
## Query Generation Patterns
### SELECT with JOINs
```sql
-- INNER JOIN: only matching rows
SELECT o.id, c.name, o.total
FROM orders o
INNER JOIN customers c ON c.id = o.customer_id;
-- LEFT JOIN: all left rows, NULLs for non-matches
SELECT c.name, COUNT(o.id) AS order_count
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
GROUP BY c.name;
-- Self-join: hierarchical data (employees/managers)
SELECT e.name AS employee, m.name AS manager
FROM employees e
LEFT JOIN employees m ON m.id = e.manager_id;
```
### Common Table Expressions (CTEs)
```sql
-- Recursive CTE for org chart
WITH RECURSIVE org AS (
SELECT id, name, manager_id, 1 AS depth
FROM employees WHERE manager_id IS NULL
UNION ALL
SELECT e.id, e.name, e.manager_id, o.depth + 1
FROM employees e INNER JOIN org o ON o.id = e.manager_id
)
SELECT * FROM org ORDER BY depth, name;
```
### Window Functions
```sql
-- ROW_NUMBER for pagination / dedup
SELECT *, ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY created_at DESC) AS rn
FROM orders;
-- RANK with gaps, DENSE_RANK without gaps
SELECT name, score, RANK() OVER (ORDER BY score DESC) AS rank FROM leaderboard;
-- LAG/LEAD for comparing adjacent rows
SELECT date, revenue,
revenue - LAG(revenue) OVER (ORDER BY date) AS daily_change
FROM daily_sales;
```
### Aggregation Patterns
```sql
-- FILTER clause (PostgreSQL) for conditional aggregation
SELECT
COUNT(*) AS total,
COUNT(*) FILTER (WHERE status = 'active') AS active,
AVG(amount) FILTER (WHERE amount > 0) AS avg_positive
FROM accounts;
-- GROUPING SETS for multi-level rollups
SELECT region, product, SUM(revenue)
FROM sales
GROUP BY GROUPING SETS ((region, product), (region), ());
```
---
## Migration Patterns
### Up/Down Migration Scripts
Every migration must have a reversible counterpart. Name files with a timestamp prefix for ordering:
```
migrations/
├── 20260101_000001_create_users.up.sql
├── 20260101_000001_create_users.down.sql
├── 20260115_000002_add_users_email_index.up.sql
└── 20260115_000002_add_users_email_index.down.sql
```
### Zero-Downtime Migrations (Expand/Contract)
Use the expand-contract pattern to avoid locking or breaking running code:
1. **Expand** — add the new column/table (nullable, with default)
2. **Migrate data** — backfill in batches; dual-write from application
3. **Transition** — application reads from new column; stop writing to old
4. **Contract** — drop old column in a follow-up migration
### Data Backfill Strategies
```sql
-- Batch update to avoid long-running locks
UPDATE users SET email_normalized = LOWER(email)
WHERE id IN (SELECT id FROM users WHERE email_normalized IS NULL LIMIT 5000);
-- Repeat in a loop until 0 rows affected
```
### Rollback Procedures
- Always test the `down.sql` in staging before deploying `up.sql` to production
- Keep rollback window short — if the contract step has run, rollback requires a new forward migration
- For irreversible changes (dropping columns with data), take a logical backup first
---
## Performance Optimization
### Indexing Strategies
| Index Type | Use Case | Example |
|------------|----------|---------|
| **B-tree** (default) | Equality, range, ORDER BY | `CREATE INDEX idx_users_email ON users(email);` |
| **GIN** | Full-text search, JSONB, arrays | `CREATE INDEX idx_docs_body ON docs USING gin(to_tsvector('english', body));` |
| **GiST** | Geometry, range types, nearest-neighbor | `CREATE INDEX idx_locations ON places USING gist(coords);` |
| **Partial** | Subset of rows (reduce size) | `CREATE INDEX idx_active ON users(email) WHERE active = true;` |
| **Covering** | Index-only scans | `CREATE INDEX idx_cov ON orders(customer_id) INCLUDE (total, created_at);` |
### EXPLAIN Plan Reading
```sql
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT) SELECT ...;
```
Key signals to watch:
- **Seq Scan** on large tables — missing index
- **Nested Loop** with high row estimates — consider hash/merge join or add index
- **Buffers shared read** much higher than **hit** — working set exceeds memory
### N+1 Query Detection
Symptoms: application issues one query per row (e.g., fetching related records in a loop).
Fixes:
- Use `JOIN` or subquery to fetch in one round-trip
- ORM eager loading (`select_related` / `includes` / `with`)
- DataLoader pattern for GraphQL resolvers
### Connection Pooling
| Tool | Protocol | Best For |
|------|----------|----------|
| **PgBouncer** | PostgreSQL | Transaction/statement pooling, low overhead |
| **ProxySQL** | MySQL | Query routing, read/write splitting |
| **Built-in pool** (HikariCP, SQLAlchemy pool) | Any | Application-level pooling |
**Rule of thumb:** Set pool size to `(2 * CPU cores) + disk spindles`. For cloud SSDs, start with `2 * vCPUs` and tune.
### Read Replicas and Query Routing
- Route all `SELECT` queries to replicas; writes to primary
- Account for replication lag (typically <1s for async, 0 for sync)
- Use `pg_last_wal_replay_lsn()` to detect lag before reading critical data
---
## Multi-Database Decision Matrix
| Criteria | PostgreSQL | MySQL | SQLite | SQL Server |
|----------|-----------|-------|--------|------------|
| **Best for** | Complex queries, JSONB, extensions | Web apps, read-heavy workloads | Embedded, dev/test, edge | Enterprise .NET stacks |
| **JSON support** | Excellent (JSONB + GIN) | Good (JSON type) | Minimal | Good (OPENJSON) |
| **Replication** | Streaming, logical | Group replication, InnoDB cluster | N/A | Always On AG |
| **Licensing** | Open source (PostgreSQL License) | Open source (GPL) / commercial | Public domain | Commercial |
| **Max practical size** | Multi-TB | Multi-TB | ~1 TB (single-writer) | Multi-TB |
**When to choose:**
- **PostgreSQL** — default choice for new projects; best extensibility and standards compliance
- **MySQL** — existing MySQL ecosystem; simple read-heavy web applications
- **SQLite** — mobile apps, CLI tools, unit test databases, IoT/edge
- **SQL Server** — mandated by enterprise policy; deep .NET/Azure integration
### NoSQL Considerations
| Database | Model | Use When |
|----------|-------|----------|
| **MongoDB** | Document | Schema flexibility, rapid prototyping, content management |
| **Redis** | Key-value / cache | Session store, rate limiting, leaderboards, pub/sub |
| **DynamoDB** | Wide-column | Serverless AWS apps, single-digit-ms latency at any scale |
> Use SQL as default. Reach for NoSQL only when the access pattern clearly benefits from it.
---
## Sharding & Replication
### Horizontal vs Vertical Partitioning
- **Vertical partitioning**: Split columns across tables (e.g., separate BLOB columns). Reduces I/O for narrow queries.
- **Horizontal partitioning (sharding)**: Split rows across databases/servers. Required when a single node cannot hold the dataset or handle the throughput.
### Sharding Strategies
| Strategy | How It Works | Pros | Cons |
|----------|-------------|------|------|
| **Hash** | `shard = hash(key) % N` | Even distribution | Resharding is expensive |
| **Range** | Shard by date or ID range | Simple, good for time-series | Hot spots on latest shard |
| **Geographic** | Shard by user region | Data locality, compliance | Cross-region queries are hard |
### Replication Patterns
| Pattern | Consistency | Latency | Use Case |
|---------|------------|---------|----------|
| **Synchronous** | Strong | Higher write latency | Financial transactions |
| **Asynchronous** | Eventual | Low write latency | Read-heavy web apps |
| **Semi-synchronous** | At-least-one replica confirmed | Moderate | Balance of safety and speed |
---
## Cross-References
- **sql-database-assistant** — query writing, optimization, and debugging for day-to-day SQL work
- **database-schema-designer** — ERD modeling, normalization analysis, and schema generation
- **migration-architect** — large-scale migration planning across database engines or major schema overhauls
- **senior-backend** — application-layer patterns (connection pooling, ORM best practices)
- **senior-devops** — infrastructure provisioning for database clusters and replicas





首頁
