17 KiB
17 KiB
表结构设计
**本文档引用的文件** - [user.py](file://backend/app/models/user.py) - [query.py](file://backend/app/models/query.py) - [citation_record.py](file://backend/app/models/citation_record.py) - [query_task.py](file://backend/app/models/query_task.py) - [subscription.py](file://backend/app/models/subscription.py) - [initial_migration.py](file://backend/alembic/versions/488d0bd5ab01_initial_migration.py) - [database.py](file://backend/app/database.py) - [config.py](file://backend/app/config.py)目录
简介
本文件详细描述GEO项目的数据库表结构设计,涵盖用户查询监控平台的核心数据模型。该系统采用PostgreSQL作为主要数据库,使用SQLAlchemy ORM进行对象关系映射,支持异步数据库操作。系统包含五个核心表:users(用户表)、queries(查询表)、citation_records(引用记录表)、query_tasks(查询任务表)和subscriptions(订阅表),这些表通过外键关系相互关联,形成完整的业务数据模型。
项目结构
GEO项目的数据库层采用分层架构设计,主要包含以下组件:
graph TB
subgraph "数据库层"
DB[(PostgreSQL数据库)]
Engine[异步引擎]
Session[会话管理]
end
subgraph "ORM模型层"
User[User模型]
Query[Query模型]
Citation[CitationRecord模型]
Task[QueryTask模型]
Subscription[Subscription模型]
end
subgraph "配置层"
Config[配置管理]
Alembic[迁移管理]
end
Config --> Engine
Engine --> DB
Session --> DB
User --> DB
Query --> DB
Citation --> DB
Task --> DB
Subscription --> DB
Alembic --> DB
图表来源
章节来源
核心组件
数据库连接配置
系统使用异步PostgreSQL连接,配置参数如下:
- 数据库URL:
postgresql+asyncpg://postgres:postgres123@db:5432/geo_platform - Redis连接:
redis://redis:6379/0 - JWT密钥:
your-secret-key-change-in-production - Playwright浏览器路径:
/ms-playwright
异步数据库引擎
使用SQLAlchemy异步引擎创建数据库连接池,支持:
- 异步会话管理
- 连接池配置
- 自动事务处理
- 连接生命周期管理
章节来源
架构概览
GEO系统的数据库架构采用标准的三层设计模式:
erDiagram
USERS {
uuid id PK
string email UK
string password_hash
string name
string plan
integer max_queries
boolean is_active
timestamp created_at
timestamp updated_at
}
QUERIES {
uuid id PK
uuid user_id FK
string keyword
string target_brand
jsonb brand_aliases
jsonb platforms
string frequency
string status
timestamp last_queried_at
timestamp next_query_at
timestamp created_at
timestamp updated_at
}
CITATION_RECORDS {
uuid id PK
uuid query_id FK
string platform
boolean cited
integer citation_position
text citation_text
jsonb competitor_brands
text raw_response
timestamp queried_at
}
QUERY_TASKS {
uuid id PK
uuid query_id FK
string platform
string status
text error_message
timestamp scheduled_at
timestamp started_at
timestamp 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
timestamp created_at
}
USERS ||--o{ QUERIES : "拥有"
QUERIES ||--o{ CITATION_RECORDS : "包含"
QUERIES ||--o{ QUERY_TASKS : "包含"
USERS ||--o{ SUBSCRIPTIONS : "拥有"
图表来源
- initial_migration.py:24-37
- initial_migration.py:40-56
- initial_migration.py:62-78
- initial_migration.py:81-94
- initial_migration.py:97-111
详细组件分析
用户表 (users)
用户表是整个系统的核心实体,存储平台用户的基本信息和账户状态。
字段定义
| 字段名 | 数据类型 | 约束条件 | 描述 |
|---|---|---|---|
| id | UUID | 主键, 非空, 默认值 | 用户唯一标识符 |
| String(255) | 唯一, 非空 | 用户邮箱地址 | |
| password_hash | String(255) | 非空 | 用户密码哈希值 |
| name | String(100) | 可空 | 用户姓名 |
| plan | String(20) | 非空, 默认值: "free" | 用户套餐类型 |
| max_queries | Integer | 非空, 默认值: 5 | 最大查询次数限制 |
| is_active | Boolean | 非空, 默认值: true | 账户激活状态 |
| created_at | Timestamp | 非空, 默认值: NOW() | 创建时间 |
| updated_at | Timestamp | 非空, 默认值: NOW() | 更新时间 |
约束和索引
- 主键: id (UUID)
- 唯一约束: email
- 外键: 无直接外键关系
- 关系: 与查询表(一对多)、订阅表(一对多)
业务规则
- 用户必须提供唯一的邮箱地址
- 默认免费套餐,最大查询次数为5次
- 账户默认激活状态
- 时间戳自动管理
章节来源
查询表 (queries)
查询表记录用户的搜索关键词和品牌监控配置。
字段定义
| 字段名 | 数据类型 | 约束条件 | 描述 |
|---|---|---|---|
| id | UUID | 主键, 非空, 默认值 | 查询记录唯一标识符 |
| user_id | UUID | 外键, 非空 | 关联用户ID |
| keyword | String(200) | 非空 | 搜索关键词 |
| target_brand | String(100) | 非空 | 目标品牌名称 |
| brand_aliases | JSONB | 非空, 默认值: [] | 品牌别名列表 |
| platforms | JSONB | 非空, 默认值: ["wenxin","kimi"] | 监控平台列表 |
| frequency | String(20) | 非空, 默认值: "weekly" | 查询频率 |
| status | String(20) | 非空, 默认值: "active" | 查询状态 |
| last_queried_at | Timestamp | 可空 | 最后查询时间 |
| next_query_at | Timestamp | 可空 | 下次查询时间 |
| created_at | Timestamp | 非空, 默认值: NOW() | 创建时间 |
| updated_at | Timestamp | 非空, 默认值: NOW() | 更新时间 |
约束和索引
- 主键: id (UUID)
- 外键: user_id → users.id (级联删除)
- 索引: idx_queries_user_id, idx_queries_status, idx_queries_next_query_at
- 关系: 与用户表(多对一)、引用记录表(一对多)、查询任务表(一对多)
业务规则
- 必须关联有效用户
- 平台默认监控"wenxin"和"kimi"
- 状态默认为"active"
- 支持定时查询调度
- 级联删除确保数据一致性
章节来源
引用记录表 (citation_records)
引用记录表存储每次查询的具体结果和竞争情报。
字段定义
| 字段名 | 数据类型 | 约束条件 | 描述 |
|---|---|---|---|
| id | UUID | 主键, 非空, 默认值 | 引用记录唯一标识符 |
| query_id | UUID | 外键, 非空 | 关联查询ID |
| platform | String(50) | 非空 | 查询平台名称 |
| cited | Boolean | 非空, 默认值: false | 是否被引用 |
| citation_position | Integer | 可空 | 引用位置 |
| citation_text | Text | 可空 | 引用文本内容 |
| competitor_brands | JSONB | 非空, 默认值: [] | 竞争品牌列表 |
| raw_response | Text | 可空 | 原始响应内容 |
| queried_at | Timestamp | 非空, 默认值: NOW() | 查询时间 |
约束和索引
- 主键: id (UUID)
- 外键: query_id → queries.id (级联删除)
- 索引: idx_citation_records_query_id, idx_citation_records_queried_at, idx_citation_records_platform
- 关系: 与查询表(多对一)
业务规则
- 必须关联有效查询
- 引用状态默认未引用
- 支持JSON格式的竞争品牌数据
- 按平台和查询时间建立索引优化查询性能
- 级联删除确保查询历史完整清理
章节来源
查询任务表 (query_tasks)
查询任务表管理异步查询任务的状态和执行信息。
字段定义
| 字段名 | 数据类型 | 约束条件 | 描述 |
|---|---|---|---|
| id | UUID | 主键, 非空, 默认值 | 任务唯一标识符 |
| query_id | UUID | 外键, 非空 | 关联查询ID |
| platform | String(50) | 非空 | 执行平台 |
| status | String(20) | 非空, 默认值: "pending" | 任务状态 |
| error_message | Text | 可空 | 错误信息 |
| scheduled_at | Timestamp | 非空, 默认值: NOW() | 调度时间 |
| started_at | Timestamp | 可空 | 开始执行时间 |
| completed_at | Timestamp | 可空 | 完成时间 |
约束和索引
- 主键: id (UUID)
- 外键: query_id → queries.id (级联删除)
- 索引: idx_query_tasks_status
- 关系: 与查询表(多对一)
业务规则
- 必须关联有效查询
- 任务状态默认为"pending"
- 支持任务执行跟踪
- 状态变更自动记录时间戳
- 级联删除确保任务历史清理
章节来源
订阅表 (subscriptions)
订阅表管理用户的付费订阅信息和状态。
字段定义
| 字段名 | 数据类型 | 约束条件 | 描述 |
|---|---|---|---|
| id | UUID | 主键, 非空, 默认值 | 订阅记录唯一标识符 |
| user_id | UUID | 外键, 非空 | 关联用户ID |
| plan | String(20) | 非空 | 套餐类型 |
| status | String(20) | 非空, 默认值: "active" | 订阅状态 |
| start_date | Date | 非空 | 订阅开始日期 |
| end_date | Date | 非空 | 订阅结束日期 |
| amount | Numeric(10,2) | 可空 | 支付金额 |
| payment_method | String(50) | 可空 | 支付方式 |
| payment_id | String(255) | 可空 | 支付ID |
| created_at | Timestamp | 非空, 默认值: NOW() | 创建时间 |
约束和索引
- 主键: id (UUID)
- 外键: user_id → users.id (级联删除)
- 关系: 与用户表(多对一)
业务规则
- 必须关联有效用户
- 状态默认为"active"
- 支持多种支付方式
- 日期范围确保订阅有效性
- 级联删除确保订阅历史清理
章节来源
依赖分析
外键关系图
graph LR
Users["Users表<br/>主键: id"] --> |外键: user_id| Queries["Queries表<br/>主键: id"]
Queries --> |外键: query_id| CitationRecords["CitationRecords表<br/>主键: id"]
Queries --> |外键: query_id| QueryTasks["QueryTasks表<br/>主键: id"]
Users --> |外键: user_id| Subscriptions["Subscriptions表<br/>主键: id"]
style Users fill:#e1f5fe
style Queries fill:#f3e5f5
style CitationRecords fill:#e8f5e8
style QueryTasks fill:#fff3e0
style Subscriptions fill:#fce4ec
图表来源
关系类型分析
一对一关系
- users ↔ subscriptions: 一个用户对应一个当前有效的订阅记录
一对多关系
- users → queries: 一个用户可以有多个查询记录
- users → subscriptions: 一个用户可以有多个订阅记录
- queries → citation_records: 一个查询可以有多个引用记录
- queries → query_tasks: 一个查询可以有多个任务
多对多关系
- 通过中间表实现的多对多关系不存在于当前设计中
级联删除策略
所有外键关系都设置了级联删除策略:
- 删除用户时,自动删除其所有查询、订阅记录
- 删除查询时,自动删除其所有引用记录和任务
章节来源
性能考虑
索引策略
系统为关键查询字段建立了专门的索引:
查询表索引
- idx_queries_user_id: 提升按用户查询的性能
- idx_queries_status: 支持状态过滤查询
- idx_queries_next_query_at: 优化定时任务调度
引用记录表索引
- idx_citation_records_query_id: 提升按查询获取记录的性能
- idx_citation_records_queried_at: 支持时间序列查询
- idx_citation_records_platform: 优化平台过滤
查询任务表索引
- idx_query_tasks_status: 支持任务状态统计和调度
数据类型优化
- 使用UUID作为主键,避免序列号暴露业务信息
- JSONB类型存储动态配置,支持高效查询和更新
- 数值类型使用Numeric精确存储金额数据
- 时间戳使用带时区的DateTime确保时区一致性
查询优化建议
- 批量操作: 对于大量数据的插入和更新,使用批量操作减少数据库往返
- 分页查询: 对于列表查询,实现分页机制避免一次性加载过多数据
- 缓存策略: 结合Redis实现热点数据缓存
- 连接池管理: 合理配置连接池大小以平衡性能和资源使用
故障排除指南
常见问题及解决方案
数据库连接问题
- 症状: 应用启动时报数据库连接错误
- 原因: DATABASE_URL配置不正确或数据库服务未启动
- 解决: 检查.env文件中的DATABASE_URL配置,确认数据库服务正常运行
外键约束冲突
- 症状: 删除用户时报外键约束错误
- 原因: 存在相关记录导致级联删除失败
- 解决: 确保级联删除策略正确配置,检查数据完整性
索引性能问题
- 症状: 查询响应缓慢
- 原因: 缺少必要的索引或索引设计不当
- 解决: 分析查询计划,添加适当的索引
数据类型转换错误
- 症状: JSONB字段操作报错
- 原因: 数据类型不匹配或格式错误
- 解决: 确保JSONB数据格式正确,使用适当的序列化方法
调试工具
- 数据库监控: 使用PostgreSQL内置监控工具查看查询性能
- 日志分析: 启用SQLAlchemy日志输出分析查询执行情况
- 性能分析: 使用EXPLAIN ANALYZE分析慢查询
章节来源
结论
GEO项目的数据库表结构设计体现了现代Web应用的最佳实践:
设计优势
- 清晰的数据模型: 五个核心表覆盖了完整的业务场景
- 合理的外键关系: 确保数据一致性和完整性
- 高效的索引策略: 针对常见查询模式优化性能
- 异步数据库支持: 提供良好的并发处理能力
- 灵活的数据类型: JSONB支持动态配置需求
业务逻辑实现
- 用户权限控制通过用户表的激活状态实现
- 查询配额控制通过用户表的max_queries字段实现
- 订阅管理通过订阅表的日期范围和状态字段实现
- 数据清理通过级联删除策略自动维护
扩展性考虑
系统设计具有良好的扩展性:
- 新增表时可复用现有的UUID主键模式
- JSONB字段支持未来功能的动态配置
- 异步架构支持水平扩展
- 清晰的关系设计便于添加新的业务实体
这个数据模型为GEO平台提供了坚实的基础,能够支持用户查询监控、竞争情报分析和订阅管理等核心业务功能。