2010-06-12 51 views
0

我最近遇到了一個相當複雜的問題,並經過四處尋找,我無法找到解決方案。我在stackoverflow.com上找到了很多次我的問題的答案,所以我決定在這裏發帖。帶兩個外鍵的2列表。性能/設計問題

因此,我正在爲基於Web的項目製作用戶/組管理系統,並將所有相關數據存儲到PostgreSQL數據庫中。此係統依靠三個表:

  1. USERS(包含主鍵 「USER_ID」)
  2. 基(包含主鍵 「GROUP_ID」)
  3. GROUP_USERS

兩個第一表只需定義站點上的所有用戶和所有組,並且最後一個表GROUP_USERS存儲每個用戶所屬的組。它只有兩列:

  1. USER_ID
  2. GROUP_ID

由於每個用戶都可以是多個組的成員,我決定做一個單獨的表用於此目的,而不是存儲逗號在USERS表中分隔列。

現在,這兩列都是外鍵,我也想讓它們成爲一個組合主鍵,因爲USER_ID和GROUP_ID的每個組合都必須是唯一的。但是現在我被困在似乎只有很多索引和關係的很小的表中,其中只包含數字。最後,我希望這個表儘可能快,即使包含數萬行。磁盤上的大小不應該是一個問題,因爲它只是所有的數字,但它感覺非常愚蠢的全尺寸索引引用一個較小的表。

我應該堅持我目前的解決方案,存儲逗號分隔值列在用戶表或有任何其他的解決辦法,我應該知道的。我在尋找的是最好的表現。此表可能(但不太可能或通常)在單個頁面加載時被查詢數百次。

我不想使用數組列,即使它們被postgreSQL支持。我希望儘可能通用,以便稍後可以切換數據庫(如有必要)。

編輯:換句話說,將使用複合主鍵,並且在一個表中的兩個外鍵僅具有兩個列已而不是相反對性能有負面影響,由於所生成的索引的大小?

編輯2:澄清。

謝謝!

回答

1

我相信你在正確的道路是正確的了,但不明白你真正定義的索引。

我的建議是你應該在用戶可以通過USER_ID你的主鍵索引,成羣的GROUP_ID你的主鍵索引,並在GROUP_USERS兩個指標。 GROUP_USERS中的其中一個索引應由夫婦(USER_ID,GROUP_ID)或夫妻(GROUP_ID,USER_ID)提供。第二個索引應該是在最後定義的索引中排在第二位的字段。

現在,當定義了GROUP_USERS主鍵爲什麼我提到的兩個選項?這是因爲主鍵索引與任何其他重複索引之間的性能差異較小。對該表最常見的查詢很可能是查明用戶是否在某個組中,並且該查詢將以任何方式執行。你必須考慮的是以下兩個查詢中的哪一個更常見。

  1. 查詢哪些組特定用戶是英寸
  2. 查詢哪些用戶是在一定的基團。

如果1更可能超過2,那麼您的主鍵應該是(USER_ID,GROUP_ID),否則(GROUP_ID,USER_ID)。

+0

我已按照您的建議設置了表格。我相信我很可能會檢查用戶是否在某個特定組中,而不是相反。 您的回覆讓我感到更加自信,我現在正以正確的方式進行,所以我正在考慮回答這個問題。 再次謝謝你。 – Emanuel 2010-06-12 22:25:45

0

如果我正確地理解你的問題,你可能會丟失的是主鍵(對於這個問題,外鍵以及)可能是所謂複合,這意味着它們包含多個列。這就是你想要的。在兩個用戶ID和的GroupId,並在每一個indivudyally外鍵的複合主鍵,每個指向(參考文獻)中的各父表中的PK。

+0

嗯,是的。我不完全確定如何將我的問題轉化爲文字,也許我只是感到困惑。 ;) 我的問題是,如果你剛纔提到的這個解決方案會對性能產生負面影響,而不是相反。 我會編輯主要的帖子,以便更清楚。 謝謝你的快速答案! – Emanuel 2010-06-12 16:27:06

+0

每個索引對插入,更新和刪除性能都有一定的負面影響,因爲數據中的每個更改都需要額外的寫入IO才能更新每個索引,但無論添加多少個索引都只能對Read產生積極影響操作,因爲如果有索引可用於幫助查找所需的記錄,這將顯着減少訪問數據所需的讀取IO數量。 – 2010-06-13 14:21:53