发现问题: 数据库建表、改表脚本分散在多个位置,存在重复、遗漏和不一致
严重程度: 🟡 中等(不影响功能,但影响可维护性)
建议: 统一所有DDL操作到 database/migration.sql
- 行数: ~190行 CREATE TABLE + ALTER TABLE
- 表数量: 16个表定义
- 问题:
- ❌ 在应用初始化时执行,不是集中管理
- ❌ 包含应该在migration中的表定义
- ❌ ALTER TABLE添加列逻辑混乱(已部分修复)
- ❌ 包含复杂的表迁移逻辑(ai_models 重命名)
config/database.go 中的16个表:
ai_models
audit_logs
beta_codes
credit_packages
credit_transactions
exchanges
kelly_stats ⚠️ (遗漏)
login_attempts
news_feed_state ⚠️ (遗漏)
password_resets
system_config
trade_records ⚠️ (遗漏)
traders
user_credits
user_signal_sources
users
- 行数: 281行
- 表数量: 6个表(旧SQLite到PostgreSQL迁移脚本)
- 表:
- users
- exchanges
- ai_models
- performance_snapshots
- trade_snapshots
- ...
问题: 与current migration.sql中的schema不一致,定义已过时
包含逐步增量迁移:
- 20251201_add_web3_wallets
- 20251201_credits
- 20251211_invitation_system
- 20251216_ai_learning_phase1
- 20251222_mem0_integration_config
- 20251223_gemini_config_integration
- 20251228_crossmint_payment
问题: 这些已被集成到migration.sql,仍然存在可能导致混淆
✗ kelly_stats - Kelly公式统计(缓存)
✗ news_feed_state - 新闻源状态
✗ trade_records - 交易记录(Kelly学习用)
✓ credit_compensation_tasks
✓ credit_reservations
✓ learning_reflections
✓ parameter_change_history
✓ payment_orders
✓ trade_analysis_records
✓ user_news_config
✓ user_wallets
✓ web3_wallet_nonces
✓ web3_wallets
// config/database.go 第219行
CREATE TABLE IF NOT EXISTS users (...)
// database/migration.sql 第15行
CREATE TABLE IF NOT EXISTS users (...)
// 结果: 两个地方都试图创建同一个表// config/database.go 有,migration.sql 没有:
- kelly_stats
- news_feed_state
- trade_records- ❌ 建表在 config/database.go
- ❌ 列添加在 config/database.go alterTables()
- ❌ 索引创建分散
- ❌ 约束创建分散
- ❌ 旧迁移脚本仍然存在
// config/database.go 中的复杂逻辑:
func (d *Database) migrateAIModelsTable() {
// 重命名旧表
ALTER TABLE ai_models RENAME TO ai_models_old
// 创建新表
CREATE TABLE ai_models (...)
// 迁移数据
INSERT INTO ai_models SELECT ... FROM ai_models_old
// 删除旧表
DROP TABLE ai_models_old
}这些应该在migration.sql中处理,或者根本不需要
在 database/migration.sql 的Part 5或新的Part中添加:
-- Part 6: 性能统计和交易记录表
CREATE TABLE IF NOT EXISTS trade_records (
id BIGSERIAL PRIMARY KEY,
trader_id TEXT NOT NULL,
symbol TEXT NOT NULL,
entry_price DECIMAL(18,8) NOT NULL,
exit_price DECIMAL(18,8) NOT NULL,
profit_pct DECIMAL(10,6) NOT NULL,
leverage INTEGER DEFAULT 1,
holding_time_seconds BIGINT DEFAULT 0,
margin_mode TEXT DEFAULT 'cross',
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS kelly_stats (
id BIGSERIAL PRIMARY KEY,
trader_id TEXT NOT NULL,
symbol TEXT NOT NULL,
total_trades INTEGER DEFAULT 0,
profitable_trades INTEGER DEFAULT 0,
win_rate DECIMAL(10,6) DEFAULT 0,
avg_win_pct DECIMAL(10,6) DEFAULT 0,
avg_loss_pct DECIMAL(10,6) DEFAULT 0,
max_profit_pct DECIMAL(10,6) DEFAULT 0,
max_drawdown_pct DECIMAL(10,6) DEFAULT 0,
volatility DECIMAL(10,6) DEFAULT 0,
weighted_win_rate DECIMAL(10,6) DEFAULT 0,
updated_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(trader_id, symbol)
);
CREATE TABLE IF NOT EXISTS news_feed_state (
category TEXT PRIMARY KEY,
last_id BIGINT DEFAULT 0,
last_timestamp BIGINT DEFAULT 0,
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- 索引
CREATE INDEX IF NOT EXISTS idx_trade_records_trader ON trade_records(trader_id);
CREATE INDEX IF NOT EXISTS idx_trade_records_symbol ON trade_records(symbol);
CREATE INDEX IF NOT EXISTS idx_kelly_stats_trader ON kelly_stats(trader_id);移除 createTables() 函数中的所有表定义,改为:
func (d *Database) createTables() error {
// 注意: 所有表定义现在在 database/migration.sql 中
// 此函数仅用于遗留兼容性,实际创建由migration脚本处理
// 如果使用SQLite(旧方式),从database/migration.sql创建
// 如果使用PostgreSQL(新方式),由go run cmd/db-migrate/main.go 处理
return nil
}删除表迁移逻辑(如ai_models的重命名),仅保留向后兼容的列添加
database/migrations/
├── _archive/
│ ├── 20251201_add_web3_wallets/
│ ├── 20251201_credits/
│ └── ...
└── README.md (说明这些已集成到migration.sql)
在 DATABASE_SCHEMA.md 添加说明:
## 数据库初始化方式
### 新方式(推荐)
使用统一的迁移脚本:
- `database/migration.sql` - 完整的schema定义
- `cmd/db-migrate/main.go` - 执行工具
- `.env` - 连接配置
### 旧方式(遗留)
- `config/database.go` - 应用启动时创建表(兼容SQLite)
- `database/migrate.go` - SQLite → PostgreSQL迁移脚本| 文件 | 操作 | 优先级 | 影响 |
|---|---|---|---|
| database/migration.sql | 添加3个遗漏的表 | 🔴 高 | 确保Kelly统计和交易记录功能 |
| config/database.go | 清理createTables() | 🟡 中 | 代码整洁,减少维护负担 |
| config/database.go | 简化alterTables() | 🟡 中 | 避免表迁移重复 |
| database/migrations/ | 存档到_archive | 🟢 低 | 历史记录保留 |
| DATABASE_SCHEMA.md | 添加初始化说明 | 🟢 低 | 用户指导 |
- 修改 database/migration.sql
- 添加 trade_records 表
- 添加 kelly_stats 表
- 添加 news_feed_state 表
- 添加对应的索引
-
go run cmd/db-reset/main.go(清空) -
go run cmd/db-migrate/main.go(迁移) -
go run cmd/db-verify/main.go(验证) - 确认3个新表被创建
- 评估是否仍需要createTables()
- 如需要,改为验证表存在而不是创建
- 删除过时的表迁移逻辑
- 更新 DATABASE_SCHEMA.md
- 添加3个新表的文档
- 说明旧migration脚本已archived
✅ 统一的schema定义位置 ✅ 减少重复代码 ✅ 提高可维护性 ✅ 清晰的初始化流程 ✅ 防止未来的schema不同步
- 如果新tables有问题,使用
go run cmd/db-reset/main.go重新开始 - 旧代码保留注释说明来源(config/database.go)
修复前:
❌ 建表代码分散在3个地方
❌ 3个表缺失在migration.sql
❌ config/database.go混合了DDL和应用逻辑
❌ migration脚本难以追踪
❌ 难以维护和一致性验证
修复后:
✅ 所有建表代码集中在 database/migration.sql
✅ 完整的25张表定义(23原有 + 3新增)
✅ config/database.go 仅做backward compatibility
✅ 清晰的migration脚本历史(archived)
✅ 单一事实来源(SSOT)原则
- 优先修复 database/migration.sql - 添加3个遗漏的表
- 可选清理 config/database.go - 代码结构优化
- 保留兼容 - 保持config/database.go中的createTables()以支持SQLite本地开发
- 充分测试 - 在PostgreSQL上验证所有migration和verify工具
预计工作量: 2-3小时 优先级: 🟡 中等(不紧急,但需要做) 最佳时机: 当前(已完成统一migration.sql)
分析日期: 2026-01-15 分析版本: Ultrathink v1 状态: 准备实施