# 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) ```sql -- 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 的 `` 标签在应用层聚合。 #### 查询 2:部门树递归查询 ```sql -- SysUserMapper.xml: deptId 条件 SELECT t.dept_id FROM sys_dept t WHERE find_in_set(#{deptId}, ancestors) ``` **分析**:使用 `find_in_set` 函数进行字符串匹配,无法使用索引,全表扫描。 #### 查询 3:数据范围过滤 ```sql -- 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(必须修复) 1. **主键类型修正**:将所有业务表的 `id double` 改为 `id bigint(20) NOT NULL AUTO_INCREMENT` ```sql ALTER TABLE stocks MODIFY COLUMN id bigint(20) NOT NULL AUTO_INCREMENT; ``` 2. **添加核心查询索引**: ```sql -- 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); ``` 3. **trade_dates 表添加主键**: ```sql ALTER TABLE trade_dates ADD PRIMARY KEY (date); ``` #### P1(建议修复) 4. **修复 statistics 表字段**:合并 `operations_id` 和 `operateion_id` 为统一的外键字段 5. **时间查询优化**:将 `date_format(u.create_time,'%y%m%d') >= ?` 改为范围查询: ```sql AND u.create_time >= #{params.beginTime} AND u.create_time < DATE_ADD(#{params.endTime}, INTERVAL 1 DAY) ``` 6. **部门树查询优化**:考虑使用闭包表(Closure Table)或物化路径的整数数组类型替代 `find_in_set` #### P2(可选改进) 7. **添加审计字段**:为所有业务表添加 create_by, create_time, update_by, update_time 8. **添加软删除**:为业务表添加 del_flag 字段 9. **大字段分离**:将 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 (操作快照) │ │ │ └──────────────────────────────────────────────────────────┘ │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` --- *文档结束*