单数据库多租户数据隔离学习总结

1 为什么要隔离

对不同租户间数据隔离,从而保证数据安全

2 三种管理多租户数据的方法

多租户数据管理会涉及到数据共享和隔离程度。采用不同的技术业务手段隔离和共享程度也会发生变化。但每种方法也有其相似性。

在这里插入图片描述

以微软SQL Server为例(包含模式的定义),如果采用了 隔离数据库的方法,隔离程度最高。而采用共享模式的方法,数据共享程度最高。而共享模式的方法,正好是隔离程度与共享度的一种折中。

2.1 隔离数据库

在这里插入图片描述

每个租户一个数据库。租户共享上层应用,但每个租户在底层有自己的库存储数据,同时这些数据与其他所有组合相隔离。通过库的隔离,保证数据安全性,防止数据被意外或恶意的被其他租户访问或破坏。

每租户一个数据库,租户可以方便地更改自己的数据模型、数据备份与恢复。

但这种模式下由于每个库一个租户,开销会较大。但如果有很强的隔离要求,可以考虑使用这种模式。

2.2 共享一个数据库,对模式隔离

在Sql Server中有schema这个概念,因此整个结构分为 数据库->模式->表,这种隔离方式就在Schema上进行。一个库下,每个租户对应一个schema。Schema在mysql下就等同于数据库的概念。隔离方式也很好理解。

在这里插入图片描述
在sql server下,每个租户对应一个schema,然后在这个schema下为租户建表。

创建schema

CREATE SCHEMA ContosoSchema AUTHORIZATION Contoso

建表

CREATE TABLE ContosoSchema.Resumes (EmployeeID int identity primary key, 
   Resume nvarchar(MAX))

将schema设置为租户的默认账户

ALTER USER Contoso WITH DEFAULT_SCHEMA = ContosoSchema

租户可以访问默认schema下的表,或者访问租户对应的schema下的表。

这种方式的优缺点就依赖于schema上提供的能力。

2.3 共享一个数据库,一个模式,在表上隔离

在2.3中提到的,sql server中schema等同于mysql中的数据库。因此这种模式下在mysql下中相当于在一个数据库下,不同的租户共享数据库中的表。即不同的租户使用不同的行。为了区分不同租户需要增加租户ID(tenantId)来区分租户。

在这里插入图片描述
这种模式下直接共享了表,因此很多通过db提供的不同租户间安全保护、隔离能力均需要再应用层来完成。开发工作量会较多。

2.4 小结

2.1 - 2.3 的多租户实现,基于分层的思想。依赖不同的数据库产品,在不同的层次上实现对租户的划分。因此其优缺点也就与所在层的组件所具有的能力相关。如果能力不足,则需要额外的开发工作。

3 隔离方式的选择

上述介绍了三种方式,可以从以下几点考虑如何选择。

  • 经济角度:共享表的形式需要较高的开发量,处理成本较高,需要考虑安全,隔离,容量,访问量等问题。但后期接入成本会逐渐降低。
  • 安全角度:直接基于数据库隔离会减轻工作量。但通过共享表的方式处理也能提供相应的安全能力,只是需要良好的设计与开发。
  • 租户角度:服务的租户数量、每个租户占用的存储空间、租户的并发数量等

下图就就对租户相关的因素的一种图形化描述。
在这里插入图片描述

4 做什么

数据隔离,从分层的角度考虑,并基于不同的数据库产品进行数据划分。最终就是要做到如何把租户的数据路由到正确的位置,让用户无感知。

参考[2]中介绍了一些方式,例如在数据库组件中拦截sql语句,增加一些参数,最终在用户无感知的情况下事情请求路由。

同理其它方面安全检查、鉴权等也可以参考进行相应处理。

5 总结

还是基于分层思想,结合不同产品,针对实际情况进行开发。当然实际开发中涉及的细节还是很多。

参考

[1]https://web.archive.org/web/20110311185417/http://msdn.microsoft.com/en-us/library/aa479086.aspx
[2]java多租户https://www.ibm.com/developerworks/cn/java/j-lo-dataMultitenant/

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SaaS多租户系统的数据库隔离是指为每个租户提供独立的数据库系统,以保证每个租户数据和配置信息都是相互隔离的。这种方案的优点是隔离性好,每个租户数据都是独立的,不会相互干扰,同时也方便数据备份和恢复。但是这种方案的缺点是需要为每个租户提供独立的数据库,会增加系统的维护成本和资源消耗。 下面是一个Python Flask框架的例子,演示如何实现SaaS多租户数据库隔离: ```python from flask import Flask, g from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False app.config['SQLALCHEMY_ENGINE_OPTIONS'] = {'pool_size': 100, 'pool_recycle': 280} db = SQLAlchemy(app) class Tenant(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50), unique=True, nullable=False) class User(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(50), unique=True, nullable=False) tenant_id = db.Column(db.Integer, db.ForeignKey('tenant.id'), nullable=False) @app.before_request def before_request(): tenant_name = get_tenant_name_from_request() g.tenant = Tenant.query.filter_by(name=tenant_name).first() @app.teardown_request def teardown_request(exception): db.session.remove() def get_tenant_name_from_request(): # 从请求中获取租户名 pass @app.route('/users') def get_users(): users = User.query.filter_by(tenant_id=g.tenant.id).all() return jsonify([user.name for user in users]) ``` 在这个例子中,我们使用了Flask框架和SQLAlchemy库来实现SaaS多租户数据库隔离。我们定义了两个模型类Tenant和User,分别表示租户和用户。在before_request函数中,我们从请求中获取租户名,并通过查询数据库获取租户对象,将其保存在g对象中。在teardown_request函数中,我们关闭数据库连接。在get_users函数中,我们通过过滤租户ID来获取该租户下的所有用户,并返回用户列表。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值