- 系统架构总览:技术栈、目录结构、数据流向 - 指标引擎详解:16个指标完整原理与参数(含源码行号) - 信号评分引擎:多指标共振评分机制、动态阈值、案例分析 - 大周期偏向判定:assessBigTimeframeBias 完整说明 - EWO转换检测机制:evaluateEwoTurnForUser 逐步流程 - 飞书通知格式规范:三类通知完整格式模板 - 类型系统参考:所有 TypeScript 类型完整文档 - 数据库与存储:MySQL 表结构、缓存机制、维护指南 - 部署运维指南:Docker Compose、Nginx、飞书配置 - 开发历史与TODO:功能状态表、优先级路线图 - 优化建议汇总:9项优化建议含源码位置和预期效果
208 行
5.4 KiB
Markdown
208 行
5.4 KiB
Markdown
# tradehk 数据库与存储
|
||
|
||
> 返回:[tradehk 文档中心](./README.md)
|
||
> 源文件:`drizzle/schema.ts`、`server/db.ts`、`server/storage.ts`
|
||
|
||
## 概述
|
||
|
||
tradehk 使用 MySQL 8.0 作为持久化存储,通过 Drizzle ORM 进行类型安全的数据库操作。主要存储:用户信息、用户配置、监控列表、交易信号记录。
|
||
|
||
---
|
||
|
||
## 数据库表结构
|
||
|
||
### users 表(用户)
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| id | INT AUTO_INCREMENT | 主键 |
|
||
| name | VARCHAR(255) | 显示名称 |
|
||
| username | VARCHAR(255) UNIQUE | 用户名 |
|
||
| email | VARCHAR(255) UNIQUE | 邮箱 |
|
||
| passwordHash | VARCHAR(255) | 密码哈希(bcrypt)|
|
||
| createdAt | DATETIME | 创建时间 |
|
||
| updatedAt | DATETIME | 更新时间 |
|
||
|
||
---
|
||
|
||
### user_settings 表(用户配置)
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| id | INT AUTO_INCREMENT | 主键 |
|
||
| userId | INT | 外键 → users.id |
|
||
| configJson | TEXT | JSON 格式的完整用户配置(UserConfig) |
|
||
| updatedAt | DATETIME | 更新时间 |
|
||
|
||
**configJson 结构**:存储 `UserConfig` 的完整 JSON 序列化,包含时区、指标参数、通知配置、EWO 规则等。
|
||
|
||
---
|
||
|
||
### watchlist 表(监控列表)
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| id | INT AUTO_INCREMENT | 主键 |
|
||
| userId | INT | 外键 → users.id |
|
||
| symbol | VARCHAR(20) | 交易对(如 "BTCUSDT")|
|
||
| isActive | BOOLEAN | 是否在活跃监控列表中 |
|
||
| sortOrder | INT | 排列顺序 |
|
||
| createdAt | DATETIME | 创建时间 |
|
||
|
||
---
|
||
|
||
### signals 表(交易信号记录)
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| id | INT AUTO_INCREMENT | 主键 |
|
||
| userId | INT | 外键 → users.id |
|
||
| symbol | VARCHAR(20) | 交易对 |
|
||
| interval | VARCHAR(10) | K线周期(如 "10m")|
|
||
| direction | ENUM('long','short') | 信号方向 |
|
||
| strength | ENUM('strong','medium','weak') | 信号强度 |
|
||
| score | INT | 信号评分(80/50/30)|
|
||
| price | DECIMAL(20,8) | 信号价格 |
|
||
| ewo | DECIMAL(20,8) | EWO 值(可空)|
|
||
| macd | DECIMAL(20,8) | MACD 值(可空)|
|
||
| macdSignal | DECIMAL(20,8) | MACD 信号线值(可空)|
|
||
| macdHist | DECIMAL(20,8) | MACD 柱状图值(可空)|
|
||
| ao | DECIMAL(20,8) | AO 值(可空)|
|
||
| reasons | TEXT | JSON 字符串,原因列表(可空)|
|
||
| signalAt | BIGINT | 信号时间戳(毫秒)|
|
||
| createdAt | DATETIME | 记录创建时间 |
|
||
|
||
**索引**:`(userId, symbol, interval, direction, signalAt)` 联合唯一索引,用于信号去重。
|
||
|
||
---
|
||
|
||
## 内存缓存(pairCache / tickerCache)
|
||
|
||
除 MySQL 外,tradehk 还维护两个内存缓存:
|
||
|
||
### pairCache(K线缓存)
|
||
|
||
```typescript
|
||
Map<string, {
|
||
candles: Candle[]; // 最多 CACHE_CANDLE_LIMIT(300) 根 K 线
|
||
updatedAt: number; // 最后更新时间戳
|
||
}>
|
||
```
|
||
|
||
**键格式**:`"{symbol}__{interval}"`,如 `"BTCUSDT__10m"`
|
||
|
||
**更新时机**:每次引擎轮询时,通过 `refreshCacheForPairs` 从 Binance API 拉取最新数据。
|
||
|
||
### tickerCache(行情缓存)
|
||
|
||
```typescript
|
||
Map<string, {
|
||
price: number; // 最新价格
|
||
change24h: number; // 24小时涨跌幅
|
||
volume24h: number; // 24小时成交量
|
||
updatedAt: number; // 最后更新时间戳
|
||
}>
|
||
```
|
||
|
||
**键格式**:`"{symbol}"`,如 `"BTCUSDT"`
|
||
|
||
---
|
||
|
||
## 关键数据库操作
|
||
|
||
### 信号去重检查
|
||
|
||
```typescript
|
||
// hasSignalRecord 函数
|
||
// 检查同一用户、同一币对、同一方向、同一时间戳的信号是否已存在
|
||
SELECT COUNT(*) FROM signals
|
||
WHERE userId = ? AND symbol = ? AND interval = ?
|
||
AND direction = ? AND signalAt = ?
|
||
```
|
||
|
||
### 信号窗口查询
|
||
|
||
```typescript
|
||
// getSignalsInWindow 函数
|
||
// 用于定期汇总通知
|
||
SELECT * FROM signals
|
||
WHERE userId = ? AND signalAt BETWEEN ? AND ?
|
||
ORDER BY signalAt DESC
|
||
LIMIT ?
|
||
```
|
||
|
||
### EWO 转换去重槽
|
||
|
||
EWO 转换去重使用 Redis 风格的共享槽(实际存储在 MySQL 的 `dedup_slots` 表中):
|
||
|
||
```typescript
|
||
// consumeSharedEwoTurnDedupeSlot 函数
|
||
// 原子性地检查并占用去重槽
|
||
// 返回 true 表示允许推送,false 表示已推送过
|
||
```
|
||
|
||
---
|
||
|
||
## 数据库维护
|
||
|
||
### 数据增长估算
|
||
|
||
假设监控 10 个币对,每个币对每小时产生 2 个信号:
|
||
|
||
| 时间 | 信号记录数 | 磁盘占用(估算)|
|
||
|------|-----------|----------------|
|
||
| 1 天 | 480 条 | < 1 MB |
|
||
| 1 周 | 3,360 条 | < 5 MB |
|
||
| 1 月 | 14,400 条 | < 20 MB |
|
||
| 1 年 | 175,200 条 | < 250 MB |
|
||
|
||
**结论**:signals 表增长缓慢,一般不需要特别清理。但如果监控大量币对或使用高频周期,建议设置定期清理任务。
|
||
|
||
### 清理过期信号
|
||
|
||
```sql
|
||
-- 清理30天前的信号记录
|
||
DELETE FROM signals
|
||
WHERE signalAt < UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 30 DAY)) * 1000;
|
||
```
|
||
|
||
### 数据库备份
|
||
|
||
```bash
|
||
# 完整备份
|
||
docker compose exec mysql mysqldump -u root -p tradehk > backup_$(date +%Y%m%d).sql
|
||
|
||
# 只备份 signals 表
|
||
docker compose exec mysql mysqldump -u root -p tradehk signals > signals_backup_$(date +%Y%m%d).sql
|
||
```
|
||
|
||
---
|
||
|
||
## Drizzle ORM 使用说明
|
||
|
||
tradehk 使用 Drizzle ORM 进行类型安全的数据库操作。
|
||
|
||
### 运行迁移
|
||
|
||
```bash
|
||
# 生成迁移文件
|
||
pnpm drizzle-kit generate
|
||
|
||
# 执行迁移
|
||
pnpm drizzle-kit migrate
|
||
```
|
||
|
||
### 查看迁移历史
|
||
|
||
```bash
|
||
ls drizzle/migrations/
|
||
```
|
||
|
||
---
|
||
|
||
## 相关文档
|
||
|
||
- [系统架构总览](./系统架构总览.md) — 数据流向
|
||
- [类型系统参考](./类型系统参考.md) — Signal 类型定义
|
||
- [部署运维指南](./部署运维指南.md) — 数据库备份和维护
|