# 数据库切换指南

## 📚 概述

小虾 SaaS 支持两种数据存储方式：
1. **InMemory（内存数据库）** - 开发和测试环境
2. **PostgreSQL** - 生产环境

通过环境变量 `USE_IN_MEMORY_DB` 控制。

---

## 🔄 快速切换

### 方式 1: 环境变量

在 `.env` 文件中设置：

```env
# 使用内存数据库（开发/测试）
USE_IN_MEMORY_DB=true

# 使用 PostgreSQL（生产）
USE_IN_MEMORY_DB=false
DATABASE_URL=postgresql://user:pass@localhost:5432/xiaoxia_saas
```

### 方式 2: 启动时指定

```bash
# 使用内存数据库
USE_IN_MEMORY_DB=true uvicorn apps.api.main:app --reload

# 使用 PostgreSQL
USE_IN_MEMORY_DB=false uvicorn apps.api.main:app --reload
```

---

## 💡 InMemory 数据库

**特点：**
- ✅ 无需安装 PostgreSQL
- ✅ 无需数据库迁移
- ✅ 快速启动
- ✅ 适合开发和测试
- ❌ 重启后数据丢失
- ❌ 不适合生产环境

**使用场景：**
- 本地开发
- 单元测试
- 集成测试
- 快速原型验证

**启动：**
```bash
# 设置环境变量
export USE_IN_MEMORY_DB=true

# 启动服务
uvicorn apps.api.main:app --reload
```

---

## 🗄️ PostgreSQL 数据库

**特点：**
- ✅ 数据持久化
- ✅ 支持事务
- ✅ 生产就绪
- ✅ 支持并发
- ❌ 需要安装 PostgreSQL
- ❌ 需要运行数据库迁移

**使用场景：**
- 生产环境
- 预发布环境
- 需要数据持久化的场景

**设置步骤：**

1. **安装 PostgreSQL**
   ```bash
   # Ubuntu
   sudo apt-get install postgresql
   
   # macOS
   brew install postgresql
   ```

2. **创建数据库**
   ```bash
   sudo -u postgres psql
   CREATE DATABASE xiaoxia_saas;
   CREATE USER xiaoxia_user WITH PASSWORD 'your_password';
   GRANT ALL PRIVILEGES ON DATABASE xiaoxia_saas TO xiaoxia_user;
   \q
   ```

3. **运行 Alembic 迁移**
   ```bash
   alembic upgrade head
   ```

4. **配置环境变量**
   ```env
   USE_IN_MEMORY_DB=false
   DATABASE_URL=postgresql://xiaoxia_user:password@localhost:5432/xiaoxia_saas
   ```

5. **启动服务**
   ```bash
   uvicorn apps.api.main:app --reload
   ```

---

## 🐳 Docker 环境

### Canonical Docker Compose（自动配置 PostgreSQL）

```bash
# 自动启动 PostgreSQL 和应用
WEB_PORT=3001 docker compose -f infra/docker/compose.yml up -d --build

# 查看日志
docker compose -f infra/docker/compose.yml logs -f api
```

`infra/docker/compose.yml` 是当前唯一有效 compose 入口；根目录 `docker-compose.yml` 已退役。

---

## 🧪 测试环境

### 单元测试（推荐 InMemory）

```python
# tests/conftest.py
import os
os.environ['USE_IN_MEMORY_DB'] = 'true'
```

### 集成测试（可选 PostgreSQL）

```bash
# 使用 PostgreSQL 进行集成测试
USE_IN_MEMORY_DB=false pytest tests/integration -v
```

---

## 🔧 实现原理

依赖注入容器根据配置自动选择：

```python
# apps/api/app/dependencies.py
@property
def user_repository(self):
    if settings.USE_IN_MEMORY_DB:
        return InMemoryUserRepository()
    else:
        return PostgresUserRepository(settings.DATABASE_URL)
```

**优点：**
- 业务逻辑无需改动
- 切换透明
- 测试隔离

---

## ⚠️ 注意事项

1. **数据不兼容**
   - InMemory 和 PostgreSQL 之间无法直接迁移数据
   - 切换前请备份重要数据

2. **性能差异**
   - InMemory 更快（无 I/O）
   - PostgreSQL 支持更大数据量

3. **并发支持**
   - InMemory 不支持多进程
   - PostgreSQL 支持多进程和集群

4. **环境一致性**
   - 开发环境建议使用 InMemory
   - 生产环境必须使用 PostgreSQL

---

## 🚀 最佳实践

1. **开发流程**
   ```
   开发（InMemory） → 测试（InMemory） → 预发布（PostgreSQL） → 生产（PostgreSQL）
   ```

2. **配置管理**
   - 使用 `.env` 文件管理配置
   - 不要提交 `.env` 到版本控制
   - 使用 `.env.example` 作为模板

3. **数据库迁移**
   - 所有 schema 变更都要有迁移脚本
   - 迁移脚本要幂等（可多次执行）
   - 测试迁移脚本后再应用到生产

---

**最后更新:** 2026-06-17
