2012-12-06 119 views
9

我有4種類型的用戶,都有具體的數據,但他們也分享COMMUN數據,如usernamepassword ..關係數據庫設計多種用戶類型

我首先想到的是創建一個主usersuser_type欄。然後,當查詢用戶數據時,我可以先選擇他們的user_type,然後根據output運行不同的查詢來獲取「用戶類型」特定數據。 我不喜歡這個,因爲我希望我可以用一個查詢並理想地使用外鍵來獲取所有用戶相關的數據。

第二個想法是在users表中沒有user_type列,而是使用來自特定用戶類型表的外鍵將指向表的主行。 我喜歡這個好一點,但我想我將不得不運行N個查詢,其中N是每次我需要抓取用戶數據時的用戶類型數量。

還有其他的選擇嗎?在這種情況下,最好的做法是什麼?

非常感謝

+0

如果我理解你,你只需要在你的SQL語句中使用JOIN子句。類似於'SELECT * FROM users U LEFT JOIN user_details D ON U.id = D.user_id WHERE U.id =?' –

+0

用戶可以一次有多種類型嗎? –

+0

@Catcall否在這種情況下,用戶只能有一種類型,但我很好奇在這兩種情況下有什麼可能性 – silkAdmin

回答

14

您的情況看起來像是類/子類的實例。

有兩種經典的方法來設計SQL表來處理子類。各有優點和缺點。

單程被稱爲「單表繼承」。在這個設計中,所有類型的用戶都只有一張桌子。如果給定的列不屬於給定的行,則交集保留NULL。可以添加一列來指示用戶類型。

另一種稱爲「類表繼承」的方法。這很像Nanego給出的答案,只做了一些小的改動。有一個用戶表,包含所有常用數據和一個id字段。每個子類都有一個表,其中的數據與該子類相關。 id字段通常設置爲用戶表中匹配行中id字段的副本。通過這種方式,子類密鑰可以執行雙重任務,充當引用用戶表的主鍵和外鍵。這最後一項技術被稱爲「共享主鍵」。它在插入時需要一點編程,但它非常值得。它強化了這種關係的一對一性質,並加速了必要的聯結。

您可以將所有這三種設計作爲SO中的標籤或Web上的文章來查找。

+2

感謝您放棄這些條款,使用Google搜索並已經學到了很多東西 – silkAdmin

0

我的方式來做到這本來是創建一個表「人」與普通的字段,以及用於與外鍵「爲person_id」每種類型的用戶一個表。

在您的請求中,您只需將兩個表與foreign_key連接即可獲得一種類型用戶的所有數據。

你有幾種類型的用戶?

+0

4但我想保持這種靈活性。我提到的第二種解決方案其實就是你所建議的。 – silkAdmin

2

雖然它更有效地利用了磁盤空間,但分割成單獨的表的問題在於,您實際上需要有條件的連接 - 根據user_type連接到用戶類型特定的表。將代碼編寫爲SQL是一種痛苦,而現在誰在乎磁盤空間呢?

更好的選擇是讓一個用戶表有足夠的列來存儲有關任何用戶類型的信息,因爲知道某些列不會用於某些用戶類型。具有未使用的列的「低效率」將在執行速度和查詢簡單性方面得到補償。

如果你得到另一個用戶類型,它也很容易擴展 - 添加列比添加表要容易得多,而且當你添加更多的用戶類型時,新列的需求會減少t關於用戶需要存儲的許多不同的東西)

+2

我不喜歡這個,因爲它只是覺得馬虎,但它確實是事實。 –

+0

我同意,這將使代碼更清潔,以避免連接,但我希望有與PHP類匹配的表,它只是會感覺更優雅 – silkAdmin

+1

另外我看到一個缺點是,該表鬆散的完整性,因爲我必須使所有可以導致後端代碼錯誤的字段爲空。 – silkAdmin