看到一篇比较多租户数据隔离方案的文章,总结挺不错。其实大部份内容在我前几年写的文章都有。html
文章翻译自:mysql
https://blog.arkency.com/comparison-of-approaches-to-multitenancy-in-rails-apps/sql
多租户意味着同一个应用上有不用的用户隔离。这是很是典型的saas模型。你能够用不一样的隔离级别来实现多租户。数据库
1. 行级别: 在每一个数据库表里添加tenat_id字段,而后在每一个查询语句也添加相应的tenant_id安全
2. schema 级别: 每一个租户有在同一个数据库内本身独立命名空间。 能够容易使用 PostgreSQL schemas 来实现. 后续会介绍使用Mysql如何实现。 app
3. 数据库级别:每一个租户建立独立的数据库。 很是少用到。运维
下面是比较这几种实现方式的优缺点:ide
行级别 | schema级别 | db级别 | |
---|---|---|---|
租户建立时间 | ⚡️ 新增一条记录 | 🐢 慢 (须要建立schema和表 ) | 🐌 很是慢 + 可能须要运维支持 |
租户间泄漏数据风险post |
💥 忘记添加 WHERE |
✅ 比较安全 | ✅ 很是安全 |
侵入性 | 🍝 全部代码须要添加tenant_id 列条件 |
👍 通常 | 👍 很是少 |
Need shared tables or merging data across tenantsui 不一样租户间共享和合并数据 |
✅ 没任何问题 | 👍sql能够跨数据查询 | 🚫 sql没法实现,只能应用代码实现 |
Running DB migrations 数据库迁移 |
⚡️ O(1) | 🐢 O(n) | 🐌 O(n) |
Conventionality | 👍 Standard Rails | 🛠 Occasionally at odds with Rails assumptions | 🤔 |
Additional costs 其它成本 |
👍 无 | 👍 无 | ❓ 建立大量数据成本 |
Operational overhead 额外运维成本 |
✅ 无 | 👍有可能,须要维护大量表 | 🛠 须要维护大量数据库 |
Complexity 复杂度 |
🍝 处处添加tenant_id |
🌴 利用PG特性 search_path |
🤔 |
Where possible 可行性 |
🌍 很是容易实现 | ⚠️ 确认是不是托管数据库。是否有权限 | ⚠️ 是否能按需建立数据库 |
Cost of switching 切换租户成本 |
⚡️ 设置变量。tenant_id =? | ⚡️ 须要设置search_path |
🐢 须要建立独立数据库链接 |
Extract a single tenant’s data 抽取独立租户数据 |
🛠 有点麻烦 | 👍 容易 | 👍 很是容易 |
Mysql没有相似PostgreSQL schemas功能,但Mysql数据库能够实现相似方式使用。切换数据库时候不须要建立独立数据库链接,在Mysql但是经过use 语句来选择数据库。类型在 PG数据库使用search_path功能。相似方案,能够在表名前在租户数据库前缀。
Mysql缺点:是你须要保证数据库间没有名字冲突。建立租户时候,须要有建立数据库的权限。若是你没有须要。而PG只须要在当前数据库建立schemas的权限,而且不用关系名字冲突。即便在托管的数据库服务,也能很方便实现。
快速方案选择:
条件 | 推荐 |
---|---|
A lot of tenants? | consider row-level |
A lot of low-value tenants? (like abandoned accounts or free tiers) | consider row-level |
Less tenants and they’re high-value? | schema-level more viable |
Anxious about data isolation? (ensuring no data leaks between tenants) | consider schema-level |
Customers might require more data isolation for legal reasons? | consider schema-level or even db-level |
On a managed or cloud hosted database? | if you wanna go for schema-level make sure it all works for you |
Multitenantizing an existing single-tenant code base? | schema-level might be easier to introduce |
Greenfield project? | row-level more viable |
Need to combine a lot of data across tenants | schema-level possible, but row-level is a safer bet |