geo/.qoder/repowiki/zh/content/数据库设计/数据库架构.md

436 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 数据库架构
<cite>
**本文引用的文件**
- [backend/app/database.py](file://backend/app/database.py)
- [backend/app/config.py](file://backend/app/config.py)
- [backend/alembic/env.py](file://backend/alembic/env.py)
- [backend/alembic/versions/488d0bd5ab01_initial_migration.py](file://backend/alembic/versions/488d0bd5ab01_initial_migration.py)
- [backend/requirements.txt](file://backend/requirements.txt)
- [backend/app/models/user.py](file://backend/app/models/user.py)
- [backend/app/models/query.py](file://backend/app/models/query.py)
- [backend/app/models/citation_record.py](file://backend/app/models/citation_record.py)
- [backend/app/models/query_task.py](file://backend/app/models/query_task.py)
- [backend/app/models/subscription.py](file://backend/app/models/subscription.py)
- [backend/app/models/__init__.py](file://backend/app/models/__init__.py)
- [backend/app/api/deps.py](file://backend/app/api/deps.py)
- [backend/app/api/auth.py](file://backend/app/api/auth.py)
- [backend/app/main.py](file://backend/app/main.py)
- [docker-compose.yml](file://docker-compose.yml)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件系统性梳理 GEO 平台的数据库架构,重点覆盖以下方面:
- 基于 PostgreSQL 的异步数据库连接配置SQLAlchemy 异步引擎、连接池与会话生命周期管理
- 连接字符串配置、环境变量管理与安全注意事项
- 异步数据库操作的优势、性能特征与最佳实践
- 连接监控、错误处理与故障恢复机制
- 生产环境配置建议与性能调优指南
## 项目结构
后端采用 FastAPI + SQLAlchemy 2.x 异步 ORM 架构,数据库层由异步引擎与会话工厂构成,配合 Alembic 进行迁移管理;模型定义位于 models 子包中,并通过 API 层注入依赖进行使用。
```mermaid
graph TB
subgraph "后端应用"
CFG["配置模块<br/>app/config.py"]
DB["数据库引擎与会话<br/>app/database.py"]
MODELS["ORM 模型<br/>app/models/*"]
ALEMBIC["迁移环境<br/>alembic/env.py"]
MIGRATE["初始迁移脚本<br/>alembic/versions/*"]
API_DEPS["API 依赖注入<br/>app/api/deps.py"]
API_AUTH["认证路由<br/>app/api/auth.py"]
MAIN["应用入口与生命周期<br/>app/main.py"]
end
subgraph "外部服务"
PG["PostgreSQL 实例"]
REDIS["Redis 实例"]
end
CFG --> DB
DB --> MODELS
ALEMBIC --> MIGRATE
API_DEPS --> DB
API_AUTH --> DB
MAIN --> API_AUTH
MAIN --> API_DEPS
DB --> PG
REDIS -. 缓存/任务队列 .-> MAIN
```
图表来源
- [backend/app/database.py:1-29](file://backend/app/database.py#L1-L29)
- [backend/app/config.py:1-17](file://backend/app/config.py#L1-L17)
- [backend/alembic/env.py:1-89](file://backend/alembic/env.py#L1-L89)
- [backend/alembic/versions/488d0bd5ab01_initial_migration.py:1-128](file://backend/alembic/versions/488d0bd5ab01_initial_migration.py#L1-L128)
- [backend/app/api/deps.py:1-43](file://backend/app/api/deps.py#L1-L43)
- [backend/app/api/auth.py:1-43](file://backend/app/api/auth.py#L1-L43)
- [backend/app/main.py:1-48](file://backend/app/main.py#L1-L48)
章节来源
- [backend/app/database.py:1-29](file://backend/app/database.py#L1-L29)
- [backend/app/config.py:1-17](file://backend/app/config.py#L1-L17)
- [backend/alembic/env.py:1-89](file://backend/alembic/env.py#L1-L89)
- [backend/alembic/versions/488d0bd5ab01_initial_migration.py:1-128](file://backend/alembic/versions/488d0bd5ab01_initial_migration.py#L1-L128)
- [backend/app/api/deps.py:1-43](file://backend/app/api/deps.py#L1-L43)
- [backend/app/api/auth.py:1-43](file://backend/app/api/auth.py#L1-L43)
- [backend/app/main.py:1-48](file://backend/app/main.py#L1-L48)
## 核心组件
- 异步引擎与会话工厂
- 使用 SQLAlchemy 异步引擎创建数据库连接,关闭 echo启用 future 模式
- 会话工厂配置为非自动提交、非自动刷新、关闭提交时过期,确保事务边界清晰
- 提供异步上下文管理的会话生成器,保证在请求结束时正确关闭会话
- 配置与连接字符串
- 通过 Pydantic Settings 从 .env 文件加载配置,包含 DATABASE_URL、REDIS_URL、JWT_SECRET 等
- 默认 DATABASE_URL 指向本地或容器内 PostgreSQL 实例
- 模型与索引
- 用户、查询、引用记录、查询任务、订阅等核心实体,均采用 PostgreSQL UUID 主键与 JSONB 字段
- 在高频查询字段上建立复合索引,提升读取性能
- 迁移与初始化
- Alembic 环境支持离线与在线迁移,使用异步引擎执行迁移
- 初始迁移脚本创建表结构与索引,定义外键约束与默认值
章节来源
- [backend/app/database.py:1-29](file://backend/app/database.py#L1-L29)
- [backend/app/config.py:1-17](file://backend/app/config.py#L1-L17)
- [backend/app/models/user.py:1-41](file://backend/app/models/user.py#L1-L41)
- [backend/app/models/query.py:1-55](file://backend/app/models/query.py#L1-L55)
- [backend/app/models/citation_record.py:1-42](file://backend/app/models/citation_record.py#L1-L42)
- [backend/app/models/query_task.py:1-39](file://backend/app/models/query_task.py#L1-L39)
- [backend/app/models/subscription.py:1-37](file://backend/app/models/subscription.py#L1-L37)
- [backend/alembic/env.py:64-88](file://backend/alembic/env.py#L64-L88)
- [backend/alembic/versions/488d0bd5ab01_initial_migration.py:21-128](file://backend/alembic/versions/488d0bd5ab01_initial_migration.py#L21-L128)
## 架构总览
下图展示异步数据库连接在应用中的整体流转FastAPI 路由通过依赖注入获取 AsyncSession执行数据库操作后自动释放迁移通过 Alembic 异步引擎执行;配置从 .env 加载 DATABASE_URL。
```mermaid
sequenceDiagram
participant Client as "客户端"
participant API as "FastAPI 路由"
participant Deps as "依赖注入(get_db)"
participant Session as "AsyncSession"
participant Engine as "异步引擎"
participant PG as "PostgreSQL"
Client->>API : "HTTP 请求"
API->>Deps : "解析依赖(获取会话)"
Deps->>Session : "创建/获取会话"
Session->>Engine : "执行 SQL"
Engine->>PG : "发送查询"
PG-->>Engine : "返回结果"
Engine-->>Session : "映射为模型"
Session-->>API : "业务结果"
API-->>Client : "响应"
API->>Deps : "请求结束"
Deps->>Session : "关闭会话"
```
图表来源
- [backend/app/api/auth.py:13-42](file://backend/app/api/auth.py#L13-L42)
- [backend/app/api/deps.py:16-42](file://backend/app/api/deps.py#L16-L42)
- [backend/app/database.py:23-28](file://backend/app/database.py#L23-L28)
## 详细组件分析
### 异步引擎与会话生命周期
- 引擎创建
- 使用异步引擎echo 关闭future 启用,避免冗余日志与兼容性问题
- 会话工厂
- 非自动提交、非自动刷新、关闭提交时过期,便于显式控制事务
- 会话生成器
- 通过上下文管理器确保异常时也能正确关闭会话,避免连接泄漏
```mermaid
flowchart TD
Start(["进入 get_db"]) --> NewSession["创建 AsyncSessionLocal()"]
NewSession --> TryBlock["进入 try 块并 yield 会话"]
TryBlock --> FinallyBlock["finally 块中关闭会话"]
FinallyBlock --> End(["退出 get_db"])
```
图表来源
- [backend/app/database.py:23-28](file://backend/app/database.py#L23-L28)
章节来源
- [backend/app/database.py:1-29](file://backend/app/database.py#L1-L29)
### 连接字符串与环境变量管理
- 连接字符串
- 默认 DATABASE_URL 指向 PostgreSQL 实例,可在 .env 中覆盖
- 环境变量加载
- 通过 Pydantic SettingsConfigDict 从 .env 加载,忽略未知字段
- 安全注意事项
- 生产环境务必使用强密钥与加密传输
- 不要在代码中硬编码敏感信息,优先使用环境变量与密钥管理服务
章节来源
- [backend/app/config.py:4-16](file://backend/app/config.py#L4-L16)
### 数据模型与索引策略
- 用户模型
- UUID 主键、邮箱唯一、密码哈希、计划与配额字段
- 查询模型
- 外键关联用户、JSONB 存储平台与别名、多字段索引优化
- 引用记录模型
- JSONB 存储竞品品牌与原始响应,按查询与时间、平台建立索引
- 查询任务模型
- 状态字段索引,便于任务调度与状态统计
- 订阅模型
- 金额与支付信息存储,日期范围与状态管理
```mermaid
erDiagram
USERS {
uuid id PK
string email UK
string password_hash
string name
string plan
int max_queries
bool is_active
timestamptz created_at
timestamptz updated_at
}
QUERIES {
uuid id PK
uuid user_id FK
string keyword
string target_brand
jsonb brand_aliases
jsonb platforms
string frequency
string status
timestamptz last_queried_at
timestamptz next_query_at
timestamptz created_at
timestamptz updated_at
}
CITATION_RECORDS {
uuid id PK
uuid query_id FK
string platform
bool cited
int citation_position
text citation_text
jsonb competitor_brands
text raw_response
timestamptz queried_at
}
QUERY_TASKS {
uuid id PK
uuid query_id FK
string platform
string status
text error_message
timestamptz scheduled_at
timestamptz started_at
timestamptz completed_at
}
SUBSCRIPTIONS {
uuid id PK
uuid user_id FK
string plan
string status
date start_date
date end_date
numeric amount
string payment_method
string payment_id
timestamptz created_at
}
USERS ||--o{ QUERIES : "拥有"
QUERIES ||--o{ CITATION_RECORDS : "产生"
QUERIES ||--o{ QUERY_TASKS : "驱动"
USERS ||--o{ SUBSCRIPTIONS : "订阅"
```
图表来源
- [backend/app/models/user.py:11-41](file://backend/app/models/user.py#L11-L41)
- [backend/app/models/query.py:11-55](file://backend/app/models/query.py#L11-L55)
- [backend/app/models/citation_record.py:11-42](file://backend/app/models/citation_record.py#L11-L42)
- [backend/app/models/query_task.py:11-39](file://backend/app/models/query_task.py#L11-L39)
- [backend/app/models/subscription.py:11-37](file://backend/app/models/subscription.py#L11-L37)
章节来源
- [backend/app/models/user.py:1-41](file://backend/app/models/user.py#L1-L41)
- [backend/app/models/query.py:1-55](file://backend/app/models/query.py#L1-L55)
- [backend/app/models/citation_record.py:1-42](file://backend/app/models/citation_record.py#L1-L42)
- [backend/app/models/query_task.py:1-39](file://backend/app/models/query_task.py#L1-L39)
- [backend/app/models/subscription.py:1-37](file://backend/app/models/subscription.py#L1-L37)
### 迁移与初始化
- 离线/在线迁移
- 离线模式直接使用 DATABASE_URL在线模式通过异步引擎建立连接并执行迁移
- 使用 NullPool 避免额外连接池开销
- 初始迁移
- 创建 users、queries、citation_records、query_tasks、subscriptions 表
- 添加必要的外键与索引,确保查询性能与数据一致性
```mermaid
sequenceDiagram
participant CLI as "Alembic CLI"
participant Env as "env.py"
participant Engine as "异步引擎"
participant Conn as "连接"
participant DB as "PostgreSQL"
CLI->>Env : "run_migrations_online()"
Env->>Engine : "create_async_engine(DATABASE_URL, poolclass=NullPool)"
Engine->>Conn : "connect()"
Conn->>DB : "执行迁移"
DB-->>Conn : "返回迁移结果"
Conn-->>Engine : "完成迁移"
Engine-->>Env : "dispose()"
```
图表来源
- [backend/alembic/env.py:64-88](file://backend/alembic/env.py#L64-L88)
- [backend/alembic/versions/488d0bd5ab01_initial_migration.py:21-128](file://backend/alembic/versions/488d0bd5ab01_initial_migration.py#L21-L128)
章节来源
- [backend/alembic/env.py:1-89](file://backend/alembic/env.py#L1-L89)
- [backend/alembic/versions/488d0bd5ab01_initial_migration.py:1-128](file://backend/alembic/versions/488d0bd5ab01_initial_migration.py#L1-L128)
### API 依赖注入与会话使用
- 依赖注入
- OAuth2 密钥流用于令牌校验;通过 get_db 获取 AsyncSession
- 典型流程
- 注册/登录接口使用 AsyncSession 执行写入与查询
- 当前用户接口通过令牌解析与数据库查询返回用户信息
```mermaid
sequenceDiagram
participant Client as "客户端"
participant Auth as "认证路由"
participant Deps as "get_current_user"
participant DB as "AsyncSession"
participant Model as "User 模型"
Client->>Auth : "POST /api/v1/auth/login"
Auth->>DB : "执行认证查询"
DB-->>Auth : "返回用户对象"
Auth-->>Client : "返回访问令牌与用户信息"
Client->>Auth : "GET /api/v1/auth/me"
Auth->>Deps : "校验令牌并解析用户ID"
Deps->>DB : "查询用户"
DB-->>Deps : "返回用户"
Deps-->>Client : "返回当前用户"
```
图表来源
- [backend/app/api/auth.py:13-42](file://backend/app/api/auth.py#L13-L42)
- [backend/app/api/deps.py:16-42](file://backend/app/api/deps.py#L16-L42)
章节来源
- [backend/app/api/auth.py:1-43](file://backend/app/api/auth.py#L1-L43)
- [backend/app/api/deps.py:1-43](file://backend/app/api/deps.py#L1-L43)
## 依赖分析
- 组件耦合
- API 层通过依赖注入使用数据库会话,降低耦合度
- 模型与数据库层解耦,仅依赖 Base 与类型注解
- 外部依赖
- SQLAlchemy 2.x 异步 ORM、asyncpg、Alembic
- FastAPI、Pydantic Settings、Redis缓存/任务)
```mermaid
graph LR
API_AUTH["app/api/auth.py"] --> DEPS["app/api/deps.py"]
DEPS --> DB["app/database.py"]
API_AUTH --> DB
DB --> CONFIG["app/config.py"]
DB --> MODELS["app/models/*"]
ALEMBIC_ENV["alembic/env.py"] --> CONFIG
ALEMBIC_ENV --> MODELS
ALEMBIC_MIG["alembic/versions/*"] --> MODELS
```
图表来源
- [backend/app/api/auth.py:1-43](file://backend/app/api/auth.py#L1-L43)
- [backend/app/api/deps.py:1-43](file://backend/app/api/deps.py#L1-L43)
- [backend/app/database.py:1-29](file://backend/app/database.py#L1-L29)
- [backend/app/config.py:1-17](file://backend/app/config.py#L1-L17)
- [backend/alembic/env.py:1-89](file://backend/alembic/env.py#L1-L89)
- [backend/alembic/versions/488d0bd5ab01_initial_migration.py:1-128](file://backend/alembic/versions/488d0bd5ab01_initial_migration.py#L1-L128)
章节来源
- [backend/requirements.txt:1-35](file://backend/requirements.txt#L1-L35)
## 性能考量
- 异步优势
- 高并发场景下减少阻塞,提升吞吐量
- 与 FastAPI 协同,充分利用事件循环
- 连接池与会话
- 默认未显式配置连接池参数,建议在生产中根据 QPS 与实例规格调整最大连接数、空闲连接数与超时
- 索引与查询
- 已在高频查询字段建立索引,避免全表扫描
- 对 JSONB 字段的查询建议结合 GIN 索引(如需)
- 写入优化
- 批量写入与事务合并可显著降低写入延迟
- 监控与观测
- 建议集成数据库性能视图与慢查询日志
- 结合应用指标(请求耗时、错误率)定位瓶颈
## 故障排查指南
- 连接失败
- 检查 DATABASE_URL 是否正确,网络连通性与防火墙
- 确认 PostgreSQL 实例健康状态与认证凭据
- 迁移失败
- 离线/在线模式分别检查配置与权限
- 查看 Alembic 输出与 PostgreSQL 日志
- 会话泄漏
- 确保所有分支均能到达 finally 块,避免异常中断导致会话未关闭
- 错误处理
- API 层对认证失败与数据库异常进行标准化响应
- 建议增加重试与熔断策略(如适用)
章节来源
- [backend/app/database.py:23-28](file://backend/app/database.py#L23-L28)
- [backend/alembic/env.py:64-88](file://backend/alembic/env.py#L64-L88)
- [backend/app/api/auth.py:13-42](file://backend/app/api/auth.py#L13-L42)
- [backend/app/api/deps.py:16-42](file://backend/app/api/deps.py#L16-L42)
## 结论
GEO 项目采用 SQLAlchemy 异步 ORM 与 FastAPI 构建了高并发、可维护的数据库层。通过合理的模型设计、索引策略与依赖注入,实现了清晰的职责分离与良好的扩展性。建议在生产环境中完善连接池参数、监控体系与安全策略,持续优化查询与写入路径。
## 附录
### 生产环境配置建议
- 连接字符串与环境变量
- 使用独立 .env 文件管理 DATABASE_URL避免硬编码
- 在容器编排中通过环境注入,确保不同环境隔离
- 连接池与会话
- 显式配置最大连接数、空闲连接数、连接超时与回收策略
- 控制会话生命周期,避免长事务与长时间持有连接
- 安全
- 使用强口令与 TLS 加密传输
- 限制数据库用户权限,最小化授权
- 监控与可观测性
- 集成数据库性能视图与慢查询日志
- 应用层记录关键指标QPS、P95/P99、错误率
- 备份与恢复
- 定期备份策略与演练,确保可快速恢复
### 性能调优清单
- 索引优化
- 对高频过滤与排序字段建立合适索引
- 对 JSONB 字段查询考虑 GIN 索引
- 查询优化
- 减少 N+1 查询,使用 select_in_load 或 joinedload
- 合理分页与投影,避免 SELECT *
- 写入优化
- 批量插入与事务合并
- 写入热点拆分与读写分离(如需要)
- 连接与资源
- 合理设置连接池大小,避免过度占用
- 及时关闭会话与释放资源