# 数据库开发规范 - CODING-STANDARDS-DATABASE

**版本**: 2.0.0
**适用范围**: 数据库开发岗位（SQL/NoSQL/图数据库/时序数据库，技术栈无关）
**最后更新**: 2025-12-25

---

## 🚨 核心铁律（继承自 common.md）

> **必须遵循 common.md 的四大核心铁律**

```
铁律1: SPEC 是唯一真源（SSOT）
       - 数据模型必须符合 SPEC 定义
       - 表结构、索引、约束以 SPEC 为准

铁律2: 智能复用与销毁重建
       - 现有表结构完全匹配 → 直接复用
       - 部分匹配 → 迁移脚本重建

铁律3: 禁止渐进式开发
       - 禁止保留旧字段，添加新字段
       - 禁止兼容性视图和触发器

铁律4: Context7 调研先行
       - 数据库设计参考最佳实践
       - 使用成熟的 ORM 和查询模式
```

---

## 🗄️ 数据建模

### 设计原则
- ✅ 符合业务领域模型
- ✅ 明确实体关系和约束
- ✅ 根据访问模式设计（读多/写多/读写平衡）
- ✅ 避免过度范式化或反范式化
- ❌ 禁止使用业务数据作为主键

### 命名规范
- ✅ 表名/集合名：复数名词（users, orders）
- ✅ 列名/字段名：单数名词（user_id, created_at）
- ✅ 索引命名：idx_[表名]_[列名]
- ✅ 外键命名：fk_[表名]_[引用表名]
- ❌ 避免保留字和特殊字符

### 数据类型
- ✅ 使用最小满足需求的数据类型
- ✅ 字符串长度明确限制
- ✅ 时间使用UTC存储
- ✅ 金额使用定点数或整数（避免浮点数）
- ❌ 禁止滥用TEXT/BLOB类型

---

## 🔐 数据完整性

### 约束设置
- ✅ 主键约束：每个表必须有主键
- ✅ 非空约束：必填字段明确标注
- ✅ 唯一约束：业务唯一性通过索引保证
- ✅ 外键约束：关联关系明确定义
- ✅ 检查约束：业务规则在数据库层验证

### 默认值和计算字段
- ✅ 合理设置默认值（created_at默认当前时间）
- ✅ 状态字段有明确初始值
- ✅ 计算字段考虑存储vs实时计算权衡
- ❌ 避免NULL值的歧义（用默认值或Optional类型）

---

## 📊 查询优化

### 查询设计
- ✅ 明确查询意图，避免SELECT *
- ✅ 使用参数化查询（防止SQL注入）
- ✅ 复杂查询分解为多步执行
- ✅ 避免N+1查询问题
- ✅ 使用EXPLAIN分析执行计划
- ❌ 禁止在WHERE子句中对列进行函数运算

### 索引策略
- ✅ 高频查询字段建立索引
- ✅ 联合索引遵循最左前缀原则
- ✅ 覆盖索引优化查询性能
- ✅ 定期监控索引使用情况
- ✅ 删除未使用的索引
- ❌ 避免过度索引（影响写入性能）

### 分页和限制
- ✅ 大数据集必须分页
- ✅ 使用游标分页而非OFFSET（大偏移量）
- ✅ 限制单次查询返回行数（< 10000行）
- ✅ 聚合查询考虑时间范围限制

---

## ⚡ 事务管理

### 事务原则
- ✅ 明确事务边界（ACID要求）
- ✅ 事务尽可能短（减少锁持有时间）
- ✅ 避免事务中执行外部IO操作
- ✅ 使用适当的隔离级别
- ✅ 显式提交或回滚

### 并发控制
- ✅ 理解并发问题（脏读、不可重复读、幻读）
- ✅ 使用乐观锁或悲观锁
- ✅ 避免死锁（按相同顺序访问资源）
- ✅ 设置事务超时时间
- ❌ 避免长时间持有锁

---

## 🔄 数据迁移

### 迁移规范
- ✅ 所有schema变更通过迁移脚本
- ✅ 迁移脚本可重复执行（幂等性）
- ✅ 向后兼容的变更策略
- ✅ 大表变更分批执行
- ✅ 迁移前备份数据
- ❌ 禁止手动修改生产数据库schema

### 版本控制
- ✅ 迁移文件按时间戳或版本号命名
- ✅ 记录迁移历史
- ✅ 提供回滚脚本
- ✅ 在测试环境验证迁移
- ❌ 禁止修改已执行的迁移脚本

---

## 🛡️ 数据安全

### 访问控制
- ✅ 最小权限原则
- ✅ 应用账号只有必要权限（禁止root连接）
- ✅ 敏感数据加密存储
- ✅ 定期审计数据库访问日志
- ❌ 禁止在代码中硬编码数据库凭证

### SQL注入防护
- ✅ 100%使用参数化查询/预编译语句
- ✅ 验证和清理用户输入
- ✅ 限制数据库错误信息暴露
- ❌ 禁止字符串拼接SQL

### 数据脱敏
- ✅ 敏感字段（手机、邮箱、身份证）脱敏显示
- ✅ 日志中不记录敏感数据
- ✅ 测试环境使用脱敏数据
- ❌ 禁止明文存储密码

---

## 📈 性能和监控

### 性能优化
- ✅ 监控慢查询日志
- ✅ 定期分析表统计信息
- ✅ 合理使用连接池
- ✅ 缓存热点数据
- ✅ 读写分离（读多场景）
- ✅ 分库分表（超大规模数据）

### 容量规划
- ✅ 监控数据增长趋势
- ✅ 定期清理历史数据
- ✅ 归档冷数据
- ✅ 设置表大小告警
- ✅ 预留存储空间

---

## 💾 备份和恢复

### 备份策略
- ✅ 定期全量备份
- ✅ 增量备份（高频变更场景）
- ✅ 验证备份可恢复性
- ✅ 异地备份存储
- ✅ 记录备份时间点

### 灾难恢复
- ✅ 制定恢复时间目标（RTO）
- ✅ 制定恢复点目标（RPO）
- ✅ 定期演练恢复流程
- ✅ 主从复制/集群高可用
- ✅ 监控复制延迟

---

## 🧪 数据库测试

### 测试范围
- ✅ 迁移脚本测试
- ✅ 查询性能测试
- ✅ 并发压力测试
- ✅ 数据完整性测试
- ✅ 备份恢复测试

### 测试数据
- ✅ 使用独立的测试数据库
- ✅ 模拟生产数据量级
- ✅ 测试边界条件（空值、极值）
- ❌ 禁止在生产数据库上测试

---

## 📋 数据库开发检查清单

- [ ] 数据模型符合业务领域
- [ ] 主键、索引、约束完整
- [ ] 查询使用参数化（防SQL注入）
- [ ] 索引覆盖高频查询
- [ ] 事务边界明确且简短
- [ ] 迁移脚本幂等且可回滚
- [ ] 敏感数据加密和脱敏
- [ ] 慢查询监控和优化
- [ ] 备份策略和恢复验证
- [ ] 迁移和查询有测试覆盖

---

---

## 🏛️ 高级架构模式（20+年经验）

### 分布式数据库架构
```
分片策略（Sharding）：
- 水平分片：按用户ID/时间范围
- 垂直分片：按业务模块
- 一致性哈希：动态扩缩容
- 分片键选择：高基数、均匀分布、查询频繁

读写分离架构：
- 主从复制（异步/半同步/同步）
- 读请求负载均衡
- 写后读一致性保证
- 故障自动切换

多活架构：
- 双主复制（冲突解决）
- 分区容错（CAP权衡）
- 就近访问（地理分布）
- 数据同步延迟监控
```

### NewSQL 与分布式事务
```
分布式事务模式：
- 2PC（两阶段提交）：强一致性，性能差
- TCC（Try-Confirm-Cancel）：最终一致性
- Saga 模式：长事务编排
- 本地消息表：可靠消息传递

NewSQL 选型：
- TiDB：MySQL兼容，水平扩展
- CockroachDB：PostgreSQL兼容，强一致
- YugabyteDB：多模型支持
- 适用场景：OLTP + 分布式
```

### 多模型数据库设计
```
关系型（RDBMS）：
- 适用：事务处理、强一致性需求
- 代表：PostgreSQL、MySQL

文档型（Document）：
- 适用：灵活Schema、嵌套数据
- 代表：MongoDB、Couchbase

时序型（Time-Series）：
- 适用：监控、IoT、金融行情
- 代表：TimescaleDB、InfluxDB

图数据库（Graph）：
- 适用：社交网络、知识图谱
- 代表：Neo4j、Amazon Neptune

向量数据库（Vector）：
- 适用：AI检索、相似度搜索
- 代表：Pinecone、Milvus、pgvector
```

---

## 🔧 资深开发者必备技巧

### 查询优化深度技巧
```
执行计划分析：
- EXPLAIN ANALYZE 实际执行统计
- 识别 Seq Scan vs Index Scan
- 识别 Nested Loop vs Hash Join
- 评估 Rows 估计准确性

索引高级策略：
- 部分索引（WHERE条件）
- 表达式索引（函数索引）
- 覆盖索引（Include列）
- 条件索引（过滤索引）

查询重写技巧：
- CTE 递归查询优化
- 窗口函数替代自连接
- EXISTS 替代 IN（子查询）
- LATERAL JOIN 高级用法
```

### 高并发场景优化
```
锁优化：
- 行级锁 vs 表级锁
- 乐观锁（版本号）vs 悲观锁
- 避免锁升级
- 死锁检测和预防

连接池调优：
- 池大小 = (核心数 * 2) + 磁盘数
- 连接生命周期管理
- 预热策略
- 监控空闲连接

批量操作优化：
- 批量INSERT（Bulk Insert）
- COPY 命令（PostgreSQL）
- 分批处理大事务
- 延迟索引更新
```

### 数据归档与冷热分离
```
分层存储策略：
- 热数据：SSD，高频访问
- 温数据：HDD，定期访问
- 冷数据：对象存储，归档查询

归档方案：
- 时间分区（按月/季度）
- 自动归档触发器
- 归档表压缩
- 归档数据可查询

表分区：
- Range分区（时间）
- List分区（枚举值）
- Hash分区（均匀分布）
- 分区裁剪（Partition Pruning）
```

### 高可用与容灾
```
复制拓扑：
- 级联复制（减少主库压力）
- 环形复制（多数据中心）
- 延迟复制（误操作恢复）

故障切换：
- 自动Failover（Patroni/Orchestrator）
- VIP漂移
- DNS切换
- 应用层路由

RPO/RTO 设计：
- RPO=0：同步复制（性能牺牲）
- RPO<1min：半同步复制
- RTO<30s：自动故障切换
```

---

## 🚨 资深开发者常见陷阱

### 设计陷阱
```
❌ 过度范式化：
- 所有数据都拆成独立表
- 查询需要多表JOIN
- 正确做法：根据访问模式适度反范式

❌ 滥用 JSON/JSONB 字段：
- 把关系型数据存为JSON
- 失去约束和索引优势
- 正确做法：JSON用于真正灵活的数据

❌ 忽视数据增长：
- 设计时只考虑当前数据量
- 表膨胀后查询变慢
- 正确做法：容量规划，预留分区
```

### 性能陷阱
```
❌ SELECT * 惯性：
- 查询所有列
- 无法使用覆盖索引
- 正确做法：明确指定需要的列

❌ ORM 滥用：
- N+1 查询问题
- 过度抽象隐藏低效查询
- 正确做法：监控ORM生成的SQL

❌ 索引过度：
- 每个列都建索引
- 写入性能严重下降
- 正确做法：根据查询模式建索引
```

### 运维陷阱
```
❌ 大表DDL不评估：
- 直接 ALTER TABLE 大表
- 长时间锁表
- 正确做法：在线DDL工具（pt-osc/gh-ost）

❌ 备份不验证：
- 有备份但从未恢复测试
- 真正需要时发现备份损坏
- 正确做法：定期恢复演练

❌ 忽视复制延迟：
- 读从库不考虑延迟
- 数据不一致
- 正确做法：监控延迟，关键读走主库
```

---

## 📊 性能监控指标

| 指标 | 目标值 | 告警阈值 | 测量工具 |
|------|--------|----------|----------|
| 查询响应时间（P99） | < 100ms | > 500ms | APM/慢查询日志 |
| QPS | 根据场景 | > 80%容量 | 监控系统 |
| 连接使用率 | < 70% | > 90% | 连接池监控 |
| 缓存命中率 | > 95% | < 80% | 数据库统计 |
| 复制延迟 | < 1s | > 10s | 复制监控 |
| 死锁频率 | 0 | > 1/小时 | 数据库日志 |
| 磁盘使用率 | < 70% | > 85% | 系统监控 |
| IOPS | 根据存储 | > 80%容量 | IO监控 |
| 长事务 | 0 | > 5分钟 | 事务监控 |
| 索引膨胀 | < 20% | > 50% | pg_stat_user_indexes |

---

## 📋 数据库开发检查清单（完整版）

### 设计检查
- [ ] 数据模型符合业务领域
- [ ] 分区/分片策略明确
- [ ] 主键、索引、约束完整
- [ ] 考虑未来数据增长

### 查询检查
- [ ] 所有查询使用参数化
- [ ] 执行计划已分析
- [ ] 无N+1查询问题
- [ ] 高频查询有索引覆盖

### 事务检查
- [ ] 事务边界明确且简短
- [ ] 并发控制策略明确
- [ ] 无长事务

### 运维检查
- [ ] 迁移脚本幂等且可回滚
- [ ] 备份策略和恢复已验证
- [ ] 监控和告警已配置
- [ ] 高可用方案已测试

---

**数据库开发原则总结**：
数据完整性、查询优化、事务ACID、安全防护、性能监控、备份恢复、迁移版本控制、最小权限、参数化查询、容量规划
