2010-03-26 75 views
2

我正處於多用戶應用程序的規劃階段,每個用戶只能訪問自己的數據。會有幾個相互關聯的表,所以我可以使用JOIN來確保它們只訪問他們的數據,但是我應該在每個表中包含user_id嗎?這會更快嗎?從長遠來看,這肯定會讓一些查詢更容易。我應該在多個表中包含user_id嗎?

具體來說,問題是關於包含user_id字段的多個表。

例如,每個用戶可以配置類別,項目(在這些類別中)以及針對這些項目的子項目。從用戶到子項通過其他表有一個邏輯路徑,但它需要3個JOIN。我應該只在所有表中包含user_id嗎?

謝謝!

回答

3

通常,您使用外鍵來關聯表間的數據。在很多情況下,這個外鍵是用戶ID。例如:

users 
    id 
    name 

phonenumbers 
    user_id 
    phonenumber 

所以是的,這是非常有意義的。

+0

我的問題是,是否包含多個表格,而不僅僅是一個表格,我會編輯我的問題。 – Drarok 2010-03-26 00:12:13

0

如果一個類別只能屬於一個用戶,那麼是的,你需要在類別表中包含user_id。如果一個類別可以屬於多個人,那麼您將擁有一個將類別ID映射到用戶ID的單獨表格。如果兩者之間有一對一的映射關係,你仍然可以做到這一點,但沒有真正的理由。

如果您可以保證總是通過加入到類別表來訪問這些子表,那麼您不需要在其他表中包含user_id。如果您有機會獨立訪問它們,那麼您應該在這些表上擁有user_id。

1

normalize的程度可能是一個困難的決定。有關此主題的最佳StackOverflow答案之一(Database Development Mistakes Made by App Developers)針對以下兩種情況發出警告:(1)未能正常化,以及(2)過度歸一化。

您提到,從長遠來看,在多個表格中重複相同的數據可能會更容易(也就是說,不會規範化該數據)。查看上一個鏈接中的「不通過視圖簡化複雜查詢」主題。如果您有效地使用視圖,那麼在編寫視圖時只需執行一次3連接查詢,然後就可以在大多數情況下使用不含連接的查詢。

大多數開發人員往往欠規範化,因爲它似乎更簡單。繼續並正常化。使用視圖來簡化您的日常查詢。當您的需求變得更加複雜或者您決定添加功能時,您會很高興將時間投入到關係數據庫設計中。

或者,根據您的工具集,您可能希望使用database abstraction圖層,該圖層在處理較高級別的數據對象時執行關聯設計。

0

這是多租戶數據庫中的設計決策。用「根」表,顯然你有user_id。但是在非「根」表中,當您使用代理PK時您有選擇。

假設您有具有項目和項目的用戶。項目顯然必須有一個user_id,但是如果動作綁定到一個且只有一個項目,那麼user_id是多餘的,並且也違反了正常形式,因爲如果要移動到另一個用戶的項目(可能不太可能在您的用例中),項目FK和用戶FK都必須更新。通常在多租戶方案中,這並非真正可行的方案,因此每個表的主鍵實際上都是承租人和承租人「內部」的唯一主鍵(它們也可能是全球唯一的) 。

如果您在設計中廣泛使用自然鍵,那麼需要明確的租戶+自然鍵,以便可以使用每個租戶的自然鍵。只有在使用像IDENTITY或GUID或序列這樣的替代品時,這會成爲一個問題,因爲它很容易使IDENTITY成爲PK,畢竟它的定義是唯一的。

讓user_id在所有表格中都允許您在視圖中執行某些操作來增強安全性(縱深防禦),爲您提供一些防禦性編程(在SQL Server中,您可以通過內聯表值函數限制所有訪問 - 基本上是參數化視圖 - 要求應用程序在每個「表格」訪問中指定user_id),並且還允許您通過將所有共享密鑰上的所有內容叉開來輕鬆擴展到多個數據庫。

請參閱this article瞭解一些有趣的見解。

(在大型多人並行模式像的Teradata,主索引確定在其上的數據的生活,所以我會認爲這是必須的以停止行的重新分配到另一安培的安培。)

一般來說,我會說你在每個表中都有一個tenantid,它應該是表中的第一列,在大多數索引中應該是大多數情況下的主鍵的一部分,除非另有說明。在可能的情況下,它應該是大多數存儲過程中必需的參數。

0

,如果它是Oracle,那麼你可能會建立一個細粒度的安全規則做連接和防止在原有基礎上的用戶ID是否存在某些活動...(SELECT INSERT,UPDATE,DELETE等)
您需要登錄的用戶和user_id之間的映射。你可以使用uid,但是如果數據庫在災難之後重建,這個數字可能會改變......

相關問題