看到一篇比較多租戶數據隔離方案的文章,總結挺不錯。其實大部份內容在我前幾年寫的文章都有。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 |