# Database 重要决策记录

**版本：** 3.0  
**最后更新**: 2026-01-17

---

本文档记录了 Database 模块的重要架构设计决策，包括问题背景、可选方案、决策理由和影响。

---

## 决策 1：支持多数据库

**日期**：2025-12-19  
**状态**：已实施

### 痛点

不同环境和场景需要不同的数据库：
- 开发环境：需要轻量级数据库，便于本地开发
- 生产环境：需要高性能数据库，支持多进程并发读
- 迁移需求：不同项目可能使用不同的数据库，需要方便迁移

### 可选方案

**方案 A：只支持单一数据库（如 PostgreSQL）**
- 优点：实现简单，无需适配
- 缺点：开发环境配置复杂，迁移困难

**方案 B：支持多种数据库（PostgreSQL、MySQL、SQLite）** ✅
- 优点：开箱即用方便，支持专业数据库操作，语法近似便于迁移
- 缺点：需要实现适配器，代码稍复杂

### 为什么选择当前方案

选择方案 B 的理由：
1. **开箱即用方便**：SQLite 便于本地开发，无需配置数据库服务器
2. **专业数据库操作**：PostgreSQL/MySQL 支持生产环境的高性能需求
3. **语法近似便于迁移**：PostgreSQL、MySQL、SQLite 的 SQL 语法相似，便于在不同数据库间迁移

### 影响

- 通过适配器模式统一不同数据库的接口
- 支持 PostgreSQL、MySQL、SQLite 三种数据库
- 业务代码无需关心底层数据库类型，可以轻松切换

---

## 决策 2：定义 Field 类型系统

**日期**：2025-12-19  
**状态**：已实施

### 痛点

如果直接使用原始 SQL 类型定义字段，会导致：
- 类型不统一：不同数据库的类型名称不同（如 PostgreSQL 的 `VARCHAR` vs MySQL 的 `TEXT`）
- 难以验证：无法在定义阶段验证字段类型是否被数据库支持
- 迁移困难：切换数据库时需要手动修改所有字段类型定义
- 缺乏抽象：无法统一处理字段的默认值、约束等

### 可选方案

**方案 A：直接使用原始 SQL 类型**
- 优点：实现简单，直接使用数据库原生类型
- 缺点：类型不统一，难以验证，迁移困难

**方案 B：定义 Field 类型系统** ✅
- 优点：类型统一，易于验证，便于迁移，支持多数据库适配
- 缺点：需要实现 Field 类体系

### 为什么选择当前方案

选择方案 B 的理由：
1. **类型统一**：通过 Field 类抽象，统一不同数据库的类型差异
2. **易于验证**：Field 类可以检查数据库是否支持该类型
3. **便于迁移**：切换数据库时，Field 类自动生成对应的 SQL 类型
4. **支持多数据库适配**：每个 Field 类可以根据数据库类型生成对应的 SQL

### 影响

- 所有字段类型都通过 Field 类定义（StringField、IntField、DateField 等）
- Schema 定义更清晰，易于理解和维护
- 支持多数据库自动适配，切换数据库无需修改 Schema

---

## 决策 3：使用适配器模式而不是 ORM

**日期**：2025-12-19  
**状态**：已实施

### 痛点

如果使用 ORM（如 SQLAlchemy），会导致：
- 性能开销：ORM 的抽象层会增加性能开销
- 学习成本：需要学习 ORM 的 API 和概念
- 灵活性受限：难以优化特定查询

### 可选方案

**方案 A：使用 ORM（如 SQLAlchemy）**
- 优点：功能强大，支持迁移
- 缺点：性能开销，学习成本高，灵活性受限

**方案 B：使用适配器模式，直接使用 SQL** ✅
- 优点：性能优先，灵活性高，简单直接
- 缺点：需要手动编写 SQL（但这是可接受的）

### 为什么选择当前方案

选择方案 B 的理由：
1. **性能优先**：直接 SQL 减少抽象层开销
2. **灵活性**：可以优化特定查询，不受 ORM 限制
3. **简单性**：减少学习成本和维护成本

### 影响

- 不使用 ORM，直接使用 SQL
- 通过适配器模式统一不同数据库的接口
- 性能更好，但需要手动编写 SQL

---

## 决策 4：默认实例机制

**日期**：2025-12-19  
**状态**：已实施

### 痛点

如果每次使用都需要显式传递数据库实例，会导致：
- 使用不便：90% 的场景都需要传递 db 参数
- 多进程问题：子进程无法共享主进程的数据库实例
- 代码冗余：每个 Model 都需要接收 db 参数

### 可选方案

**方案 A：每次显式传递数据库实例**
- 优点：控制灵活
- 缺点：使用不便，代码冗余，多进程问题

**方案 B：提供默认实例机制** ✅
- 优点：使用简单，支持多进程，代码简洁
- 缺点：需要设计默认实例机制

### 为什么选择当前方案

选择方案 B 的理由：
1. **简化使用**：90% 的场景不需要显式传递数据库实例
2. **多进程支持**：子进程自动检测并创建只读实例
3. **向后兼容**：保持现有代码可用

### 影响

- 主进程初始化并设置默认实例
- 子进程自动检测并创建只读实例
- Model 类自动获取默认 db，无需显式传递

---

## 决策 5：三层架构设计

**日期**：2025-12-19  
**状态**：已实施

### 痛点

如果将所有功能集中在一个类中，会导致：
- 职责不清：连接管理、Schema 管理、表操作混在一起
- 难以测试：功能耦合，难以独立测试
- 难以扩展：修改某个功能可能影响其他功能

### 可选方案

**方案 A：单层架构（所有功能在一个类中）**
- 优点：简单直接
- 缺点：职责不清，难以测试，难以扩展

**方案 B：三层架构（ConnectionManager + SchemaManager + TableManager）** ✅
- 优点：职责清晰，易于测试，易于扩展
- 缺点：层级稍多，学习成本略高

### 为什么选择当前方案

选择方案 B 的理由：
1. **职责清晰**：每个管理器只负责一个明确的功能
2. **易于测试**：每个管理器可以独立测试
3. **易于扩展**：可以独立扩展某个管理器

### 影响

- DatabaseManager 拆分为三个管理器
- 每个管理器职责清晰，易于维护
- 可以独立扩展某个管理器，不影响其他管理器

---

## 相关文档

- **[overview.md](./overview.md)**：模块概览
- **[architecture.md](./architecture.md)**：架构文档

> **提示**：本文档记录了 Database 的重要设计决策。如需了解完整的架构设计，请参考 [architecture.md](./architecture.md)。

---

**文档结束**
