资源中心(MVP 极简版)设计
只保留 2 张核心表
我们将资源相关的数据统一在一张主表,减少复杂度。 标签、属性、关系都不做独立表,统一放 JSON。
1. resource(主表)
满足你的字段要求,并保留最基本的 RBAC 所需能力。
必含字段(你要求的公共字段):
id
status
create_time
update_time
creator_id
updater_id
delete_flag
业务字段(精简后,只保留真正常用且必要的):
code 唯一编码
name 名称
type 类型:API | MENU | PAGE | ACTION | DATA
parent_id 父级资源 id,支持层级
path 路径(API path / 页面 path)
method HTTP 方法(API 用)
sort 排序
visible 是否可见
description 描述文字
meta 扩展 JSON,用于标签、属性、标志位等
2. resource_permission(资源-权限的关联表)
仅保留必要的一张表,与既有 permission 体系对接。
字段:
id
resource_id
permission_id
status
create_time
update_time
creator_id
updater_id
delete_flag
为什么只需要这两张表?
- 资源信息本身已经够完整:将标签、属性等放到 meta JSON,减少结构复杂度。
- 关联权限是必须的:其他都不是必须表。
- 没有引入 resource_tag / resource_attribute 等附表,因为早期阶段用 JSON 存即可。
- 前端可展示树、过滤、属性、标签,全靠 meta。
数据库表结构(简洁版)
resource
CREATE TABLE `resource` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`status` TINYINT NOT NULL DEFAULT 1,
`create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`update_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
`creator_id` BIGINT NULL,
`updater_id` BIGINT NULL,
`delete_flag` TINYINT NOT NULL DEFAULT 0,
`code` VARCHAR(128) NOT NULL,
`name` VARCHAR(255) NOT NULL,
`type` VARCHAR(64) NOT NULL,
`parent_id` BIGINT NULL,
`path` VARCHAR(512) NULL,
`method` VARCHAR(16) NULL,
`sort` INT NOT NULL DEFAULT 0,
`visible` TINYINT NOT NULL DEFAULT 1,
`description` VARCHAR(1024) NULL,
`meta` JSON NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_code` (`code`),
KEY `idx_parent` (`parent_id`),
KEY `idx_status` (`status`),
KEY `idx_delete_flag` (`delete_flag`)
);
resource_permission
CREATE TABLE `resource_permission` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`status` TINYINT NOT NULL DEFAULT 1,
`create_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
`update_time` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3),
`creator_id` BIGINT NULL,
`updater_id` BIGINT NULL,
`delete_flag` TINYINT NOT NULL DEFAULT 0,
`resource_id` BIGINT NOT NULL,
`permission_id` BIGINT NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_resource_permission` (`resource_id`, `permission_id`)
);
初始化数据(精简版)
INSERT INTO resource (code, name, type, sort, description)
VALUES
('menu.rbac', 'RBAC-PLUS', 'MENU', 1, 'RBAC 扩展菜单'),
('menu.rbac.resource', '资源管理', 'MENU', 2, '资源中心');
INSERT INTO resource (code, name, type, path, method, sort, description)
VALUES
('api.user.list', '用户列表', 'API', '/api/v1/users', 'GET', 1, '查询用户列表'),
('api.user.get', '查询用户', 'API', '/api/v1/users/{id}', 'GET', 2, '按 ID 查询用户');
后端接口(极简版)
查询资源列表
GET /api/resource?page=1&size=20&type=API&parent_id=0&q=user
资源树
GET /api/resource/tree
获取详情
GET /api/resource/{id}
新建
POST /api/resource
修改
PUT /api/resource/{id}
删除
DELETE /api/resource/{id}
设置关联权限
POST /api/resource/{id}/permissions
前端页面设计(更简洁、更现代)
页面结构
1. 搜索区(可折叠)
- 搜索框(名称/编码)
- 类型下拉(宽一些)
- 状态/可见性开关
- 折叠按钮
2. 列表区
- 现代紧凑表格
-
图标按钮操作栏:
- 查看
- 编辑
- 删除
- 权限绑定
3. 详情抽屉(右侧)
分成 3 块:
- 基本信息(名称/类型/path/method)
- Meta 扩展信息(JSON 展示)
- 关联权限(列表)
4. 新建 / 编辑 弹窗(现代化 UI)
- Key Info 区块
- Path/Method 区块
- Meta JSON 编辑区(可折叠)
- 右侧实时预览(可选)
最终总结:这是最简单、可用的 RBAC+ 资源中心
你现在只需要维护:
- resource(一个主表)
- resource_permission(一个关联表)
标签、属性、附加信息通通放 meta 中。
页面也不用复杂,主要是:
- 列表 + 详情抽屉 + 新建/编辑弹窗
- 搜索区折叠
- 图标按钮紧凑操作栏
为什么需要映射表?
为什么 RBAC+ 里必须要 resource_permission 这个表?什么时候可以不要?什么时候必须要?
1. 先说结论
如果你希望实现“资源级权限控制”(不是简单菜单权限),并且资源与权限是多对多关系,那么就必须要 resource_permission。
如果你只做传统 RBAC(角色 = 权限,权限绑定菜单),那就不需要。
换句话说:
- 简单业务:确实可以不要
- 要做企业级资源中心 / 可扩展的权限体系:必须要
2. 为什么很多企业架构里必须有这个表?
因为你的系统不是只有“菜单权限”,而是:
- REST API(GET /users/1, POST /orders)
- 页面 / 菜单
- 数据行(订单 #123)
- 数据列(工资字段)
- MQ topic
- Dubbo 接口
- 文件、文档
- 业务对象(例如「某个租户」「某个项目」「某个业务域」)
这些都是“资源”。
核心问题:资源与权限之间 不是一对一的关系。
举例
一个 API 资源:
/api/orders
你可能会创建多个权限:
- 查看订单(order:read)
- 修改订单(order:update)
- 删除订单(order:delete)
同一个资源 → 多个权限 多个权限 → 同一个资源也可能引用
如果你直接在 resource 表里加一个 permission_id,将无法表达“多权限绑定一个资源”。
这就是需要中间表的原因。
3. 资源与权限必须是多对多吗?
大部分可扩展的权限系统里是 YES。
| 关系 | 是否现实存在 | 举例 |
|---|---|---|
| 资源 → 权限(1 对多) | 常见 | 一个资源对应多个操作(读/写/删) |
| 权限 → 资源(多对多) | 很常见 | 某个“查看权限”可能对应多个资源,例如 10 个页面都用一个 read 权限 |
| 权限 → 资源(单对单) | 只有菜单系统才这样 | 菜单 = 权限,最简体系 |
如果你要做“统一资源中心”,第 3 种是不够的。
4. 如果不要 resource_permission,会怎样?
你会遇到这些痛点:
1)无法绑定多个权限到同一个资源
例如订单详情页页面,可能包含多个 API、多个按钮。 你无法描述哪些权限影响这个资源。
2)无法复用权限
比如“读取权限”适用于多个资源,你没法复用。
3)扩展资源类型时会非常痛苦
未来加 MQ、Kafka、文件、任意资源类型,都无法通用处理。
4)无法表达资源实例级授权
例如:用户只允许访问 “project_id = 123” 你也无法用权限去绑定多个资源实例。
对 IAM 平台来说这是灾难。
5. 那我到底该不该保留这个表?
情况 A:你要做“简单菜单 + API 权限”
→ 你确实可以删除 resource_permission,权限直接挂在资源表中即可(资源包含一个 permission_id)
情况 B:你要做“通用资源中心”,未来要支持更多资源
→ 必须保留
情况 C:你要做“企业级权限”,支持跨系统接入
→ 必须保留
情况 D:你要做“实例级权限”
例如:
- 仅能查看自己所属项目
- 仅能管理某几个租户
→ 必须保留
你现在在做的 IAM 平台倾向于 B/C/D,因此这个表是基础设施。
6. 如果你想“足够简单但可扩展”,我可以给你一个极简版设计
三个表就够:
resource
permission
resource_permission
没有 resource_type、resource_instance 等复杂字段。
并且 resource 只关心:
id
name
code (资源唯一码,如 api:/users, page:/dashboard)
type (api/page/button)
permission:
id
code (read/write/delete)
name
关联表:
resource_id
permission_id
你未来想扩展,只需加字段,不需要改变模型。
7. 如果你想更简单,我可以帮你再瘦身到 2 张表
你说一句: “我只需要菜单权限,不做资源中心。”
我就给你:
menu_role
menu
role
但是这种根本不是你想做的 IAM 平台。
8. 总结
你现在看到的复杂,是因为你在做的是 可扩展、多资源类型、支持实例级授权的企业级 IAM 平台。
