2009-11-16 39 views
13

每次我看到大約多租戶數據庫模型的教程告訴你把TenantID在每一個表:Multitenant DB:爲什麼要在每個表中放置一個TenantID列?

zoos 
------- 
id 
zoo_name 
tenant_id 

animals 
------- 
id 
zoo_id 
animal_name 
tenant_id 

然而,這似乎是多餘的給我。爲什麼不將tenant_id列添加到zoos表中並利用zoosanimals之間的外鍵關係?

你是否爲每個表添加tenant_id以防止連接過度瘋狂?它是防範錯誤的保護措施嗎?性能考慮?

+1

設計多租戶數據庫時有一些注意事項,請閱讀MSDN文章:[多租戶數據架構](http://msdn.microsoft.com/en-us/library/aa479086.aspx)總之,有幾個方法,它是選擇和後果的連續體。根據需求做出明智的決定。 – 2012-01-11 09:47:32

回答

8

如果我在層次結構頂部(即在動物園級別)擁有tenantID,則需要考慮幾個問題。

  1. 層次結構的頂部永遠不能改變,例如,如果你需要添加一個節點上的動物園級以上的樹(比如地區 - >動物園 - >動物),那麼它會強制重新組織每時間。
  2. 對於某些查詢,您將被迫從層次結構的頂部開始,即給我一個所有可用動物的列表將迫使您從樹頂開始
  3. 爲什麼不使用模式?每個租戶都在自己的模式中被隔離。這也將很好地分離數據集。
5

首先想到的是查找animals > zoos > tenants比簡單animals > tenants要慢。最有可能的是這是一個查找,你會做往往(例如,「讓所有的動物爲某個租戶,無論動物園」)。

對於中小型應用程序,您可以使用更規範化的結構,但爲了提高效率,您應該使用無關數據(並且一般而言,多租戶應用程序不會太小)。只要確保它不會「不同步」,這是伴隨冗餘數據而來的風險。

要回答你的最後一段,原因是性能,純粹和簡單。加入並不是壞事;它們可以幫助您將一段數據保存在一個地方而不是三個。這絕對不是爲了防止錯誤。將tenant_id字段添加到更多表格會增加bug的風險(儘管對於從未更改的id,這不會成爲一個問題)。

+1

-1。只在動物園表中存儲租戶ID不是「更規範化」。將它作爲外鍵存儲在每個表格中並非無關緊要;這就是你認爲用外鍵做的事情。 – 2012-01-11 13:03:24

+0

是的。數據庫越規範化,冗餘就越少。我認爲你會同意在多個地方存儲一個id是冗餘的。我從來沒有說過這些字段是處理數據一致性的一流外鍵,但即使它們會由於額外的檢查而降低性能。問題在於解釋爲什麼該字段被添加到多個表格中的原因,我認爲我這樣做了。所以我會說你的-1是沒有根據的。 – Blixt 2012-01-11 16:36:50

+1

外鍵不是多餘的。它們是關係模型的核心和顯着特徵。在多租戶共享架構體系結構中,所有外鍵都是由tenant_id加上其他內容組成的複合鍵。該租戶ID是區分一個租戶的行與其他每個租戶的行的唯一區別。將租戶ID保留在表中,並且還必須禁止插入,更新和刪除操作。 (考慮一下。) – 2012-01-13 03:06:12

8

它的方便性和性能 - 在標準化方面,你是絕對正確的,它只需要進入頂端。然後問題就變成了獲取某些數據(比如動物園 - >動物 - >食品 - >供應商),你必須對非常簡單的查詢進行非常複雜的連接。

所以在現實世界中有一個妥協 - 問題就變成了什麼地方,到了什麼程度。

請參閱本文Maybe Normalizing Isn't Normal - 和它的結論:

正如老話 推移,正常化,直到它傷害, 非規範化直到它的工作原理

來開始探索這個問題的地方

+0

冒着發生書呆子宗教戰爭的危險,我不禁想知道這是不是一個自然鑰匙是有用的例子適合。如果您的多租戶應用是按域名分區的,並且您將tenant_id設置爲域名,那麼您也可以減少連接。 – Paul 2010-03-17 19:14:02

+0

它不會減少連接 - 你仍然有問題要麼包括在多個層次(理論上是壞的)或複雜的連接(還有理論上的糟糕),並且無論自然鍵總是回來並咬你( - : – Murph 2010-03-18 09:27:33

+1

- 1.如果您規範化了一個多租戶,與3NF或5NF的共享關係,那麼您將在每個表中獲得租戶標識符 – 2012-01-11 13:07:08

14

如果您的關鍵設計考慮因素之一是安全性 - 具體來說,一個客戶端在訪問另一個客戶端的數據時無法完成,關於如何實施此安全性,可能需要在每個表格中添加符合條件的列。描述here的這種策略需要在每張桌子上建立一個視圖;假設每個表都包含一個tenantId列,那麼如果配置得當,每個視圖都可以包含一個「WHERE tenantId = SUSER_SID()」子句(當然,您還需要配置數據庫,以便客戶端只能訪問視圖)。

另一個因素(如我目前的工作)是加載倉庫數據(ETL)。表在tenantId上分區(我們使用表分區,但分區視圖也可以),並且可以輕鬆地爲客戶端加載或卸載數據,而不會嚴重影響任何其他客戶端。

但一如既往,涉及到很多「依賴」。如果沒有明確的需求,未來需求的可能性很低,然後將該列標準化。只要認識到它比概念或邏輯數據庫設計更像是物理實現的設計。

0

那麼,Bob可能在動物園No1擁有一隻長頸鹿,而喬可能在同一個動物園擁有一隻獅子。 他們不應該看對方的數據。

0

N1是爲了安全。

在多租戶應用程序中,安全性需要是一個強大的概念。

假設您給予用戶修改動物的能力。 您可以創建一個表單,顯示當前租戶的動物園。 如果用戶破解表單並傳遞另一個租戶的動物園標識,會發生什麼情況?

該動物將被轉移到另一個租戶的另一個動物園!

這是一個多租戶應用程序真正的痛苦!

+0

您可以在服務器端進行檢查以確保用戶擁有該ID的權限。不管數據庫設計如何,你都需要這樣做,但我明白你的意思。 – 2010-11-12 19:27:21

+2

如果用戶侵入表單並提供屬於另一個租戶的動物的id,會發生什麼情況?如果用戶侵入「我的個人檔案「頁面提供超級管理員帳戶的ID?您完全不能相信用戶的輸入 - 這適用於任何用戶擁有不同權限的系統,而不僅僅是多租戶。 – 2012-12-03 19:15:57

相關問題