17 KiB
17 KiB
数据库架构
**本文引用的文件** - [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)目录
简介
本文件系统性梳理 GEO 平台的数据库架构,重点覆盖以下方面:
- 基于 PostgreSQL 的异步数据库连接配置:SQLAlchemy 异步引擎、连接池与会话生命周期管理
- 连接字符串配置、环境变量管理与安全注意事项
- 异步数据库操作的优势、性能特征与最佳实践
- 连接监控、错误处理与故障恢复机制
- 生产环境配置建议与性能调优指南
项目结构
后端采用 FastAPI + SQLAlchemy 2.x 异步 ORM 架构,数据库层由异步引擎与会话工厂构成,配合 Alembic 进行迁移管理;模型定义位于 models 子包中,并通过 API 层注入依赖进行使用。
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
- backend/app/config.py:1-17
- backend/alembic/env.py:1-89
- backend/alembic/versions/488d0bd5ab01_initial_migration.py:1-128
- backend/app/api/deps.py:1-43
- backend/app/api/auth.py:1-43
- backend/app/main.py:1-48
章节来源
- backend/app/database.py:1-29
- backend/app/config.py:1-17
- backend/alembic/env.py:1-89
- backend/alembic/versions/488d0bd5ab01_initial_migration.py:1-128
- backend/app/api/deps.py:1-43
- backend/app/api/auth.py:1-43
- backend/app/main.py:1-48
核心组件
- 异步引擎与会话工厂
- 使用 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
- backend/app/config.py:1-17
- backend/app/models/user.py:1-41
- backend/app/models/query.py:1-55
- backend/app/models/citation_record.py:1-42
- backend/app/models/query_task.py:1-39
- backend/app/models/subscription.py:1-37
- backend/alembic/env.py:64-88
- backend/alembic/versions/488d0bd5ab01_initial_migration.py:21-128
架构总览
下图展示异步数据库连接在应用中的整体流转:FastAPI 路由通过依赖注入获取 AsyncSession,执行数据库操作后自动释放;迁移通过 Alembic 异步引擎执行;配置从 .env 加载 DATABASE_URL。
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 : "关闭会话"
图表来源
详细组件分析
异步引擎与会话生命周期
- 引擎创建
- 使用异步引擎,echo 关闭,future 启用,避免冗余日志与兼容性问题
- 会话工厂
- 非自动提交、非自动刷新、关闭提交时过期,便于显式控制事务
- 会话生成器
- 通过上下文管理器确保异常时也能正确关闭会话,避免连接泄漏
flowchart TD
Start(["进入 get_db"]) --> NewSession["创建 AsyncSessionLocal()"]
NewSession --> TryBlock["进入 try 块并 yield 会话"]
TryBlock --> FinallyBlock["finally 块中关闭会话"]
FinallyBlock --> End(["退出 get_db"])
图表来源
章节来源
连接字符串与环境变量管理
- 连接字符串
- 默认 DATABASE_URL 指向 PostgreSQL 实例,可在 .env 中覆盖
- 环境变量加载
- 通过 Pydantic SettingsConfigDict 从 .env 加载,忽略未知字段
- 安全注意事项
- 生产环境务必使用强密钥与加密传输
- 不要在代码中硬编码敏感信息,优先使用环境变量与密钥管理服务
章节来源
数据模型与索引策略
- 用户模型
- UUID 主键、邮箱唯一、密码哈希、计划与配额字段
- 查询模型
- 外键关联用户、JSONB 存储平台与别名、多字段索引优化
- 引用记录模型
- JSONB 存储竞品品牌与原始响应,按查询与时间、平台建立索引
- 查询任务模型
- 状态字段索引,便于任务调度与状态统计
- 订阅模型
- 金额与支付信息存储,日期范围与状态管理
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
- backend/app/models/query.py:11-55
- backend/app/models/citation_record.py:11-42
- backend/app/models/query_task.py:11-39
- backend/app/models/subscription.py:11-37
章节来源
- backend/app/models/user.py:1-41
- backend/app/models/query.py:1-55
- backend/app/models/citation_record.py:1-42
- backend/app/models/query_task.py:1-39
- backend/app/models/subscription.py:1-37
迁移与初始化
- 离线/在线迁移
- 离线模式直接使用 DATABASE_URL;在线模式通过异步引擎建立连接并执行迁移
- 使用 NullPool 避免额外连接池开销
- 初始迁移
- 创建 users、queries、citation_records、query_tasks、subscriptions 表
- 添加必要的外键与索引,确保查询性能与数据一致性
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()"
图表来源
章节来源
API 依赖注入与会话使用
- 依赖注入
- OAuth2 密钥流用于令牌校验;通过 get_db 获取 AsyncSession
- 典型流程
- 注册/登录接口使用 AsyncSession 执行写入与查询
- 当前用户接口通过令牌解析与数据库查询返回用户信息
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 : "返回当前用户"
图表来源
章节来源
依赖分析
- 组件耦合
- API 层通过依赖注入使用数据库会话,降低耦合度
- 模型与数据库层解耦,仅依赖 Base 与类型注解
- 外部依赖
- SQLAlchemy 2.x 异步 ORM、asyncpg、Alembic
- FastAPI、Pydantic Settings、Redis(缓存/任务)
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
- backend/app/api/deps.py:1-43
- backend/app/database.py:1-29
- backend/app/config.py:1-17
- backend/alembic/env.py:1-89
- backend/alembic/versions/488d0bd5ab01_initial_migration.py:1-128
章节来源
性能考量
- 异步优势
- 高并发场景下减少阻塞,提升吞吐量
- 与 FastAPI 协同,充分利用事件循环
- 连接池与会话
- 默认未显式配置连接池参数,建议在生产中根据 QPS 与实例规格调整最大连接数、空闲连接数与超时
- 索引与查询
- 已在高频查询字段建立索引,避免全表扫描
- 对 JSONB 字段的查询建议结合 GIN 索引(如需)
- 写入优化
- 批量写入与事务合并可显著降低写入延迟
- 监控与观测
- 建议集成数据库性能视图与慢查询日志
- 结合应用指标(请求耗时、错误率)定位瓶颈
故障排查指南
- 连接失败
- 检查 DATABASE_URL 是否正确,网络连通性与防火墙
- 确认 PostgreSQL 实例健康状态与认证凭据
- 迁移失败
- 离线/在线模式分别检查配置与权限
- 查看 Alembic 输出与 PostgreSQL 日志
- 会话泄漏
- 确保所有分支均能到达 finally 块,避免异常中断导致会话未关闭
- 错误处理
- API 层对认证失败与数据库异常进行标准化响应
- 建议增加重试与熔断策略(如适用)
章节来源
- backend/app/database.py:23-28
- backend/alembic/env.py:64-88
- backend/app/api/auth.py:13-42
- backend/app/api/deps.py:16-42
结论
GEO 项目采用 SQLAlchemy 异步 ORM 与 FastAPI 构建了高并发、可维护的数据库层。通过合理的模型设计、索引策略与依赖注入,实现了清晰的职责分离与良好的扩展性。建议在生产环境中完善连接池参数、监控体系与安全策略,持续优化查询与写入路径。
附录
生产环境配置建议
- 连接字符串与环境变量
- 使用独立 .env 文件管理 DATABASE_URL,避免硬编码
- 在容器编排中通过环境注入,确保不同环境隔离
- 连接池与会话
- 显式配置最大连接数、空闲连接数、连接超时与回收策略
- 控制会话生命周期,避免长事务与长时间持有连接
- 安全
- 使用强口令与 TLS 加密传输
- 限制数据库用户权限,最小化授权
- 监控与可观测性
- 集成数据库性能视图与慢查询日志
- 应用层记录关键指标(QPS、P95/P99、错误率)
- 备份与恢复
- 定期备份策略与演练,确保可快速恢复
性能调优清单
- 索引优化
- 对高频过滤与排序字段建立合适索引
- 对 JSONB 字段查询考虑 GIN 索引
- 查询优化
- 减少 N+1 查询,使用 select_in_load 或 joinedload
- 合理分页与投影,避免 SELECT *
- 写入优化
- 批量插入与事务合并
- 写入热点拆分与读写分离(如需要)
- 连接与资源
- 合理设置连接池大小,避免过度占用
- 及时关闭会话与释放资源