多租户系统数据隔离方案

news2024/10/1 21:31:11

目录

前言

数据行

数据表

基于业务场景

基于数据量

数据库

数据源表

动态数据源


前言

多租户系统是一种将多个客户的数据和应用程序分开的系统,每个客户被视为一个独立的租户,互不干扰。实现多租户系统的关键之一是确保数据的隔离。

数据隔离的方案可以分成三种:

  1. 数据行级别:所有租户的数据都在同一张表内,表中设计一个租户ID字段来区分不同租户,只需增加租户ID处理逻辑。这种方案最简单,也适用于绝大多数数据量不大,并发量也不高的小系统
  2. 数据表级别:每个租户在同一个数据库中,使用不同的数据表来存储数据,多租户操作不需要切换数据源,相对没那么复杂,但是需要为数据表增加租户标识以及在应用程序中增加表名处理逻辑,适用于单个租户数据量大,但是并发不高的系统
  3. 数据库级别:每个租户使用独立的数据库来存储数据,隔离性最高,但在应用程序中就需要管理多个数据源,增加了管理的复杂性。只有单个租户数据量大且并发高才需要考虑这种隔离方式

之前公司的产品是一个多租户的SAAS平台,是一个面向企业办公的平台,每个企业其实就相当于一个租户。实际使用中采用可 数据行+数据表 混合的数据隔离方案,大多数业务场景中是数据行级别,即所有的数据都在同一张表下,用租户ID来区分。少部分业务场景则是数据表级别,每个租户都有自己的数据表,表名使用租户ID做后缀区分。

数据行

基于绝大多数没有什么并发量和数据量的前提,使用数据行隔离级别就足够了,方案简单易用。

以之前公司的产品作为例子,使用的就是数据行隔离级别。

系统中的租户其实就是企业,在每张数据表中都设计一个企业ID(company_id),不同企业的数据通过企业ID来区分。

在业务操作时都要带上企业ID处理,比如查询时带上企业ID过滤条件,使得查询只查出该企业下的数据;保存数据时带上企业ID,将企业ID保存到表中,标识该行数据是这个企业的,以便查询时过滤。

数据表

采用数据表级别的隔离方案,一般来说,有两个原因。

  1. 业务场景
  2. 数据量大

同样以之前公司的产品作为例子,少部分业务场景就是用了数据表级别的隔离方案。

基于业务场景

公司的产品是面向企业的,每个企业都能基于平台去设计自己的企业应用,实现自己自定义的业务逻辑。简单来说,平台上能注册多个企业,企业间数据互相隔离,每个企业又能够设计多个应用,每个应用的数据也是相互隔离的。

这种业务场景下,针对企业下每个应用的数据隔离,如果还采用数据行隔离的方案,那么只使用企业ID一个字段是区分不了每个应用的数据的,还需要加上应用ID才能够区分;而且由于存在多层的嵌套关系(一个平台注册多个企业,一个企业又可以设计多个应用),显得一张表下储存的数据种类很臃肿。

以上这种场景,可以使用数据表级别隔离方案来优化,每个企业下的应用使用不同的表来存储,表使用企业ID后缀来做区分,表中的数据再通过数据行隔离的方式,通过应用ID(app_id)来区分同一个企业下的不同应用。

这样做的好处就是数据之间的隔离关系显得很清晰,通过表名就能直接了解到数据之间隔离关系。但是个人感觉这种方式是不必要的,从功能实现上来说,直接用数据行隔离和用数据表隔离其实都能够实现,甚至数据行隔离实现还比较简单,使用数据表隔离还需要自己处理表名的逻辑。

基于数据量

基于某些业务场景采用数据表隔离是不必要的,但如果是单个租户数据量大的情况下,那么使用数据表隔离就是必要的了。

公司的产品是面向办公的,每个企业都可以设计自己的表单,表单是办公产品的核心功能,它的数据量是相对较大的。而数据量大的表就会存在查询性能下降等问题,针对数据量大的问题,其实就是使用分表的思路来解决。

在多租户系统的设计中,预先估计了某些表的数据量会比较大,便可以直接提前分表,也就是直接使用数据表隔离级别。在上面的场景中,根据企业ID来进行分表,将数据分散到多个表下,解决单表数据量过大的问题。

数据库

在MySQL中,其实database和schema是没有区别的,但是在PostgreSQL里,database和schema则是有区别的,一个database下有多个schema。

这里的数据库隔离级别,包含了不同的database,也包含了同一个database,不同的schema这种情况。因为在实际使用中, 都需要动态切换数据源,所以将以上两种情况放在一起讨论。

虽然在实际接触的系统中没有使用过这种隔离级别,但是学习最重要的就是做到举一反三,所以这里也写一些数据库隔离级别的实现思路。

数据源表

一般系统都是固定的数据库,所以数据库连接信息都是直接放在项目配置文件中。而多租户系统使用数据库隔离方式,则需要实现数据源切换,就得设计一张表来存储数据库的连接信息

相关表字段如下

  • id 主键id
  • tenent_id 租户id
  • url 数据库url
  • username 用户名
  • password 密码
  • driver 数据库驱动
  • schema 视图

动态数据源

有了数据源表,那么在应用程序中就需要实现动态数据源了,在运行中根据不同的租户ID来获取对应的数据源元信息,构造数据源,放入本地缓存中,并且将这个数据源加入到动态数据中,以便在运行时切换数据源。

具体到Spring框架中,就是使用 切面/拦截器 + AbstractRoutingDataSource + ThreadLocal

使用切面(AOP)或者 拦截器(Interceptor)拦截请求,提取当前请求的租户ID,如果缓存中不存在该租户数据源,则查询数据源表,构造数据源,并加入到动态数据源中

动态数据源再根据租户ID决定运行时的数据源

动态数据源相关的使用可以参考以下:

Spring Boot 动态数据源-CSDN博客文章浏览阅读616次,点赞11次,收藏24次。大多数系统中,都需要数据库来持久化数据,在大多数情况下,一个系统只需要配置一个数据源便能够完成所有业务的查询,保存操作。也存在一个系统需要多个数据源的情况,不同的数据源对应不同的业务操作,这种场景下配置多个数据源,并且在代码中维护多套dao层就可以了。还存在一种业务场景,所有的业务操作都是一样的,只有操作的数据源的不同,如果用多套dao层来实现,由于业务操作都一样,会出现多块一模一样的代码,这样的冗余代码是我们不希望看到,不利于维护。这种业务场景就很适合用动态数据源来实现。https://blog.csdn.net/typeracer/article/details/140814168

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1979482.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Windows 添加自定义服务实现开机(用户登录之前)自动运行 Python 脚本

实现效果 使用 Python 编写的一个脚本, 希望在 Windows 系统启动时, 用户登录之前就自动运行. 准备工作 首先确保 Python 脚本可以手动正常运行, 演示起见, 编写下面的一个简单的脚本用于在 C 盘根目录中生成一个包含脚本运行时间戳的文本文件. Python 脚本存放在 C:\Python…

RISC-V (五)上下文切换和协作式多任务

任务(task) 所谓的任务就是寄存器的当前值。 -smp后面的数字指的是hart的个数,qemu模拟器最大可以有8个核,此文围绕一个核来讲。 QEMU qemu-system-riscv32 QFLAG -nographic -smp 1 -machine virt -bios none 协作式多任务 …

绘唐科技,绘唐3高级推理创作

绘唐科技,绘唐3高级推理创作绘唐3https://qvfbz6lhqnd.feishu.cn/wiki/D3YLwmIzmivZ7BkDij6coVcbn7W 《绘唐3:高级推理创作》 第一章:谋杀案的启示 在古代绘唐王朝的京都,发生了一起离奇的谋杀案。一位名叫李红的官员&#xff0c…

[Day 44] 區塊鏈與人工智能的聯動應用:理論、技術與實踐

生成对抗网络(Generative Adversarial Networks,GANs)是一种由Ian Goodfellow等人在2014年提出的深度学习模型,广泛用于图像生成、图像超分辨率、图像修复等领域。GAN由一个生成器(Generator)和一个判别器&…

状态同步帧同步

帧同步: 有明确的逻辑帧概念,按照固定的逻辑帧间隔同步帧数据 原理 锁帧:mmo那种游戏,服务器需要收到第k帧所有客户端的指令,就算没有操作也发个空指令上去(相对来说回合制卡牌这类就简单很多&#xff0…

keil编程时,出现”MULTIPLE PUBLIC DEFINITIONS“,extern声明时不能赋值

原因导致重复定义? 有可能是重复定义导致的,这就需要查看报错位置的变量或函数是不是被重复定义了。也可能是一些语法错误导致的错误 语法错误导致的错误原因 使用extern只是为了说明这个变量在别的地方已经定义过,但使用extern引用时&…

NSS [HNCTF 2022 WEEK3]ssssti

NSS [HNCTF 2022 WEEK3]ssssti SSTI类题目(flask)毋庸置疑。 有过滤,我们拿burp先fuzz一波。长度159的都是被过滤的。 过滤了下划线、引号、args、os。 我们利用request对象绕过对下划线和引号的过滤(题目不允许POST方法&#x…

【机器学习】过拟合和欠拟合、高偏差(High Bias)和高方差(High Variance)的区别、过拟合和欠拟合的示例以及图表表示

引言 在机器学习中,过拟合(Overfitting)是指模型在训练数据上学习得太好,以至于它捕捉到了数据中的噪声和随机波动,而不是潜在的真实关系,这导致模型在新的、未见过的数据上表现不佳;欠拟合&…

从零开始:MySQL安装与配置完全指南

前言 哇,终于进入到令人激动的MySQL环节了 它可以说是你编程生涯中的最佳朋友,因为它总是能存储你的数据,从不说:“我忘记了你的信 息”。而且,它是免费的,不像一些昂贵的数据库,它从不让你的…

部署k8s+conatinerd环境

1、准备系统环境 禁用默认休眠(可选) 禁用:systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target启用:sudo systemctl unmask sleep.target suspend.target hibernate.target hybrid-sleep.target …

随机对照临床试验(RCT)与历史对照临床试验(HCT)

临床试验是评估新药、新疗法或新技术有效性和安全性的关键手段。在临床试验中,如何选择对照组是影响试验结果准确性和可信度的重要因素。随机对照临床试验(Randomized Controlled Trial, RCT)和历史对照临床试验(Historical Contr…

苹果电脑玩的游戏有哪些 Mac电脑怎么玩Windows游戏 苹果电脑可以装模拟器玩游戏吗

苹果电脑虽然在游戏生态上可能不及Windows平台那么广泛,但其强大的硬件和macOS系统的优化,足以支持一系列高质量游戏的流畅运行。从策略游戏《文明VI》到动作冒险游戏《黑暗之魂III》,再到解谜游戏《传送门2》和角色扮演游戏《神界&#xff1…

世界顶尖哲学家排行榜前十名,全球公认十大最厉害的思想家之一

标题:智慧与爱心:塑造命运的双翼 正能量因有爱心, 负能量期待智慧…(升命学说) 在这个纷纭复杂的世界中,我们每个人都是自己命运的舵手。正如升命学说所揭示,正能量的培养离不开爱心的滋养&…

Springboot+Vue在线考试系统(优质版)-附项目源码与配套论文

1.1 开发背景 在线考试系统的设计与实现,首先需要对系统进行需求分析,明确系统的功能和性能要求。系统需要具备考试管理、题库管理、在线考试、自动阅卷等功能,同时还需要保证系统的安全性、稳定性和可扩展性。 在系统的架构设计方面&#…

【多线程-从零开始-贰】线程的构造方法和常见属性

Thread 的常见构造方法 在创建线程的时候,是可以给线程起名字的。默认为 Thread-0 、Thread-1… 不会影响线程执行效果,可以更好地进行管理 ThreadGroup -线程组 把多个线程放到一组里,方便统一的设置线程的一些属性不过现在很少用到&#…

【增减序列】

题目 思路 多次修改操作,为降低复杂度,采用差分。 差分数组的性质可以转化这个“所有数都一样”的目标,转化为”b[2] ~ b[n] 均为0“的目标。 为了使得方法数最少,要使得方法中不存在前后矛盾的部分,比如减了又加。…

【SpringIOC容器设计体系分析】

SpringIoc容器架构分析 BeanFactoryHierarchicalBeanFactoryListableBeanFactoryAutowireCapableBeanFactoryAbstractBeanFactoryAbstractAutowireCapableBeanFactoryDefaultListableBeanFactoryApplicationContextConfigurableApplicationContextApplicationContext除BeanFact…

nextjs 实现TodoList网页应用案例

参考: https://nextjs.org/ Next.js 是用于网络的一种 React 框架。一些世界上最大的公司在使用它,它能够借助 React 组件的力量让您创建高质量的网络应用程序。 1、创建项目: 另外注意:pages与app路由存在冲突,如果有…

UniApp手机滑块验证组件代码生成器

DIY可视化实现UniApp手机滑块验证组件,支持自定义背景图片、成功提示、错误提示、划动提示等。 手机滑块验证组件是一种广泛应用于手机应用、网页等场景的用户验证机制,其主要目的是通过用户的滑动操作来验证用户的真实性和操作意图,从而增强…

双目视觉标定的一般方法

1 双目立体相机 双目立体相机是由两个单目相机根据 特定的参数组合而成,工作时可将左右两相机捕捉到的二维图像信息转换到三维立体空间 中,进而通过系列转换变为所需要的三维空间坐标信息。 2 一般过程 双目立体相机标定步骤一般有以下几个步骤&#…