简介:这份资源是芋道 ruoyi-vue-pro 企业级快速开发平台的数据库脚本合集,面向使用 Spring Boot 与 Vue 前后端分离架构进行中大型系统开发、二次开发及数据库维护的开发者。包内共 34 个文件,以 22 个 zip 压缩包与 12 个 sql 脚本为主,整体约 143.22MB,涵盖 bpm 工作流、crm 客户管理、erp 企业资源、mall 商城、pay 支付、member 会员、ai 智能模块及报表等业务库的建表与初始化脚本,并附 quartz 定时任务、go-view 大屏等配套 SQL,便于按模块快速搭建数据库结构。已有 1092 人学习下载。借助这些脚本,读者可对照理解各业务模块的表结构、字段设计与模块间关联,快速完成环境初始化,并为系统维护、数据迁移和二次开发提供可靠参考,适合需要完整数据库底座的开发者按需取用。
1. 拿到一份“最全 SQL”先别急着导:它到底补的是哪块拼图
很多团队在搭 ruoyi-vue-pro(芋道那套 Spring Boot + Vue 的后台脚手架)时,卡住的地方往往不是代码跑不起来,而是数据库初始化这一步反复翻车:官方仓库里的 SQL 按模块拆得比较细,版本迭代又快,字段、菜单、字典、定时任务这些初始化数据一旦对不上,前端登录进去菜单是空的,或者后台报字段不存在。这份“最新最全 SQL”资源,本质上就是把多模块、多版本散落的建表与初始化数据收拢成一套可直接执行的脚本集合,解决的是“环境搭起来但数据不全”这个高频痛点。它适合正在做二次开发、需要快速拉起完整功能菜单的初中级后端,也适合想对照表结构理解芋道模块划分的读者。下面按“先看清结构、再动手导入、最后避坑验证”的顺序拆开讲。
2. 拆开 SQL 包看结构:模块划分与执行顺序决定成败
2.1 芋道多模块的表结构是怎么组织的
ruoyi-vue-pro 的数据库设计不是一张大宽表堆出来的,而是按业务域拆成若干模块,常见的有系统基础(用户、角色、菜单、字典、部门、岗位)、基础设施(文件、日志、代码生成、定时任务)、以及可选的业务模块(如支付、商城、工作流等)。每个模块既有建表语句,也有配套的初始化数据(菜单权限、字典项、系统参数)。这份“最全 SQL”的价值就在于把这些模块的 DDL 和 DML 都收齐了,但收齐不等于能乱序执行——模块之间存在外键式依赖,比如菜单表要引用系统应用,角色菜单关联表要引用角色和菜单,字典数据要引用字典类型。执行顺序错了,轻则插入失败,重则数据半残,后面排查起来非常难受。
我一般会先不执行,而是把脚本按“建表 → 基础数据 → 关联数据 → 业务数据”四层过一遍,确认每个文件属于哪一层。常见做法是文件名里带模块前缀和序号,比如01_system.sql、02_infra.sql,如果没有序号,就自己按依赖关系排。下面这段 bash 只是用来快速列出脚本清单和大致内容,帮助你在导入前建立全局视图,不涉及任何平台操作。
# 列出 SQL 目录下所有脚本,按文件名排序,先看清单再决定执行顺序 ls -1 sql/ | sort # 快速查看每个脚本前 20 行,判断是建表还是初始化数据 for f in sql/*.sql; do echo "===== $f =====" head -n 20 "$f" done逻辑说明:第一条命令建立文件清单,排序是为了让带序号的文件自然靠前;第二条循环打印每个文件头部,目的是区分 DDL(CREATE TABLE)和 DML(INSERT),以及识别脚本里是否包含DROP TABLE这类危险语句。参数上没有复杂配置,重点是养成“先看后跑”的习惯。如果你用的是 MySQL 8,注意脚本里字符集是否统一为utf8mb4,排序规则是否和现有库一致,否则跨库导入时容易出现中文乱码或比较规则冲突。
2.2 执行顺序与库名、字符集的硬约束
真正执行时,库名、字符集、SQL 模式这三项必须先定死。芋道的表普遍使用utf8mb4和utf8mb4_general_ci(部分版本用utf8mb4_unicode_ci),如果你的库默认是latin1或者排序规则不一致,导入后关联查询可能报“Illegal mix of collations”。另外 MySQL 8 默认开启了ONLY_FULL_GROUP_BY,某些初始化脚本里的聚合查询在严格模式下会失败,导入阶段虽然不涉及,但后续跑业务 SQL 时会暴露。我的习惯是建库时就把字符集和排序规则显式写死,避免继承服务器默认值。
-- 建库时显式指定字符集与排序规则,避免继承服务器默认配置 CREATE DATABASE `ruoyi-vue-pro` DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci; -- 导入前确认当前库的字符集,和脚本保持一致 SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = 'ruoyi-vue-pro';逻辑说明:第一条语句把库的字符集和排序规则固定下来,utf8mb4保证能存 emoji 和生僻字,排序规则要和脚本里的建表语句对齐;第二条是导入前的自检,如果查出来的排序规则和脚本不一致,就先改库再导入,别等报错再回头。参数上,utf8mb4_general_ci不区分大小写、性能略好,适合大多数后台场景;如果你的业务对大小写敏感,再考虑utf8mb4_bin,但要注意和脚本保持一致,否则关联字段比较会出问题。
执行顺序上,我通常按“系统基础 → 基础设施 → 业务模块”推进,每个模块内部先 DDL 后 DML。如果脚本里混着DROP TABLE IF EXISTS,务必确认这是空库首次导入,别在有数据的库上直接跑。下面是一个按顺序执行的示例,用source逐文件导入,方便定位是哪个文件出错。
# 按依赖顺序逐个导入,出错时能立刻定位到具体文件 mysql -u root -p ruoyi-vue-pro < sql/01_system_ddl.sql mysql -u root -p ruoyi-vue-pro < sql/01_system_data.sql mysql -u root -p ruoyi-vue-pro < sql/02_infra_ddl.sql mysql -u root -p ruoyi-vue-pro < sql/02_infra_data.sql逻辑说明:逐文件导入而不是一次性source整个目录,是为了在某个文件失败时能精确知道停在哪一步,方便回滚或补数据。参数上-u和-p是账号密码,库名放在最后;如果脚本里有USE语句,库名可以省略,但显式指定更稳妥。导入完成后别急着启动应用,先跑一遍表数量核对,确认该有的表都在。
3. 导入后的数据校验:菜单、字典、定时任务三处最容易缺
3.1 用 SQL 自查菜单树和权限关联是否完整
导入成功不等于数据完整。芋道的前端菜单是后端动态下发的,菜单表、角色菜单关联表、权限标识任何一处缺失,登录后都会表现为“菜单空白”或“按钮没权限”。我一般会先查菜单总数和顶级菜单数量,再查角色与菜单的关联是否覆盖了管理员角色。下面这几条查询是导入后的固定动作,能快速判断数据是不是“看起来全、实际残”。
-- 菜单总数与顶级菜单数量,顶级菜单一般对应前端一级导航 SELECT COUNT(*) AS total_menu FROM system_menu; SELECT COUNT(*) AS root_menu FROM system_menu WHERE parent_id = 0; -- 检查管理员角色是否绑定了菜单,没绑定就会出现登录后无菜单 SELECT r.id, r.name, COUNT(rm.menu_id) AS menu_count FROM system_role r LEFT JOIN system_role_menu rm ON rm.role_id = r.id GROUP BY r.id, r.name; -- 找出权限标识为空的菜单,这类菜单通常无法控制按钮显隐 SELECT id, name, permission FROM system_menu WHERE permission IS NULL OR permission = '';逻辑说明:第一条确认菜单表有数据且存在顶级节点;第二条用左连接统计每个角色绑定的菜单数,管理员角色如果menu_count为 0,说明关联数据没导进来;第三条排查权限标识缺失,芋道的按钮权限依赖permission字段,为空时前端v-hasPermi指令会失效。参数上没有需要调的,重点是看结果是否符合预期:顶级菜单一般是个位数,管理员菜单数应该接近总数。如果发现关联表为空,优先检查初始化脚本里system_role_menu的插入语句是否因为外键或重复主键被跳过。
3.2 字典与定时任务数据的完整性检查
字典和定时任务是另外两个容易被忽略的初始化数据。字典类型和字典数据是两张表,只导了类型没导数据,前端下拉框就是空的;定时任务表如果没初始化,后台“定时任务”页面打开就是一片空白,虽然不影响主流程,但会让人怀疑脚本是不是没导全。下面这段查询把这两块一起核对。
-- 字典类型与字典数据的配对情况,data_count 为 0 说明只有类型没有值 SELECT t.id, t.type, COUNT(d.id) AS data_count FROM system_dict_type t LEFT JOIN system_dict_data d ON d.dict_type = t.type GROUP BY t.id, t.type ORDER BY data_count ASC; -- 定时任务数量,正常初始化后应该有若干条内置任务 SELECT COUNT(*) AS job_count FROM infra_job; -- 检查定时任务的处理类是否为空,为空会导致任务执行时报错 SELECT id, name, handler_name FROM infra_job WHERE handler_name IS NULL OR handler_name = '';逻辑说明:第一条按字典类型统计关联数据条数,data_count为 0 的类型就是“空壳字典”,需要补数据;第二条确认定时任务表有内置记录;第三条排查处理类缺失,芋道的定时任务靠handler_name反射调用,为空时任务触发会直接抛异常。参数上ORDER BY data_count ASC让空壳字典排在最前面,方便优先处理。这三条查完,基本能判断这份 SQL 是不是“最全”——全不全不看文件大小,看关联数据有没有断链。
4. 避坑与排查:导入 SQL 时最常见的五类翻车
4.1 现象:导入报“Duplicate entry”主键冲突
原因:脚本里带了初始化数据,而目标库不是空库,或者重复执行了同一个数据脚本。芋道的初始化数据大量使用固定主键(比如菜单 ID 从 1 开始),重复插入必然冲突。解决:首次导入前确认库是空的;如果是增量补数据,先把脚本里的INSERT改成INSERT IGNORE或ON DUPLICATE KEY UPDATE,但要注意后者会覆盖已有配置,生产库上别这么干。我的习惯是导入前先mysqldump一份空库结构做对照,确认没有残留表。
4.2 现象:中文变成问号或乱码
原因:库、表、连接三处字符集不一致。常见的是库是utf8mb4,但客户端连接默认latin1,或者脚本文件本身不是 UTF-8 编码。解决:导入时显式指定--default-character-set=utf8mb4,并确认脚本文件用 UTF-8 保存(无 BOM)。如果已经导乱了,别在原库上修,重建库重新导入更干净。
4.3 现象:应用启动报“Table doesn't exist”
原因:模块脚本没导全,或者执行顺序导致某张表被跳过。芋道的业务模块表名有前缀区分,漏导一个模块的 DDL,启动时 MyBatis 加载 Mapper 就会报缺表。解决:对照应用配置文件里的数据源和 Mapper 扫描路径,把涉及的模块表逐个核对;用SHOW TABLES导出实际表清单,和脚本里的CREATE TABLE语句做差集,缺哪张补哪张。
4.4 现象:登录后菜单空白但数据库里有菜单
原因:角色菜单关联缺失,或者菜单的status字段为禁用状态,或者visible为隐藏。解决:先查管理员角色的关联菜单数,再查菜单的status和visible字段。芋道前端只渲染status=0且visible=0的菜单,初始化数据里如果有测试用的隐藏菜单,属于正常现象,别误判为导入失败。
4.5 现象:定时任务执行报“handler not found”
原因:handler_name对应的 Bean 不存在,通常是业务模块没启用或包扫描路径不对。解决:先确认handler_name在代码里确实有对应的@Component,再检查该模块是否在启动类扫描范围内。SQL 层面只能保证数据在,Bean 在不在是代码侧的事,这两边要对上,定时任务才能跑。
5. 把 SQL 当活文档用:版本比对与增量同步的一个笨办法
这份“最全 SQL”除了拿来初始化,还有一个容易被低估的用法:当版本比对基线。芋道迭代快,表结构经常加字段、改索引,如果你手上有一份某个版本的完整 SQL,后续升级时就可以用结构 diff 快速定位变化,而不是靠人肉翻提交记录。我一般会建两个库,一个导入旧版 SQL,一个导入新版 SQL,然后用information_schema做列级比对,把差异列出来再决定迁移脚本怎么写。下面这段查询就是比对两个库同名列差异的简化版,实际用的时候把库名换成你自己的。
-- 比对两个库中同名表的列差异,找出新增或删除的字段 SELECT a.TABLE_NAME, a.COLUMN_NAME AS old_col, b.COLUMN_NAME AS new_col, a.COLUMN_TYPE AS old_type, b.COLUMN_TYPE AS new_type FROM information_schema.COLUMNS a LEFT JOIN information_schema.COLUMNS b ON a.TABLE_NAME = b.TABLE_NAME AND a.COLUMN_NAME = b.COLUMN_NAME AND b.TABLE_SCHEMA = 'ruoyi_new' WHERE a.TABLE_SCHEMA = 'ruoyi_old' AND b.COLUMN_NAME IS NULL UNION ALL SELECT b.TABLE_NAME, a.COLUMN_NAME AS old_col, b.COLUMN_NAME AS new_col, a.COLUMN_TYPE AS old_type, b.COLUMN_TYPE AS new_type FROM information_schema.COLUMNS b LEFT JOIN information_schema.COLUMNS a ON a.TABLE_NAME = b.TABLE_NAME AND a.COLUMN_NAME = b.COLUMN_NAME AND a.TABLE_SCHEMA = 'ruoyi_old' WHERE b.TABLE_SCHEMA = 'ruoyi_new' AND a.COLUMN_NAME IS NULL;逻辑说明:前半段以旧库为基准左连新库,找出新库里不存在的列(即被删除的字段);后半段反过来找新增字段。COLUMN_TYPE一起带出来是为了看类型有没有变,比如varchar(64)改成varchar(128)这种不报错但可能影响索引长度的变更。参数上两个库名要换成你实际建的比对库,TABLE_SCHEMA条件别漏,否则会把系统库的列也扫进来。这个办法笨但可靠,比对着两个 SQL 文件肉眼 diff 强得多,尤其是字段多、表多的时候。
除了列比对,索引和唯一约束的变化也值得看,information_schema.STATISTICS里能查到索引名和列顺序,新增唯一索引往往意味着业务上有去重逻辑,迁移前要先清理脏数据,否则加索引会失败。我踩过一次坑:新版给某张关联表加了联合唯一索引,旧数据里有重复行,直接执行迁移脚本报Duplicate entry,最后是先跑去重 SQL 再加索引才过。从那以后我每次拿新版 SQL 做基线,都会先把索引差异单独列一张表,逐条确认数据是否满足约束,再动手迁移。希望这套“先看结构、再按序导入、最后用查询验完整性”的流程,能帮你少走几趟重建库的弯路。
本文还有配套的精品资源,点击获取