04 权限模块系统设计
04 权限模块系统设计
前言
通过前面的文章的内容介绍,我们已经将苏三商城项目的骨架搭好,并且写了一个模板CRUD接口。
今天开始模块开发了,在做模块开发之前,为了让大家更好理解这个项目的各个模板的表结构,先做系统设计。
1 功能设计
权限系统是一个公共功能,是一个系统级别的模块,非业务级别的。
苏三商城的权限模块主要包含以下菜单:
- 部门管理
- 职位管理
- 菜单管理
- 角色管理
- 用户管理
一个职位属于某一个部门。
一个菜单包含多个功能权限。
一个角色可以包含多个菜单,和多个部门。或者多个角色包含同一个菜单,和同一个部门。是一种多对多的关系。
一个用户可以包含多个角色,多个用户也可以属于同一个角色。也是一种多对多的关系。
通过角色
上的菜单
,控制功能权限
。
通过角色
上的部门
,通过数据权限
。
权限点的功能包含在菜单管理中。
这里稍微简化了一下,没有设计通过岗位控制数据权限,不然太绕了。
2 表设计
在做表设计之前,先做一下规划,指定一些规范,让表风格统一。
2.1 表的规范
由于权限相关的表是属于系统级别的表,而非业务级别,因此表名中统一增加前缀sys_
,方便后面好统一管理。
对于主表,比如:用户表、菜单表等,需要增加8个公共字段。
对于关联关系表,考虑很多事多对多的关系,保存的数据可能会非常多,就不加那8个公共字段了。
但id作为主键还是不能少。
主表的删除功能在表中做业务删除,二关联关系表做物理删除。
删除关联关系表时,需要更新主表的修改人和修改时间相关的字段。
id用bigint类型,由于非分布式系统,可以直接使用数据库自动增长的值。
时间用datetime(3)类型。
状态字段用tinyint类型。
名称字段用varchar类型,长度根据实际情况而定。
存储引擎使用InnoDB,主键使用AUTO_INCREMENT数据库自动增长,CHARSET用utf8mb4,避免一些特殊表情字符的问题。
所有的表和字段,都要加上注释。
数据库和表的变更,都需要将相关脚本写到代码中的sql目录下。
2.2 表的初步设计
有了上面的规范之后,可以开始设计表了。
根据上面的需求:
一个职位属于某一个部门。
一个菜单包含多个功能权限。
一个角色可以包含多个菜单,和多个部门。或者多个角色包含同一个菜单,和同一个部门。是一种多对多的关系。
一个用户可以包含多个角色,多个用户也可以属于同一个角色。也是一种多对多的关系。
表之间的关系,我们可以这样设计:
2.3 表的详细设计
首先设计部门表
,它是一张基础表:
CREATE TABLE `sys_dept` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
`name` varchar(30) NOT NULL COMMENT '名称',
`pid` bigint NOT NULL COMMENT '上级部门ID',
`valid_status` tinyint(1) NOT NULL DEFAULT 1 COMMENT '有效状态 1:有效 0:无效',
`create_user_id` bigint NOT NULL COMMENT '创建人ID',
`create_user_name` varchar(30) NOT NULL COMMENT '创建人名称',
`create_time` datetime(3) DEFAULT NULL COMMENT '创建日期',
`update_user_id` bigint DEFAULT NULL COMMENT '修改人ID',
`update_user_name` varchar(30) DEFAULT NULL COMMENT '修改人名称',
`update_time` datetime(3) DEFAULT NULL COMMENT '修改时间',
`is_del` tinyint(1) DEFAULT '0' COMMENT '是否删除 1:已删除 0:未删除',
PRIMARY KEY (`id`) USING BTREE,
KEY `index_pid` (`pid`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='部门';
这张表包含了id、create_user_id、create_user_name、create_time、update_user_id、update_user_name、update_time、is_del这些公共字段之外。
还包含了name表示部门名称,pid表示上级部门ID,valid_status表示数据是否有效。
这张表比较简单。
下面看看岗位表
:
CREATE TABLE `sys_job` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
`name` varchar(30) NOT NULL COMMENT '岗位名称',
`sort` int(3) NOT NULL COMMENT '岗位排序',
`dept_id` bigint NOT NULL COMMENT '部门ID',
`valid_status` tinyint(1) NOT NULL DEFAULT 1 COMMENT '有效状态 1:有效 0:无效',
`create_user_id` bigint NOT NULL COMMENT '创建人ID',
`create_user_name` varchar(30) NOT NULL COMMENT '创建人名称',
`create_time` datetime(3) DEFAULT NULL COMMENT '创建日期',
`update_user_id` bigint DEFAULT NULL COMMENT '修改人ID',
`update_user_name` varchar(30) DEFAULT NULL COMMENT '修改人名称',
`update_time` datetime(3) DEFAULT NULL COMMENT '修改时间',
`is_del` tinyint(1) DEFAULT '0' COMMENT '是否删除 1:已删除 0:未删除',
PRIMARY KEY (`id`) USING BTREE,
KEY `index_dept_id` (`dept_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='岗位';
除了8个公共字段之外,还包含了name表示岗位名称,sort表示岗位排序,dept_id表示部门ID,valid_status表示数据是否有效。
接下来,看看菜单表
:
CREATE TABLE `sys_menu` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
`name` varchar(255) DEFAULT NULL COMMENT '菜单名称',
`pid` bigint NOT NULL COMMENT '上级菜单ID',
`sort` int(3) NOT NULL COMMENT '排序',
`icon` varchar(30) DEFAULT NULL COMMENT '图标',
`path` varchar(255) DEFAULT NULL COMMENT '路由',
`hidden` tinyint(1) DEFAULT '0' COMMENT '是否隐藏',
`is_link` tinyint(1) DEFAULT '0' COMMENT '是否外链 1:是 0:否',
`type` int(2) DEFAULT NULL COMMENT '类型 1:目录 2:菜单 3:按钮',
`permission` varchar(255) DEFAULT NULL COMMENT '功能权限',
`url` varchar(30) DEFAULT NULL COMMENT 'url地址',
`create_user_id` bigint NOT NULL COMMENT '创建人ID',
`create_user_name` varchar(30) NOT NULL COMMENT '创建人名称',
`create_time` datetime(3) DEFAULT NULL COMMENT '创建日期',
`update_user_id` bigint DEFAULT NULL COMMENT '修改人ID',
`update_user_name` varchar(30) DEFAULT NULL COMMENT '修改人名称',
`update_time` datetime(3) DEFAULT NULL COMMENT '修改时间',
`is_del` tinyint(1) DEFAULT '0' COMMENT '是否删除 1:已删除 0:未删除',
PRIMARY KEY (`id`) USING BTREE,
KEY `index_pid` (`pid`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='菜单';
菜单表稍微有点复杂,除了包含了8个公共字段之外,还包含了name表示菜单名称,pid表示上级菜单ID,sort表示排序,icon表示菜单的图片,path表示菜单的路由,url表示页面地址,type表示菜单的类型目前有3种,hidden表示是否隐藏,is_link表示是否是外链,permission表示菜单的权限点。
然后就是角色表
:
CREATE TABLE `sys_role` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
`name` varchar(30) NOT NULL COMMENT '名称',
`remark` varchar(255) DEFAULT NULL COMMENT '备注',
`data_scope` varchar(255) DEFAULT NULL COMMENT '数据权限',
`level` int DEFAULT NULL COMMENT '角色级别',
`permission` varchar(255) DEFAULT NULL COMMENT '功能权限',
`create_user_id` bigint NOT NULL COMMENT '创建人ID',
`create_user_name` varchar(30) NOT NULL COMMENT '创建人名称',
`create_time` datetime(3) DEFAULT NULL COMMENT '创建日期',
`update_user_id` bigint DEFAULT NULL COMMENT '修改人ID',
`update_user_name` varchar(30) DEFAULT NULL COMMENT '修改人名称',
`update_time` datetime(3) DEFAULT NULL COMMENT '修改时间',
`is_del` tinyint(1) DEFAULT '0' COMMENT '是否删除 1:已删除 0:未删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='角色表';
角色表除了包含了8个公共字段之外,还包含了name表示角色名称,remark表示备注,data_scope表示数据权限范围,level表示角色的等级,permission表示功能权限。
然后就是角色菜单关联关系表
:
CREATE TABLE `sys_role_menu` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
`role_id` bigint NOT NULL COMMENT '角色ID',
`menu_id` bigint NOT NULL COMMENT '菜单ID',
PRIMARY KEY (`id`) USING BTREE,
KEY `index_role_id` ( `role_id`) USING BTREE,
KEY `index_menu_id` ( `menu_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='角色菜单关联';
这张表是关联关系表,考虑到后面数据量可能会很大,没有加那8个共用的字段,可以节省一些磁盘空间。
角色菜单关联关系表中只包含了id表示主键,role_id表示角色ID,memu_id表示菜单ID。
有些人喜欢将role_id和memu_id创建一个联合主键,我个人认为这不是一个好的做法。
接下来是角色部门关联关系表
:
CREATE TABLE `sys_role_dept` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
`role_id` bigint NOT NULL,
`dept_id` bigint NOT NULL,
PRIMARY KEY (`id`) USING BTREE,
KEY `index_role_id` ( `role_id`) USING BTREE,
KEY `index_dept_id` ( `dept_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色部门关联';
这张表跟上面那张表类似,也只有3个字段,id表示主键,role_id表示角色ID,dept_id表示部门ID。
接下来,是用户表
:
CREATE TABLE `sys_user` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
`avatar_id` bigint DEFAULT NULL COMMENT '头像',
`email` varchar(50) DEFAULT NULL COMMENT '邮箱',
`password` varchar(30) DEFAULT NULL COMMENT '密码',
`user_name` varchar(30) DEFAULT NULL COMMENT '用户名',
`dept_id` bigint DEFAULT NULL COMMENT '部门ID',
`phone` varchar(20) DEFAULT NULL COMMENT '手机号码',
`job_id` bigint DEFAULT NULL COMMENT '岗位ID',
`last_change_password_time` datetime(3) DEFAULT NULL COMMENT '最后修改密码的时间',
`nick_name` varchar(30) DEFAULT NULL COMMENT '别名',
`sex` tinyint(2) DEFAULT NULL COMMENT '性别 1:男 2:女',
`valid_status` tinyint(1) NOT NULL DEFAULT 1 COMMENT '有效状态 1:有效 0:无效',
`create_user_id` bigint NOT NULL COMMENT '创建人ID',
`create_user_name` varchar(30) NOT NULL COMMENT '创建人名称',
`create_time` datetime(3) DEFAULT NULL COMMENT '创建日期',
`update_user_id` bigint DEFAULT NULL COMMENT '修改人ID',
`update_user_name` varchar(30) DEFAULT NULL COMMENT '修改人名称',
`update_time` datetime(3) DEFAULT NULL COMMENT '修改时间',
`is_del` tinyint(1) DEFAULT '0' COMMENT '是否删除 1:已删除 0:未删除',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `uk_user_name` (`user_name`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='用户';
用户表包含了8个公共字段,还包含了avatar_id表示用户头像的ID,email表示邮箱,passord表示密码,user_name表示用户名称,dept_id表示部门ID,job_id表示岗位ID,phone表示用户手机号,last_change_password_time表示用户最后修改密码的时间,nick_name表示用户的别名,sex表示性别。
然后就是用户头像表
:
CREATE TABLE `sys_user_avatar` (
`id` bigint NOT NULL AUTO_INCREMENT,
`file_name` varchar(255) DEFAULT NULL COMMENT '文件名',
`path` varchar(255) DEFAULT NULL COMMENT '路径',
`file_size` varchar(10) DEFAULT NULL COMMENT '大小',
`create_user_id` bigint NOT NULL COMMENT '创建人ID',
`create_user_name` varchar(30) NOT NULL COMMENT '创建人名称',
`create_time` datetime(3) DEFAULT NULL COMMENT '创建日期',
`update_user_id` bigint DEFAULT NULL COMMENT '修改人ID',
`update_user_name` varchar(30) DEFAULT NULL COMMENT '修改人名称',
`update_time` datetime(3) DEFAULT NULL COMMENT '修改时间',
`is_del` tinyint(1) DEFAULT '0' COMMENT '是否删除 1:已删除 0:未删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='用户头像';
用户头像表也包含了8个公共字段,除此之外,还包含了file_name表示头像的名称,path表示文件的路径,file_size表示文件的大小。
最后是用户角色表
:
CREATE TABLE `sys_user_role` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
`user_id` bigint NOT NULL COMMENT '用户ID',
`role_id` bigint NOT NULL COMMENT '角色ID',
PRIMARY KEY (`id`) USING BTREE,
KEY `index_user_id` (`user_id`) USING BTREE,
KEY `index_role_id` (`role_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户角色关联';
这张表也只包含了3个字段,id表示主键,user_id表示用户ID,role_id表示角色ID。