看到一篇比較多租戶資料隔離方案的文章,總結挺不錯。其實大部分內容在我前幾年寫的文章都有。
文章翻譯自:
https://blog.arkency.com/comparison-of-approaches-to-multitenancy-in-rails-apps/
多租戶意味著同一個應用上有不用的使用者隔離。這是非常典型的saas模型。你可以用不同的隔離級別來實現多租戶。
1. 行級別: 在每個資料庫表裡新增tenat_id欄位,然後在每個查詢語句也新增相應的tenant_id
2. schema 級別: 每個租戶有在同一個資料庫內自己獨立名稱空間。 可以容易使用 PostgreSQL schemas 來實現. 後續會介紹使用Mysql如何實現。
3. 資料庫級別:每個租戶建立獨立的資料庫。 非常少用到。
下面是比較這幾種實現方式的優缺點:
行級別 | schema級別 | db級別 | |
---|---|---|---|
租戶建立時間 | ⚡️ 新增一條記錄 | ? 慢 (需要建立schema和表 ) | ? 非常慢 + 可能需要運維支援 |
租戶間洩漏資料風險 |
? 忘記新增 WHERE |
✅ 比較安全 | ✅ 非常安全 |
侵入性 | ? 所有程式碼需要新增tenant_id 列條件 |
? 一般 | ? 非常少 |
Need shared tables or merging data across tenants 不同租戶間共享和合並資料 |
✅ 沒任何問題 | ?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 vs PostgreSQL schemas
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 |