# 数据库设计

<cite>
**本文引用的文件**
- `src-tauri/Cargo.toml`
- `src-tauri/sql/Cargo.toml`
- `src-tauri/sql/ths_api_cache_table.sql`
- `src-tauri/sql/README.md`
- `src-tauri/src/lib.rs`
- `src-tauri/src/commands/db_commands.rs`
- `src-tauri/src/models/mod.rs`
- `src-tauri/src/services/financial_indicators_cache.rs`
- `src-tauri/src/cache/kv_cache.rs`
</cite>

## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能考量](#性能考量)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)

## 简介
本文件面向GSDJGXApp的数据库设计与实现，重点围绕以下目标展开：
- SeaORM ORM框架在项目中的配置与使用方式
- 数据库连接池配置、迁移脚本管理、模型定义规范
- 表结构设计（主键、外键、索引）与性能考量
- 连接管理（连接池大小、超时、重连）
- 事务处理策略（ACID、嵌套事务、回滚点）
- 性能优化（查询、索引、缓存）
- 实际配置示例与最佳实践

需要特别说明的是：当前仓库中主要使用了Tauri插件SQL（基于sqlx）进行数据库访问，并未直接出现SeaORM的显式配置或模型文件。因此本文将以现有实现为基础，结合SeaORM常见实践给出可落地的指导与建议。

## 项目结构
从项目结构看，数据库相关能力主要分布在如下位置：
- 核心Rust工程：src-tauri/Cargo.toml 中声明了 sea-orm 依赖
- SQL插件工程：src-tauri/sql/Cargo.toml 定义了基于sqlx的跨平台SQL接口
- 表结构与迁移：src-tauri/sql/ths_api_cache_table.sql 提供了验证计算缓存表的建表与索引
- 插件使用说明：src-tauri/sql/README.md 展示了迁移、加载与语法等用法
- 应用入口与命令注册：src-tauri/src/lib.rs 注册了大量数据库相关命令
- 缓存与服务：src-tauri/src/cache/kv_cache.rs、src-tauri/src/services/financial_indicators_cache.rs 提供应用层缓存策略

```mermaid
graph TB
subgraph "Rust 核心"
A["src-tauri/src/lib.rs<br/>应用入口与命令注册"]
B["src-tauri/src/commands/db_commands.rs<br/>数据库命令实现"]
C["src-tauri/src/models/mod.rs<br/>模型定义入口"]
D["src-tauri/src/services/*.rs<br/>业务服务"]
E["src-tauri/src/cache/kv_cache.rs<br/>KV缓存"]
F["src-tauri/src/services/financial_indicators_cache.rs<br/>财务指标缓存"]
end
subgraph "SQL 插件"
G["src-tauri/sql/Cargo.toml<br/>sqlx驱动与功能特性"]
H["src-tauri/sql/README.md<br/>插件用法与迁移说明"]
I["src-tauri/sql/ths_api_cache_table.sql<br/>验证缓存表与索引"]
end
A --> B
B --> C
B --> D
D --> E
D --> F
A --> G
G --> H
G --> I
```

图表来源
- `src-tauri/src/lib.rs#L1-L308`
- `src-tauri/sql/Cargo.toml#L1-L44`
- `src-tauri/sql/README.md#L1-L221`
- `src-tauri/sql/ths_api_cache_table.sql#L1-L21`

章节来源
- `src-tauri/Cargo.toml#L1-L66`
- `src-tauri/sql/Cargo.toml#L1-L44`
- `src-tauri/sql/README.md#L1-L221`
- `src-tauri/sql/ths_api_cache_table.sql#L1-L21`
- `src-tauri/src/lib.rs#L1-L308`

## 核心组件
- ORM与驱动
  - 核心工程引入了 SeaORM 依赖，具备 SQLite/MySQL/PostgreSQL 支持能力
  - SQL插件工程采用 sqlx 作为底层驱动，支持 sqlite/mysql/postgres
- 数据库命令
  - 应用入口通过 tauri::generate_handler! 注册了大量数据库相关命令，如查询、执行、事务、初始化等
- 缓存体系
  - KV缓存与财务指标缓存用于降低数据库压力，提升读取性能
- 迁移与加载
  - 插件README提供了迁移定义、注册与应用流程；支持在 tauri.conf.json 中预加载或通过客户端 load()

章节来源
- `src-tauri/Cargo.toml#L38-L38`
- `src-tauri/sql/Cargo.toml#L34-L42`
- `src-tauri/src/lib.rs#L136-L144`
- `src-tauri/sql/README.md#L116-L188`

## 架构总览
下图展示了数据库访问的整体流程：前端通过Tauri命令调用后端Rust命令，命令层根据需要选择使用SeaORM或SQL插件接口，最终落到具体数据库驱动上。

```mermaid
sequenceDiagram
participant FE as "前端"
participant Tauri as "Tauri 命令层"
participant Cmd as "数据库命令实现"
participant ORM as "SeaORM/SQLX 接口"
participant DB as "SQLite/MySQL/Postgres"
FE->>Tauri : 调用数据库相关命令
Tauri->>Cmd : 分发到具体命令处理函数
Cmd->>ORM : 执行查询/更新/事务
ORM->>DB : 发送SQL语句
DB-->>ORM : 返回结果集/影响行数
ORM-->>Cmd : 封装后的结果
Cmd-->>Tauri : 返回响应
Tauri-->>FE : 前端展示
```

图表来源
- `src-tauri/src/lib.rs#L77-L304`
- `src-tauri/sql/README.md#L55-L83`

## 详细组件分析

### 数据库连接与池化
- 连接池配置
  - 当前仓库未直接展示连接池参数配置。若使用 SeaORM，默认连接池行为由其运行时特性控制；若使用 SQL 插件（sqlx），可通过构建时特性启用 runtime-tokio 或 runtime-tokio-rustls，并在应用启动阶段初始化连接
- 超时与重试
  - 未发现显式的超时与重试策略配置。建议在生产环境为数据库操作设置合理的超时时间，并对网络型数据库增加指数退避重试
- 连接生命周期
  - SQL 插件 README 展示了通过 Database.load() 或 tauri.conf.json preload 的方式建立连接，适合桌面应用场景

章节来源
- `src-tauri/sql/README.md#L167-L187`

### 迁移脚本管理
- 迁移定义
  - 使用 Migration 结构体定义版本号、描述、SQL与方向（Up/Down）
- 注册与应用
  - 通过插件 Builder.add_migrations 注册迁移；可在 tauri.conf.json 中 preload 预加载数据库连接并自动应用
- 最佳实践
  - 版本唯一性、幂等性、可回滚性；迁移脚本应安全可重复执行

章节来源
- `src-tauri/sql/README.md#L116-L188`

### 模型定义规范（SeaORM）
- 特性开关
  - 在核心工程 Cargo.toml 中启用了 sqlx-sqlite、runtime-tokio-rustls、macros、with-chrono 等特性，便于在SeaORM中使用对应驱动与时间类型
- 建议规范
  - 字段命名统一、非空约束明确、时间字段使用带时区类型
  - 外键关系在 SeaORM 中通过关联宏与枚举定义，确保类型安全
  - 使用 macros 自动生成模型与查询器，减少手写样板代码

章节来源
- `src-tauri/Cargo.toml#L38-L38`

### 表结构设计与索引策略
- 示例表：验证计算 THS 数据存储
  - 主键：自增整数 id
  - 唯一键：query_hash，用于去重与快速定位
  - 时间字段：created_at、updated_at、data_valid_until，支持按时间范围检索与过期清理
  - 索引：针对 query_hash、status、valid_until、created_at 建立复合查询常用字段索引
- 设计原则
  - 主键唯一且稳定增长（或UUID），避免热点更新
  - 外键约束在应用层通过模型关系表达，必要时保留一致性检查
  - 索引覆盖高频查询条件，平衡写入成本与读取性能

章节来源
- `src-tauri/sql/ths_api_cache_table.sql#L1-L21`

### 事务处理策略
- ACID 保障
  - 对于需要强一致性的批量写入，建议使用事务包裹，确保原子性与一致性
- 嵌套事务
  - 不同驱动对嵌套事务支持不同，推荐在应用层以单层事务封装复杂流程，避免深层嵌套
- 回滚点（Savepoint）
  - 若需细粒度回滚，可在支持的数据库中使用 savepoint，但需谨慎评估性能与复杂度
- 错误恢复
  - 事务失败时记录上下文日志，区分可重试与不可重试错误，避免无限重试

（本节为通用实践说明，未直接分析特定文件）

### 查询与索引优化
- 查询优化
  - 使用 EXPLAIN/ANALYZE 分析慢查询计划，避免全表扫描
  - 合理分页与游标翻页，避免 OFFSET 过大导致性能下降
- 索引策略
  - 常用过滤字段、连接字段、排序字段建立索引
  - 复合索引遵循“最左匹配”原则，避免过多冗余索引
- 缓存配置
  - 应用层缓存（KV缓存、财务指标缓存）可显著降低热点查询压力
  - 缓存失效策略：基于 TTL 或基于变更事件

章节来源
- `src-tauri/src/cache/kv_cache.rs#L1-L200`
- `src-tauri/src/services/financial_indicators_cache.rs#L1-L200`

### 实际配置示例与最佳实践
- 连接字符串与驱动选择
  - SQLite：本地文件数据库，适合桌面应用与轻量场景
  - MySQL/Postgres：适合多用户、高并发与复杂查询场景
- 运行时特性
  - 根据目标数据库启用相应特性（如 sqlx-sqlite、runtime-tokio-rustls）
- 日志与监控
  - SQL 插件 README 展示了 sqlx 查询日志过滤与日志文件轮转策略，有助于定位问题

章节来源
- `src-tauri/sql/README.md#L55-L83`
- `src-tauri/sql/Cargo.toml#L34-L42`

## 依赖关系分析
- 组件耦合
  - 应用入口通过命令注册与命令实现解耦，命令实现再根据需要选择 ORM 或 SQL 插件
- 外部依赖
  - SeaORM 与 sqlx 分别承担 ORM 与底层驱动职责，二者可并存但需避免重复配置
- 特性开关
  - Cargo.toml 中的特性决定运行时行为与编译产物，需与实际部署环境一致

```mermaid
graph LR
Core["src-tauri/Cargo.toml<br/>sea-orm 依赖"] --> ORM["ORM 层"]
SQLPkg["src-tauri/sql/Cargo.toml<br/>sqlx 依赖"] --> Driver["驱动层"]
ORM --> DB["SQLite/MySQL/Postgres"]
Driver --> DB
```

图表来源
- `src-tauri/Cargo.toml#L38-L38`
- `src-tauri/sql/Cargo.toml#L34-L42`

章节来源
- `src-tauri/Cargo.toml#L1-L66`
- `src-tauri/sql/Cargo.toml#L1-L44`

## 性能考量
- 连接池
  - 根据并发请求峰值设置最大连接数，避免过度占用资源
  - 为长事务设置合理超时，防止连接饥饿
- 查询
  - 使用参数化查询，避免 SQL 注入与解析开销
  - 对高频查询建立合适索引，定期分析统计信息
- 缓存
  - 利用应用层缓存降低数据库压力，注意缓存一致性与失效策略
- IO
  - SQLite 适用于单机、小并发场景；高并发建议使用 MySQL/Postgres 并配合连接池

（本节提供通用指导，未直接分析特定文件）

## 故障排查指南
- 迁移失败
  - 检查迁移版本顺序与幂等性；确认数据库连接字符串正确
- 查询缓慢
  - 使用 EXPLAIN 分析执行计划；检查索引是否命中
- 连接异常
  - 核对驱动特性与运行时环境；检查连接池配置与超时设置
- 日志定位
  - SQL 插件 README 展示了如何过滤 sqlx 查询日志，便于聚焦问题

章节来源
- `src-tauri/sql/README.md#L116-L188`

## 结论
本项目在数据库层面采用了灵活的双轨方案：核心工程引入 SeaORM 以获得 ORM 能力，同时提供 SQL 插件（基于 sqlx）以适配多数据库与桌面应用场景。通过迁移脚本管理、合理的表结构与索引设计、以及应用层缓存策略，整体具备良好的可维护性与扩展性。建议在生产环境中进一步完善连接池参数、事务边界与监控告警，持续优化查询与索引策略。

## 附录
- 命令清单（部分）
  - 查询与执行：query_sqlite、execute_sqlite、batch_execute_sqlite
  - 事务：execute_transaction
  - 初始化：init_database_pool、init_all_database_tables、init_database_table
  - 表管理：get_table_info、get_all_tables
  - 状态检查：check_database_status
- 相关文件路径
  - `src-tauri/src/lib.rs#L136-L144`
  - `src-tauri/sql/ths_api_cache_table.sql#L1-L21`

章节来源
- `src-tauri/src/lib.rs#L136-L144`
- `src-tauri/sql/ths_api_cache_table.sql#L1-L21`