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

17 KiB
Raw Blame History

表结构设计

**本文档引用的文件** - [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)

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构概览
  5. 详细组件分析
  6. 依赖分析
  7. 性能考虑
  8. 故障排除指南
  9. 结论

简介

本文件详细描述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 : "拥有"

图表来源

详细组件分析

用户表 (users)

用户表是整个系统的核心实体,存储平台用户的基本信息和账户状态。

字段定义

字段名 数据类型 约束条件 描述
id UUID 主键, 非空, 默认值 用户唯一标识符
email 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确保时区一致性

查询优化建议

  1. 批量操作: 对于大量数据的插入和更新,使用批量操作减少数据库往返
  2. 分页查询: 对于列表查询,实现分页机制避免一次性加载过多数据
  3. 缓存策略: 结合Redis实现热点数据缓存
  4. 连接池管理: 合理配置连接池大小以平衡性能和资源使用

故障排除指南

常见问题及解决方案

数据库连接问题

  • 症状: 应用启动时报数据库连接错误
  • 原因: DATABASE_URL配置不正确或数据库服务未启动
  • 解决: 检查.env文件中的DATABASE_URL配置确认数据库服务正常运行

外键约束冲突

  • 症状: 删除用户时报外键约束错误
  • 原因: 存在相关记录导致级联删除失败
  • 解决: 确保级联删除策略正确配置,检查数据完整性

索引性能问题

  • 症状: 查询响应缓慢
  • 原因: 缺少必要的索引或索引设计不当
  • 解决: 分析查询计划,添加适当的索引

数据类型转换错误

  • 症状: JSONB字段操作报错
  • 原因: 数据类型不匹配或格式错误
  • 解决: 确保JSONB数据格式正确使用适当的序列化方法

调试工具

  1. 数据库监控: 使用PostgreSQL内置监控工具查看查询性能
  2. 日志分析: 启用SQLAlchemy日志输出分析查询执行情况
  3. 性能分析: 使用EXPLAIN ANALYZE分析慢查询

章节来源

结论

GEO项目的数据库表结构设计体现了现代Web应用的最佳实践

设计优势

  1. 清晰的数据模型: 五个核心表覆盖了完整的业务场景
  2. 合理的外键关系: 确保数据一致性和完整性
  3. 高效的索引策略: 针对常见查询模式优化性能
  4. 异步数据库支持: 提供良好的并发处理能力
  5. 灵活的数据类型: JSONB支持动态配置需求

业务逻辑实现

  • 用户权限控制通过用户表的激活状态实现
  • 查询配额控制通过用户表的max_queries字段实现
  • 订阅管理通过订阅表的日期范围和状态字段实现
  • 数据清理通过级联删除策略自动维护

扩展性考虑

系统设计具有良好的扩展性:

  • 新增表时可复用现有的UUID主键模式
  • JSONB字段支持未来功能的动态配置
  • 异步架构支持水平扩展
  • 清晰的关系设计便于添加新的业务实体

这个数据模型为GEO平台提供了坚实的基础能够支持用户查询监控、竞争情报分析和订阅管理等核心业务功能。