Appearance
数据库设计入门
以 ruoyi-vue-pro.sql 为例
1. 先建立感觉
数据库不是“很多表”,而是“很多对象之间的关系”。
你可以把它理解成有规则的 Excel,但它更强调:
- 不重复存太多相同数据
- 能表达对象之间的关系
- 能安全地增删改查
- 能适应业务扩展
所以,学数据库设计的重点不是背表名,而是看懂“为什么这样拆表”。
2. 先看整个库的模块
这份库大约有 249 张表,主要模块有:
system_:系统管理infra_:基础设施bpm_/ACT_:流程审批member_:会员product_:商品trade_:交易订单pay_:支付crm_:客户关系erp_:进销存yudao_demo_:示例表
你看到前缀,就要先判断它属于哪个业务域。
3. 先看通用字段
这份库里很多表都有这些字段:
idcreatorcreate_timeupdaterupdate_timedeletedtenant_id
它们的意思是:
id:主键,唯一编号creator/create_time:谁创建、何时创建updater/update_time:谁修改、何时修改deleted:逻辑删除tenant_id:租户隔离
这说明它是企业级设计,不是随便写的练习库。
4. 逻辑删除和多租户
逻辑删除 deleted
不是直接删数据,而是标记为删掉:
0:有效1:删除
这样历史还能保留,适合订单、用户、日志等重要数据。
多租户 tenant_id
同一套系统给多个公司/客户使用时,就需要租户隔离。
比如:
tenant_id = 1tenant_id = 121
这样就不会把不同客户的数据混在一起。
5. 这份库里最重要的 6 种表
1)主表
存一个业务对象的核心信息。
例如:
system_userssystem_roleproduct_sputrade_orderpay_order
2)明细表
一条主记录下面有多条子记录。
例如:
trade_order+trade_order_itemerp_purchase_order+erp_purchase_order_items
3)关联表
解决多对多关系。
例如:
system_user_rolesystem_role_menu
4)树形表
用 parent_id 表示层级关系。
例如:
system_deptsystem_menuproduct_category
5)字典表
统一管理状态值、类型值。
例如:
system_dict_typesystem_dict_data
6)日志表
记录操作、错误、流程历史。
例如:
system_operate_logsystem_login_logACT_HI_*
6. 用户权限模块怎么理解
这组表最适合新手入门:
system_userssystem_deptsystem_rolesystem_menusystem_user_rolesystem_role_menu
它们的关系
- 一个用户属于一个部门
- 一个用户可以有多个角色
- 一个角色可以给多个用户
- 一个角色可以拥有多个菜单权限
典型拆法
system_users 存用户基本信息:
- 用户名
- 密码
- 昵称
- 部门
- 手机号
- 邮箱
system_role 存角色:
- 超级管理员
- 普通角色
- 业务角色
system_menu 存菜单和按钮权限:
- 菜单
- 页面
- 按钮权限
system_user_role 和 system_role_menu 是中间表。
这就是多对多设计。
7. 树形结构怎么设计
像下面这些表都有 parent_id:
system_deptsystem_menuproduct_category
它们表示“父子关系”。
比如部门:
- 总公司
- 研发部
- 财务部
数据库里通常这样存:
- 总公司:
parent_id = 0 - 研发部:
parent_id = 总公司id
所以看到 parent_id,你就要想到“这是树”。
8. 商品设计:SPU 和 SKU
这份库里有:
product_spuproduct_sku
SPU
商品公共信息。
例如:
- 名称
- 分类
- 品牌
- 详情
- 主图
- 总库存
SKU
具体可卖的规格。
例如:
- 红色 128G
- 蓝色 256G
为什么要拆
因为公共信息和规格信息不一样。
不拆会导致:
- 数据重复
- 维护困难
- 扩展麻烦
9. 订单为什么要主表+明细表
这份库里有:
trade_ordertrade_order_item
trade_order
存整张订单:
- 订单号
- 用户
- 状态
- 总金额
- 收货人
- 地址
trade_order_item
存订单里的每个商品:
- 属于哪个订单
- 商品是什么
- 规格是什么
- 买了几件
- 单价是多少
这就是一对多
一张订单可以有很多商品,所以要拆。
10. 支付为什么单独拆
这份库里有:
pay_orderpay_order_extensionpay_refundpay_walletpay_wallet_recharge
订单和支付不是一回事。
- 订单:买了什么
- 支付:钱怎么走
单独拆开后:
- 支付渠道好扩展
- 退款逻辑好处理
- 钱包充值也能独立管理
11. ERP 为什么总是成对出现
例如:
erp_purchase_order+erp_purchase_order_itemserp_sale_order+erp_sale_order_itemserp_stock_in+erp_stock_in_item
这说明 ERP 单据也通常是:
- 主表:单据头
- 明细表:单据行
这是非常经典的企业系统设计。
12. 字典表的作用
system_dict_type + system_dict_data 用来统一管理枚举值。
例如:
- 性别
- 状态
- 菜单类型
- 角色类型
好处是:
- 可配置
- 好维护
- 不用到处写死中文
13. 外键为什么不一定都写出来
你会发现很多表“逻辑上有关联”,但 SQL 里未必都写 FOREIGN KEY。
例如:
dept_id指向部门user_id指向用户order_id指向订单spu_id指向商品parent_id指向父节点
这是正常的。
企业项目里常常只在业务层保证关系,不一定在数据库层强制外键。
14. 你以后看表的顺序
- 先看表名,判断模块
- 再看主键
id - 再看通用字段
- 再看关系字段:
user_id、role_id、parent_id、order_id - 再判断它是主表、明细表、关联表、树表还是字典表
- 最后问自己:为什么要这么拆?
15. 这份库的核心设计口诀
- 按业务模块拆表
- 主表放核心信息
- 明细表放重复信息
- 多对多用中间表
- 树结构用
parent_id - 状态值放字典表
- 删除常用逻辑删除
- 多公司用
tenant_id
16. 最适合新手的学习顺序
建议你按这个顺序学:
system_模块yudao_demo_模块product_模块trade_模块pay_模块- 再看
crm_、erp_、ACT_
17. 一句话总结
数据库设计的本质,不是“表多”,而是:
把一个复杂系统,拆成清晰、可维护、可扩展的关系网络。
