Sql-Server
在 SQL-Server 中對多租戶數據進行分區的建議
我將不勝感激有關分區(或不分區)多租戶業務應用程序的設計注意事項。所有數據表都使用類似於以下內容的組合鍵:
CREATE TABLE SomeTable( TenantId SMALLINT NOT NULL, ID INT NOT NULL, SomeData ..., CONSTRAINT [PK_SomeTable] PRIMARY KEY CLUSTERED (TenantID, ID) )
幾乎所有讀取都以特定租戶 ID 為關鍵字。寫入是由tenantID 隨機進入的,但任何保存3-5 天的數據在此之後往往永遠不會改變。
問題
- 如果我不分區,是 (tenantID, id) 還是 (id, tenantid) 更好的選擇。假設讀取都是按租戶 ID 進行的,寫入是按租戶 ID 隨機進行的,並且每晚有足夠的停機時間來執行維護計劃。
- 為每個租戶 ID 創建單獨的分區有什麼優缺點?
- 如果tenantID 是第一個鍵,分區會減少頁面碎片嗎?
- 如果分區在主文件中,那會改變參數嗎?
- 如果有 10 或 1000 個分區,它會改變參數嗎?
- 答案是否取決於我使用的是 SQL 2016 還是 SQL Azure?
如果我不分區,是 (tenantID, id) 還是 (id, tenantid) 更好的選擇。假設讀取都是按租戶 ID 進行的,寫入是按租戶 ID 隨機進行的,並且每晚有足夠的停機時間來執行維護計劃。
(tenantID,id) 是更好的排序方式,因為它為每個租戶的數據創建了位置。
為每個租戶 ID 創建單獨的分區有什麼優缺點?
優點:分區操作可用於對單個租戶進行操作。例如切換、截斷、重建。
缺點:維護,以及添加新租戶的分區拆分成本。
但請看:
如果tenantID 是第一個鍵,分區會減少頁面碎片嗎?
不會。每個租戶的行在索引中在邏輯上和大部分物理上都是連續的。每個租戶基本上都會有一個或幾個片段。因此,雖然分區會減少碎片,但不分區應該不是問題。
如果分區在主文件中,那會改變參數嗎?
不,那是分開的。所有分區都應該放在一個文件組中,除非有充分的理由將它們分開。對於某些特殊租戶,您可能有一個單獨的文件組,但我不建議這樣做。
如果有 10 或 1000 個分區,它會改變參數嗎?
不,除了它加劇了分區的維護問題。
答案是否取決於我使用的是 SQL 2016 還是 SQL Azure?
不。
但退一步說,您應該計劃讓多個聯合數據庫保存您的租戶數據。您仍然可以使用多租戶數據庫設計,但最終您將擁有多租戶和單租戶數據庫的混合。在數據庫中隔離租戶有許多重要的優勢。
- 租戶數據是隔離的。這對於向您的客戶銷售很重要,並且可以很容易地確保租戶永遠無法看到彼此的數據。
- 您可以單獨升級和修補租戶。
- 您可以一次免費移動、備份、恢復和導出租戶。至關重要的是,這為您提供了單個租戶的時間點還原。
- 數據庫是真正的安全邊界,您可以讓使用者僅查看單個租戶的數據。
- 您不必編寫租戶導出和租戶導入流程來將租戶從一個數據庫移動到另一個數據庫,否則您必須編寫這些流程。
- 您可以單獨擴展租戶,為大型或主要租戶提供對伺服器資源的差異化訪問權限,甚至為他們提供自己的專用資源。這使您的解決方案更易於管理、降低風險並為您創造定價機會。
- 每個租戶都有自己的查詢計劃記憶體,因此您沒有針對小租戶優化的查詢計劃用於查詢大租戶的數據,反之亦然。您可以了解每個租戶的績效指標。