25 KiB
RuoYi-Vue 数据库结构分析
分析日期:2026-06-28
数据来源:建表 SQL 文件、Mapper XML 文件、Domain 实体类
1. 表结构清单
1.1 系统管理表(sys_* / gen_* / QRTZ_*)
系统管理表位于 ry 数据库,由 RuoYi 框架提供。
| 表名 | 字段数 | 主键 | 用途 | 备注 |
|---|---|---|---|---|
sys_user |
18 | user_id (bigint, AI) | 用户信息表 | 含 del_flag 软删除 |
sys_dept |
12 | dept_id (bigint, AI) | 部门表 | 树形结构,含 ancestors |
sys_role |
13 | role_id (bigint, AI) | 角色信息表 | 含 data_scope 数据权限 |
sys_menu |
17 | menu_id (bigint, AI) | 菜单权限表 | 树形结构,M/C/F 三种类型 |
sys_post |
9 | post_id (bigint, AI) | 岗位信息表 | - |
sys_dict_type |
9 | dict_id (bigint, AI) | 字典类型表 | 唯一索引: dict_type |
sys_dict_data |
12 | dict_code (bigint, AI) | 字典数据表 | 关联 dict_type |
sys_config |
9 | config_id (int, AI) | 参数配置表 | - |
sys_notice |
9 | notice_id (int, AI) | 通知公告表 | content 使用 longblob |
sys_oper_log |
15 | oper_id (bigint, AI) | 操作日志记录 | 大表,高频写入 |
sys_logininfor |
8 | info_id (bigint, AI) | 系统访问记录 | 登录日志 |
sys_job |
12 | (job_id, job_name, job_group) 联合主键 | 定时任务调度表 | - |
sys_job_log |
7 | job_log_id (bigint, AI) | 定时任务调度日志 | - |
sys_user_role |
2 | (user_id, role_id) 联合主键 | 用户-角色关联表 | 多对多中间表 |
sys_role_menu |
2 | (role_id, menu_id) 联合主键 | 角色-菜单关联表 | 多对多中间表 |
sys_role_dept |
2 | (role_id, dept_id) 联合主键 | 角色-部门关联表 | 多对多中间表 |
sys_user_post |
2 | (user_id, post_id) 联合主键 | 用户-岗位关联表 | 多对多中间表 |
gen_table |
17 | table_id (bigint, AI) | 代码生成业务表 | - |
gen_table_column |
21 | column_id (bigint, AI) | 代码生成业务表字段 | - |
QRTZ_JOB_DETAILS |
10 | (sched_name, job_name, job_group) | Quartz 任务详情 | 外键关联 |
QRTZ_TRIGGERS |
14 | (sched_name, trigger_name, trigger_group) | Quartz 触发器 | FK → QRTZ_JOB_DETAILS |
QRTZ_SIMPLE_TRIGGERS |
6 | (sched_name, trigger_name, trigger_group) | Quartz 简单触发器 | FK → QRTZ_TRIGGERS |
QRTZ_CRON_TRIGGERS |
5 | (sched_name, trigger_name, trigger_group) | Quartz Cron 触发器 | FK → QRTZ_TRIGGERS |
QRTZ_BLOB_TRIGGERS |
4 | (sched_name, trigger_name, trigger_group) | Quartz Blob 触发器 | FK → QRTZ_TRIGGERS |
QRTZ_CALENDARS |
3 | (sched_name, calendar_name) | Quartz 日历 | - |
QRTZ_FIRED_TRIGGERS |
11 | (sched_name, entry_id) | Quartz 已触发触发器 | - |
QRTZ_PAUSED_TRIGGER_GRPS |
2 | (sched_name, trigger_group) | Quartz 暂停触发器组 | - |
QRTZ_SCHEDULER_STATE |
5 | (sched_name, instance_name) | Quartz 调度器状态 | - |
QRTZ_LOCKS |
2 | (sched_name, lock_name) | Quartz 锁表 | - |
QRTZ_SIMPROP_TRIGGERS |
8 | (sched_name, trigger_name, trigger_group) | Quartz 简单属性触发器 | FK → QRTZ_TRIGGERS |
1.2 股票业务表(nstocks 数据库)
| 表名 | 字段数 | 主键 | 用途 | 备注 |
|---|---|---|---|---|
stocks |
15 | id (double, AI) | 全部 A 股每日交易数据 | 核心行情表,AUTO_INCREMENT=82694 |
stocks_tmp |
7 | id (double, AI) | 全部 A 股每日交易数据辅助表 | 临时/辅助计算表 |
stock_index |
23 | id (double, AI) | 指数交易行情 | AUTO_INCREMENT=82694 |
stock_financial |
9 | id (double, AI) | A 股财务数据 | AUTO_INCREMENT=137032 |
stock_basis |
15 | id (double, AI) | A 股基础信息 | 大文件(521KB),含上市日期等 |
stocks_in_trend |
5 | id (double, AI) | 动量个股 | 关联 trends 表 |
stocks_limit_up |
3 | id (double, AI) | 每日涨停板 | 仅 code + trade_day |
trends |
9 | id (double, AI) | 动量结果(板块级别) | 含板块排名 |
industries |
5 | id (double, AI) | 东财行业 2 级每日数据 | - |
industries_basis |
3 | id (double, AI) | 东财行业 2 级基础信息 | 行业字典表 |
trade_dates |
3 | 无主键 | 可交易日期日历 | 包含节假日信息 |
1.3 账户/记账业务表(ry 数据库)
| 表名 | 字段数 | 主键 | 用途 | 备注 |
|---|---|---|---|---|
account |
9 | id (double, AI) | 账户每日统计 | 净资产、总资产、盈亏 |
account_book |
14 | id (double, AI) | 操作记录表(交易记) | 对应 Operations 实体 |
operations |
16 | id (double, AI) | 操作表(含账户转入转出) | 含 deal_logic 操作逻辑 |
statistics |
10 | id (double, AI) | 交易统计表单笔操作 | 清仓时统计 |
statistics_remain |
10 | id (double, AI) | 统计表当日持仓 | 包含当日清仓 |
statistics_total |
16 | id (double, AI) | 统计表清仓后汇总 | 总盈亏、总手续费等 |
1.4 分类统计
| 分类 | 表数量 | 占比 |
|---|---|---|
| 系统管理表 | 21 | 42% |
| Quartz 定时任务表 | 9 | 18% |
| 股票业务表 | 11 | 22% |
| 账户/记账业务表 | 6 | 12% |
| 代码生成表 | 2 | 4% |
| 合计 | ~49 | 100% |
2. 表关系
2.1 系统管理模块关系图
┌─────────────┐ ┌───────────────┐ ┌─────────────┐
│ sys_dept │◄─────│ sys_user │─────►│ sys_post │
│ (部门树) │ │ (用户信息) │ │ (岗位) │
└──────┬──────┘ └──────┬────────┘ └──────┬──────┘
│ │ │
│ ┌─────┴─────┐ ┌─────┴──────┐
│ │sys_user_ │ │sys_user_ │
│ │ role │ │ post │
│ │(N-M 中间) │ │(N-M 中间) │
│ └─────┬─────┘ └────────────┘
│ │
│ ┌─────┴─────┐ ┌─────────────┐
└─────────────►│ sys_role │◄─────│ sys_role_ │
│ (角色) │ │ dept │
└─────┬─────┘ │(N-M 中间) │
│ └─────────────┘
┌─────┴─────┐
│sys_role_ │ ┌─────────────┐
│ menu │◄─────│ sys_menu │
│(N-M 中间) │ │ (菜单树) │
└───────────┘ └─────────────┘
2.2 股票业务模块关系图
┌──────────────────┐ ┌───────────────┐ ┌──────────────────┐
│ stock_basis │ │ stocks │ │ stock_financial │
│ (股票基础信息) │ │ (每日行情) │ │ (财务数据) │
└────────┬─────────┘ └───────┬───────┘ └──────────────────┘
│ │
│ code(逻辑关联) │ code + trade_day
│ │
▼ ▼
┌──────────────────┐ ┌───────────────┐ ┌──────────────────┐
│ industries_ │ │ stock_index │ │ stocks_in_trend │
│ basis │ │ (指数行情) │ │ (动量个股) │
│ (行业字典) │ └───────────────┘ └────────┬─────────┘
└────────┬─────────┘ │
│ code + trade_day
│ │
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ industries │ │ trends │
│ (行业每日数据) │◄──── blemind2 关联 ──────│ (板块动量排名) │
└──────────────────┘ └──────────────────┘
┌──────────────────┐ ┌───────────────┐
│ trade_dates │ │stocks_limit_up│
│ (交易日历) │ │ (涨停板) │
└──────────────────┘ └───────────────┘
2.3 账户/记账模块关系图
┌─────────────┐ ┌───────────────┐ ┌─────────────┐
│ account │ │ operations │◄───►│account_book │
│ (账户统计) │ │ (操作记录) │ │ (交易记录) │
└─────────────┘ └───────┬───────┘ └─────────────┘
user_id │ pre_id
│
┌─────────────┼─────────────┐
▼ ▼ ▼
┌──────────┐ ┌───────────┐ ┌─────────────┐
│statistics │ │statistics │ │statistics_ │
│ (单笔统计)│ │ _remain │ │ total │
│ │ │(当日持仓) │ │(清仓汇总) │
└──────────┘ └───────────┘ └─────────────┘
user_id user_id user_id
2.4 外键约束分析
| 表名 | 外键字段 | 引用表 | 引用字段 | 约束类型 |
|---|---|---|---|---|
| QRTZ_TRIGGERS | (sched_name, job_name, job_group) | QRTZ_JOB_DETAILS | 主键 | 物理外键 |
| QRTZ_SIMPLE_TRIGGERS | (sched_name, trigger_name, trigger_group) | QRTZ_TRIGGERS | 主键 | 物理外键 |
| QRTZ_CRON_TRIGGERS | (sched_name, trigger_name, trigger_group) | QRTZ_TRIGGERS | 主键 | 物理外键 |
| QRTZ_BLOB_TRIGGERS | (sched_name, trigger_name, trigger_group) | QRTZ_TRIGGERS | 主键 | 物理外键 |
| QRTZ_SIMPROP_TRIGGERS | (sched_name, trigger_name, trigger_group) | QRTZ_TRIGGERS | 主键 | 物理外键 |
注意:系统管理表和业务表之间 没有物理外键约束,全部采用逻辑关联(通过代码层 JOIN 实现)。
2.5 多对多关系表
| 中间表 | 关联实体 1 | 关联实体 2 | 用途 |
|---|---|---|---|
sys_user_role |
sys_user | sys_role | 用户角色分配 |
sys_role_menu |
sys_role | sys_menu | 角色菜单权限 |
sys_role_dept |
sys_role | sys_dept | 角色数据权限范围 |
sys_user_post |
sys_user | sys_post | 用户岗位分配 |
3. 索引分析
3.1 主键索引清单
| 表名 | 主键类型 | 主键字段 | 自增 |
|---|---|---|---|
| sys_user | 单列 | user_id (bigint) | ✅ |
| sys_dept | 单列 | dept_id (bigint) | ✅ |
| sys_role | 单列 | role_id (bigint) | ✅ |
| sys_menu | 单列 | menu_id (bigint) | ✅ |
| sys_post | 单列 | post_id (bigint) | ✅ |
| sys_dict_type | 单列 | dict_id (bigint) | ✅ |
| sys_dict_data | 单列 | dict_code (bigint) | ✅ |
| sys_config | 单列 | config_id (int) | ✅ |
| sys_notice | 单列 | notice_id (int) | ✅ |
| sys_oper_log | 单列 | oper_id (bigint) | ✅ |
| sys_logininfor | 单列 | info_id (bigint) | ✅ |
| sys_job | 联合 | (job_id, job_name, job_group) | job_id 自增 |
| sys_job_log | 单列 | job_log_id (bigint) | ✅ |
| sys_user_role | 联合 | (user_id, role_id) | ❌ |
| sys_role_menu | 联合 | (role_id, menu_id) | ❌ |
| sys_role_dept | 联合 | (role_id, dept_id) | ❌ |
| sys_user_post | 联合 | (user_id, post_id) | ❌ |
| stocks | 单列 | id (double) | ✅ |
| stock_index | 单列 | id (double) | ✅ |
| trade_dates | 无主键 | - | ❌ |
3.2 唯一索引
| 表名 | 索引字段 | 说明 |
|---|---|---|
| sys_dict_type | dict_type | 字典类型编码唯一 |
| sys_user | 无唯一索引 | 用户名/手机/邮箱仅有应用层校验 |
3.3 普通索引 / 复合索引
大部分业务表缺少索引,仅有主键索引。以下表没有除主键外的任何索引:
stocks— 15 字段,仅有主键stock_index— 23 字段,仅有主键stock_financial— 9 字段,仅有主键operations— 16 字段,仅有主键statistics— 10 字段,仅有主键statistics_remain— 10 字段,仅有主键statistics_total— 16 字段,仅有主键trade_dates— 无主键、无索引
3.4 索引使用情况评估
| 表名 | 索引覆盖度 | 评价 |
|---|---|---|
| sys_dict_type | ★★★☆☆ | 有唯一索引,但缺少 status 索引 |
| sys_user | ★★☆☆☆ | 缺少 userName、phone、email 索引 |
| sys_oper_log | ★☆☆☆☆ | 缺少 oper_time、oper_name 索引 |
| stocks | ★☆☆☆☆ | 缺少 code、trade_day 索引 |
| trade_dates | ☆☆☆☆☆ | 无主键无索引 |
4. 查询模式
4.1 常用查询模式
系统管理模块
| 查询场景 | 涉及表 | 查询方式 | 典型条件 |
|---|---|---|---|
| 用户登录 | sys_user | 等值查询 | user_name = ? |
| 用户列表 | sys_user + sys_dept | LEFT JOIN + 模糊查询 | del_flag='0', LIKE 姓名/手机 |
| 用户详情 | sys_user + sys_dept + sys_user_role + sys_role | 多表 LEFT JOIN | user_id = ? |
| 角色已分配用户 | sys_user + sys_dept + sys_user_role + sys_role | 多表 JOIN + DISTINCT | role_id = ? |
| 角色未分配用户 | sys_user + sys_dept + sys_user_role + sys_role | NOT IN 子查询 | role_id != ? |
| 部门树查询 | sys_dept | 递归/ancestors LIKE | parent_id = ? |
| 菜单树查询 | sys_menu | 递归/parent_id | parent_id = ? |
| 操作日志 | sys_oper_log | 分页 + 时间范围 | oper_time BETWEEN |
| 登录日志 | sys_logininfor | 分页 + 时间范围 | login_time BETWEEN |
| 字典查询 | sys_dict_type + sys_dict_data | 等值关联 | dict_type = ? |
股票业务模块
| 查询场景 | 涉及表 | 查询方式 | 典型条件 |
|---|---|---|---|
| 股票行情查询 | stocks | 等值 + 范围 | code = ?, trade_day = ? |
| 区间涨跌幅查询 | stocks | 范围查询 | differrange10/20/60 BETWEEN |
| 动量个股查询 | stocks_in_trend + trends | code 关联 | trade_day = ?, type = ? |
| 涨停板查询 | stocks_limit_up | 等值 | trade_day = ? |
| 财务数据查询 | stock_financial | 等值 + 排序 | code = ?, period = ? |
| 指数行情查询 | stock_index | 等值 + 范围 | code = ?, trade_day = ? |
账户记账模块
| 查询场景 | 涉及表 | 查询方式 | 典型条件 |
|---|---|---|---|
| 账户统计 | account | 等值查询 | trade_day = ?, user_id = ? |
| 操作记录 | operations | 等值 + 模糊 | code = ?, name LIKE, trade_day = ? |
| 当日持仓统计 | statistics_remain | 等值 | code = ?, trade_day = ?, user_id = ? |
| 清仓汇总统计 | statistics_total | 等值 | code = ?, user_id = ? |
| 单笔统计 | statistics | 等值 | code = ?, operations_id = ? |
4.2 复杂关联查询
查询 1:用户详情(4 表 JOIN)
-- SysUserMapper.xml: selectUserVo
SELECT u.*, d.*, r.*
FROM sys_user u
LEFT JOIN sys_dept d ON u.dept_id = d.dept_id
LEFT JOIN sys_user_role ur ON u.user_id = ur.user_id
LEFT JOIN sys_role r ON r.role_id = ur.role_id
WHERE u.user_name = ?
分析:4 表 LEFT JOIN,sys_user_role 和 sys_role 的 JOIN 会产生笛卡尔积膨胀(一个用户多个角色时返回多行),由 MyBatis 的 <collection> 标签在应用层聚合。
查询 2:部门树递归查询
-- SysUserMapper.xml: deptId 条件
SELECT t.dept_id FROM sys_dept t
WHERE find_in_set(#{deptId}, ancestors)
分析:使用 find_in_set 函数进行字符串匹配,无法使用索引,全表扫描。
查询 3:数据范围过滤
-- SysUserMapper.xml: dataScope
${params.dataScope} -- 动态 SQL 拼接
分析:使用 ${} 直接拼接 SQL,存在 SQL 注入风险(虽然框架层有控制)。
4.3 统计查询
| 统计场景 | 涉及表 | 说明 |
|---|---|---|
| 账户每日盈亏 | account | 按 trade_day 聚合 assets_diff |
| 个股总盈亏 | statistics_total | 按 code + user_id 汇总 total_profit |
| 持仓盈亏 | statistics_remain | 按 trade_day 汇总 total_profit |
| 板块排名 | trends | 按 sort 排序 |
4.4 性能瓶颈识别
| 瓶颈 | 位置 | 严重程度 | 说明 |
|---|---|---|---|
find_in_set 查询 |
sys_dept.ancestors | 🔴 高 | 全表扫描,无法利用索引 |
| 日期格式化查询 | sys_user.create_time | 🟡 中 | date_format(u.create_time,'%y%m%d') 导致索引失效 |
| LIKE 前缀通配符 | 多处 name/phone | 🟡 中 | LIKE '%keyword%' 无法使用索引 |
| 大表无索引 | stocks, stock_index | 🔴 高 | 8 万+ 记录表仅主键索引 |
| NOT IN 子查询 | 未分配用户查询 | 🟡 中 | 可能被 NOT EXISTS 优化 |
| 动态 SQL 拼接 | dataScope | 🟡 中 | 安全风险 + 查询计划不可预测 |
5. 存在的问题
5.1 问题清单
| # | 问题 | 涉及表 | 严重程度 | 影响范围 |
|---|---|---|---|---|
| 1 | 主键使用 double 类型 | 所有业务表(stocks, account, operations, statistics 等) | 🔴 严重 | double 是浮点类型,用于主键可能导致精度问题和性能下降 |
| 2 | trade_dates 表无主键 | trade_dates | 🔴 严重 | 无主键表无法保证数据唯一性,复制和备份可能出错 |
| 3 | 业务表缺少必要索引 | stocks, stock_index, stock_financial, operations 等 | 🔴 严重 | 高频查询字段(code, trade_day)无索引,导致全表扫描 |
| 4 | statistics 表存在字段名拼写错误 | statistics | 🟡 中等 | 同时存在 operations_id(varchar) 和 operateion_id(double) 两个含义相近字段 |
| 5 | 无逻辑外键导致数据一致性风险 | sys_user_role, sys_role_menu, statistics 等 | 🟡 中等 | 删除用户/角色时,关联表数据可能残留 |
| 6 | find_in_set 查询无法利用索引 | sys_dept | 🟡 中等 | 部门树查询性能随数据量线性下降 |
| 7 | date_format 函数导致索引失效 | sys_user, sys_oper_log 等 | 🟡 中等 | 时间范围查询使用 date_format() 包装列 |
| 8 | 缺少审计字段 | 大部分业务表 | 🟢 低 | 业务表缺少 create_by, create_time, update_by, update_time |
| 9 | 缺少软删除机制 | 业务表(stocks, operations 等) | 🟢 低 | 数据删除后无法恢复,不符合审计要求 |
| 10 | 大字段 TEXT/BLOB 无分离 | sys_notice, operations.deal_logic, statistics.bz | 🟢 低 | 大文本字段与主表混合存储,影响查询性能 |
5.2 优化建议
P0(必须修复)
-
主键类型修正:将所有业务表的
id double改为id bigint(20) NOT NULL AUTO_INCREMENTALTER TABLE stocks MODIFY COLUMN id bigint(20) NOT NULL AUTO_INCREMENT; -
添加核心查询索引:
-- stocks 表 ALTER TABLE stocks ADD INDEX idx_code_trade (code, trade_day); ALTER TABLE stocks ADD INDEX idx_trade_day (trade_day); -- stock_index 表 ALTER TABLE stock_index ADD INDEX idx_code_trade (code, trade_day); -- operations 表 ALTER TABLE operations ADD INDEX idx_code_trade (code, trade_day); ALTER TABLE operations ADD INDEX idx_user_id (user_id); -- statistics_remain 表 ALTER TABLE statistics_remain ADD INDEX idx_code_trade (code, trade_day); ALTER TABLE statistics_remain ADD INDEX idx_user_id (user_id); -
trade_dates 表添加主键:
ALTER TABLE trade_dates ADD PRIMARY KEY (date);
P1(建议修复)
-
修复 statistics 表字段:合并
operations_id和operateion_id为统一的外键字段 -
时间查询优化:将
date_format(u.create_time,'%y%m%d') >= ?改为范围查询:AND u.create_time >= #{params.beginTime} AND u.create_time < DATE_ADD(#{params.endTime}, INTERVAL 1 DAY) -
部门树查询优化:考虑使用闭包表(Closure Table)或物化路径的整数数组类型替代
find_in_set
P2(可选改进)
-
添加审计字段:为所有业务表添加 create_by, create_time, update_by, update_time
-
添加软删除:为业务表添加 del_flag 字段
-
大字段分离:将 operations.deal_logic、statistics.bz 等 TEXT 字段移至扩展表
附录:数据库 ER 概览
┌─────────────────────────────────────────────────────────────────┐
│ RuoYi-Vue 数据库概览 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─ 系统管理 (ry) ──────────────────────────────────────────┐ │
│ │ sys_user ←→ sys_dept (树) │ │
│ │ sys_user ←N:M→ sys_role ←N:M→ sys_menu (树) │ │
│ │ sys_user ←N:M→ sys_post │ │
│ │ sys_role ←N:M→ sys_dept │ │
│ │ sys_dict_type ←1:N→ sys_dict_data │ │
│ │ sys_oper_log / sys_logininfor (日志) │ │
│ │ sys_job → sys_job_log (定时任务) │ │
│ │ gen_table ←1:N→ gen_table_column (代码生成) │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ 股票业务 (nstocks) ─────────────────────────────────────┐ │
│ │ stock_basis ←(code)→ stocks ←(code)→ stock_financial │ │
│ │ stocks ←(code)→ stocks_in_trend ←(code)→ trends │ │
│ │ stock_index (独立) │ │
│ │ industries_basis ←(name)→ industries │ │
│ │ stocks_limit_up (独立) │ │
│ │ trade_dates (日历) │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
│ ┌─ 账户记账 (ry) ──────────────────────────────────────────┐ │
│ │ account (每日统计) │ │
│ │ operations ←(pre_id)→ operations (自引用) │ │
│ │ operations ←→ statistics (单笔统计) │ │
│ │ operations ←→ statistics_remain (当日持仓) │ │
│ │ operations ←→ statistics_total (清仓汇总) │ │
│ │ account_book (操作快照) │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
文档结束