多租户saas数据库表的实现

租户模式

  • 三种多租户模式
    在这里插入图片描述

第一个示例 : 使用每租户的独立应用程序和其自己的数据库。

第二个示例 : 使用多租户应用,并且每个租户都具有一个数据库。

第三个示例 : 使用多租户应用,并且具有分片式多租户数据库。

三种模型,从左向右,资源共享程度依次变高,当然成本也就逐步下降,但与之带来的就是技术难度也在大幅增加。

数据库表的实现


-- 租户表:租用系统的客户
CREATE TABLE IF NOT EXISTS `sys_tenant` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '租户id',
  `name` varchar(255) DEFAULT NULL COMMENT '租户名称',
  `code` varchar(64) DEFAULT NULL COMMENT '租户编号',
  `start_time` timestamp NULL DEFAULT NULL COMMENT '开始时间',
  `end_time` timestamp NULL DEFAULT NULL COMMENT '结束时间',
  `status` char(1) NOT NULL DEFAULT '0' COMMENT '0正常 9-冻结',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='租户表';

-- 租户客户表:
-- tenant_id : 表示属于哪一个租户
CREATE TABLE IF NOT EXISTS `customer` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `name` varchar(255) NOT NULL COMMENT '名称',
  `tenant_id` int(11) NOT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='租户客户表';

-- 用户表(3 种类型 :系统用户,租户用户,租户客户用户):
-- tenant_id : 表示属于哪一个租户
-- customer_id: 表示属于哪一个客户
-- 哪个租户的哪个客户的用户信息
CREATE TABLE IF NOT EXISTS `sys_user` (
  `user_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `username` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '用户名',
  `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
  `salt` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '随机盐',
  `dept_id` int(11) DEFAULT NULL COMMENT '部门ID',
  `mini_openid` varchar(32) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '小程序openid',
  `gitee_login` varchar(32) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '码云登录',
  `osc_id` varchar(32) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '开源中国',
  `wx_openid` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '微信openid',
  `qq_openid` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT 'QQ openid',
  `user_stype` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户类型(0:系统用户,1:租户用户,2:租户客户用户)',
  `tenant_id` int(11) DEFAULT NULL DEFAULT '1' COMMENT '所属租户',
  `customer_id` int(11) DEFAULT NULL DEFAULT '1' COMMENT '所属客户',
  PRIMARY KEY (`user_id`) USING BTREE,
) ENGINE=InnoDB AUTO_INCREMENT=412 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin ROW_FORMAT=DYNAMIC COMMENT='用户表';

-- 用户与角色关联表
CREATE TABLE IF NOT EXISTS `sys_user_role` (
  `user_id` int(11) NOT NULL COMMENT '用户ID',
  `role_id` int(11) NOT NULL COMMENT '角色ID',
  PRIMARY KEY (`user_id`,`role_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='用户角色表';

-- 系统角色表(3 种类型 :系统角色,租户角色,租户客户角色):
-- tenant_id : 表示属于哪一个租户 ;
-- customer_id: 表示属于哪一个租户客户 ;
-- dept_id: 表示属于哪一个部门;
-- ds_scope: 数据权限范围(为部门ID集合),即此角色可操作范围
-- ds_type: 数据权限类型(读,写,读写)
-- 哪个租户的哪个客户的角色信息
CREATE TABLE IF NOT EXISTS `sys_role` (
  `role_id` int(11) NOT NULL AUTO_INCREMENT,
  `role_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
  `role_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
  `role_desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
  `ds_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT '2' COMMENT '数据权限类型',
  `ds_scope` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '数据权限范围',
  `tenant_id` int(11) NOT NULL COMMENT '所属租户',
  `customer_id` int(11) DEFAULT NULL COMMENT '所属客户',
  `dept_id` int(11) DEFAULT NULL COMMENT '所属部门',
  PRIMARY KEY (`role_id`) USING BTREE,
) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin ROW_FORMAT=DYNAMIC COMMENT='系统角色表';

-- 角色菜单表
CREATE TABLE IF NOT EXISTS `sys_role_menu` (
  `role_id` int(11) NOT NULL COMMENT '角色ID',
  `menu_id` int(11) NOT NULL COMMENT '菜单ID',
  PRIMARY KEY (`role_id`,`menu_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='角色菜单表';

-- 菜单权限表(3 种类型 :系统菜单,租户菜单,租户客户菜单):
-- tenant_id : 表示属于哪一个租户,可实现定制化菜单;
-- customer_id: 表示属于哪一个租户客户 ;
CREATE TABLE IF NOT EXISTS `sys_menu` (
  `menu_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '菜单ID',
  `name` varchar(32) NOT NULL COMMENT '菜单名称',
  `permission` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '菜单权限标识',
  `path` varchar(128) DEFAULT NULL COMMENT '前端URL',
  `parent_id` int(11) DEFAULT NULL COMMENT '父菜单ID',
  `icon` varchar(32) DEFAULT NULL COMMENT '图标',
  `component` varchar(64) DEFAULT NULL COMMENT 'VUE页面',
  `sort` int(11) DEFAULT '1' COMMENT '排序值',
  `keep_alive` char(1) DEFAULT '0' COMMENT '0-开启,1- 关闭',
  `type` char(1) DEFAULT NULL COMMENT '菜单类型 (0菜单 1按钮)',
  `tenant_id` int(11) DEFAULT NULL DEFAULT '1' COMMENT '租户',
  `customer_id` int(11) DEFAULT NULL COMMENT '所属客户',
  PRIMARY KEY (`menu_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=100362 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='菜单权限表';


-- 租户数据库的信息:
-- tenant_id : 表示属于哪一个租户,可实现 上述三种模式中的后两种
CREATE TABLE IF NOT EXISTS `sys_datasource_conf` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(255) DEFAULT NULL COMMENT '名称',
  `url` varchar(255) DEFAULT NULL,
  `username` varchar(255) DEFAULT NULL,
  `password` varchar(255) DEFAULT NULL,
  `tenant_id` int(11) DEFAULT NULL COMMENT '租户ID',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='数据源表';


-- 部门表(3 种类型 :系统部门,租户部门,租户客户部门):
-- tenant_id : 表示属于哪一个租户,每一个租户都有自己的部门数;
-- customer_id: 表示属于哪一个租户客户 ;
-- 哪个租户的哪个客户的部门信息
CREATE TABLE IF NOT EXISTS `sys_dept` (
  `dept_id` int(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(64) DEFAULT NULL COMMENT '部门名称',
  `parent_id` int(11) DEFAULT NULL,
  `tenant_id` int(11) DEFAULT NULL COMMENT '所属租户',
  `customer_id` int(11) DEFAULT NULL COMMENT '所属客户',
  PRIMARY KEY (`dept_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='部门管理';

-- 职位表(3 种类型 :系统职位,租户职位,租户客户职位):
-- tenant_id : 表示属于哪一个租户
-- customer_id: 表示属于哪一个租户客户 ;
-- dept_id : 表示属于哪一个部门
-- 哪个租户的哪个客户的哪个部门的职位信息
CREATE TABLE IF NOT EXISTS `sys_job` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `name` varchar(255) NOT NULL COMMENT '职位名称',
  `tenant_id` int(11) DEFAULT NULL,
  `customer_id` int(11) DEFAULT NULL COMMENT '所属客户',
  `dept_id` int(20) DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='职位表';

  • 名词解释

系统用户 :就是软件开发商用户;
租户用户:就是软件租用方用户;
租户客户用户:就是租户的客户用户;
如果租户就是软件开发商的客户的话,可以简化为前两种用户,因为租户就是客户。

所有的表都要加上 租户ID [ 、客户ID ]、部门ID,以此表明资源所属者是:哪个租户的 [ 哪个客户的 ] 哪个部门的资源 。

操作权限如何判断?

可通过 springSecurity 自定义 AccessDecisionManager,根据登录用户获取用户权限,再此用户权限来匹配此次访问的url。

数据权限如何判断?

可通过 mybaits / JPA 的拦截器,获取原始sql并改写(就是在sql基础上加上 tenant_id / customer_id / dept_id 条件)。

一个用户可以完全管理自己的资源,并可以管理职权范围内( 读,写,读写 )的本人所在体系(就是这个人属于哪个租户或者哪个客户)下授予的权限范围(部门)。

  • 2
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 多租户数据库设计是指在一个数据库中同时存储多个租户(tenant)的数据,其中每个租户拥有自己独立的数据空间,相互之间互不干扰。在SaaS(Software as a Service)应用中,多租户数据库设计是非常常见的,因为这种设计可以有效地节省资源、降低成本,简化维护和升级等操作。 下面是一些常见的多租户数据库设计思路: 1. Schema per Tenant 这种设计思路是为每个租户创建一个独立的数据库模式(schema),在这个模式中存储该租户的所有数据。这种设计思路的优点是简单、容易维护,因为每个租户的数据都是相互独立的。缺点是在租户数量大的情况下,需要频繁地创建和删除模式,可能会影响数据库性能。 2. Shared Database, Shared Schema 这种设计思路是将所有租户的数据存储在同一个数据库中,但是使用相同的模式(schema)来存储数据。在每个中,增加一个租户ID列,用来标识不同的租户。这种设计思路的优点是简单、易于扩展,但是在查询和索引数据时需要考虑租户ID,可能会影响查询性能。 3. Shared Database, Separate Schemas 这种设计思路是将所有租户的数据存储在同一个数据库中,但是为每个租户创建一个独立的模式(schema),在这个模式中存储该租户的所有数据。这种设计思路的优点是简单、易于维护,但是在查询和索引数据时需要考虑租户ID,并且需要在不同的模式之间切换,可能会影响查询性能。 4. Hybrid Approach 这种设计思路是将上述三种设计思路进行结合,根据实际情况选择最合适的方案。例如,可以为小型租户使用“Schema per Tenant”设计思路,为大型租户使用“Shared Database, Separate Schemas”设计思路,以此来平衡设计的复杂度和查询性能。 总之,多租户数据库设计需要根据具体的业务需求和技术架构来进行选择,需要考虑到数据的安全性、稳定性、可扩展性、性能等多个方面的因素。 ### 回答2: SaaS(Software as a Service,软件即服务)是一种以在线方式交付软件应用程序的业务模式。在这种模式下,多个用户可以共享同一个软件应用程序,每个用户都被分配一个独立的虚拟环境,即多租户。 在设计SaaS多租户数据库时,需要考虑以下几个关键因素: 1. 数据隔离:在多租户环境下,每个用户的数据需要进行隔离,以保证数据的安全性和私密性。可以使用数据库模式化设计实现数据的隔离,例如每个用户拥有独立的数据库实例。 2. 多租户访问控制:为了保证每个用户只能访问和操作自己的数据,需要设计适当的访问控制机制。可以在数据库层面实现访问权限控制,以及在应用层面实现身份认证和授权机制。 3. 数据共享:尽管在多租户环境下,每个用户的数据是隔离的,但有时候也需要实现数据的共享。可以通过定义公共数据模型或者共享数据实现数据的共享,使得多个租户之间可以共享一部分数据。 4. 扩展性和性能:多租户数据库需要支持大规模用户和数据的增长。为了实现良好的扩展性和性能,可以采用分布式数据库架构,将数据分散存储在多个节点上,通过负载均衡和数据分片技术来提高系统的性能和可扩展性。 5. 备份和恢复:多租户数据库需要定期进行备份和恢复操作,以防止数据丢失和灾难发生。可以使用数据库备份和恢复工具,通过设定合适的备份策略和周期,来保证数据的安全性和完整性。 综上所述,设计SaaS多租户数据库需要考虑数据隔离、多租户访问控制、数据共享、扩展性和性能以及备份和恢复等因素,以提供稳定、安全、高效的服务。 ### 回答3: SaaS(Software as a Service)即软件即服务,是一种基于云计算的软件交付模式,用户通过互联网访问和使用软件,而不需要购买和安装在本地服务器上。在SaaS多租户数据库设计中,多租户是指多个客户共享同一个应用实例和数据库,但彼此之间的数据是相互隔离和保密的。 在多租户数据库设计中,首先需要明确每个租户所需的数据模型和功能,以及他们之间的共享和隔离要求。接下来,需要选择适合多租户的数据架构,常见的有共享数据库和分离数据库两种方式。 共享数据库是将所有租户的数据存储在同一个数据库中,通过在数据中添加租户ID来区分不同租户的数据。这种方式可以实现资源共享和成本节约,但需要考虑数据隔离和性能问题。 分离数据库是为每个租户分配独立的数据库实例,每个租户有自己的数据数据库连接。这种方式可以提供更高的隔离性和性能,但需要更多的资源和成本投入。 无论选择哪种方式,多租户数据库设计需要考虑以下几个方面: 1. 数据隔离:为每个租户保证数据的安全性和隐私性,防止不同租户之间的数据交叉和泄露。 2. 可伸缩性:设计数据库架构和存储方案,以满足不同租户的扩展需求和负载变化。 3. 备份和恢复:建立可靠的备份机制和灾难恢复方案,以保证数据的安全性和可用性。 4. 安全性:采取必要的安全措施,如访问控制、身份验证和加密等,保护数据库免受潜在的安全威胁。 5. 性能优化:通过索引、分区、缓存和查询优化等技术手段,提高数据库的性能和响应速度,满足租户的需求。 总结来说,saas多租户数据库设计需要综合考虑数据隔离、可伸缩性、备份恢复、安全性和性能优化等方面的需求,选择合适的数据架构和存储方案,以满足不同租户的需求,并提供安全可靠的服务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值