2011-07-13 120 views
4

我正在設計一個數據庫,其中兩個字段具有多對一的關係,但我也需要它們之間的一對一關係,並且我希望得到一些關於是否有更好的方法來做到這一點的建議比我現在所擁有的還要多。同一表格上的多對一和一對一關係?

我的表格是accountsusers。一個帳戶可以有多個用戶,但每個帳戶只能擁有一個擁有者。用戶只能與一個帳戶相關聯。

我在表中有一個account字段,它存儲了用戶與之相關的帳戶的ID。在accounts表中,我有一個owner字段,其​​中存儲擁有該帳戶的用戶的標識(即頭管理員)。

我在使用InnoDB,所以我可以利用外鍵。問題在於,如果沒有先創建另一個帳戶或用戶(由於外鍵的限制),我無法創建帳戶或用戶,因此我使owner爲空。現在我可以創建一個空賬號爲owner的帳號,然後創建用戶,最後將帳號中的owner設置給用戶。

這是可以接受的,有沒有更好的方法?

這裏有一些可能的其他方式,我想出了,和我的想法在每個:

  1. 已經在users表中的布爾owner場。由於每個帳戶只能擁有一個所有者,因此我不得不確保每個帳戶只有一個用戶的屬性設置爲true

  2. 有第三個表owners。這似乎是更多的開銷和更多的工作,沒有什麼好的理由,因爲它與users表中的owner字段實際上是相同的。

我怎麼有,現在是很有道理的我,但它是一個有點尷尬不必設置空所有者,直到我創建的用戶,然後回來在事後進行設置。

我會很感激你可以給我的任何輸入。謝謝!

這個問題是相似的,但沒有外鍵的提到:Designing Tables: One to many and one to one at same time?

+0

用戶可以是帳戶的所有者而不是該帳戶的用戶(即另一個帳戶的用戶)嗎? –

+0

沒有。賬戶的所有者只是其本身的用戶而已。 – Compeek

回答

4

如果您的模式不能進行拓撲排序,也就是說,如果您無法建立排序,而只有在排序中表格僅引用其前面的表格時纔會建立排序。例如,對於軟件模塊(如果兩個模塊相互依賴,則存在問題),這種「分層」依賴關係也是非常好的屬性。

在您的情況下,您的用戶指的是引用用戶的帳戶和帳戶,因此很清楚,無法找到拓撲排序。

這種情況下的一個標準解決方案是引入一個單獨的表格,例如, 「角色」,你有三列:用戶,帳戶和角色。列角色可以是「所有者」或「來賓」。

事實上,你知道(鑑於當前請求)一個帳戶必須有一個且只有一個所有者,或者用戶必須列在一個帳戶中,且只有一個帳戶不是真正與該域相關的IMO規則「用戶」和「賬戶」。

你可以很容易地實現這些規則,但是組織你的數據以便你沒有其他可能是IMO的一個錯誤。你應該旨在模擬域,而不是具體的規則......因爲人們會改變他們對這些規則的看法。

你能構想有兩個賬戶的用戶嗎?你可以構想一個帳戶與多個所有者/管理員?我可以...這意味着很可能很快這將是一個請求。構建數據以便您無法表示此問題正在尋找麻煩。

此外,當您在模型中存在循環依賴關係時,您的查詢將更難以編寫。

一個很常見的情況是例如嘗試只使用一個表與分表本身就是一個「父」字段代表分層部分列表數據庫... 更好的是有兩個表代替,部分和組件,其中組件有兩個引用部分和數量。

+0

這完全是我自己的項目,我會永遠完全控制它,但我必須完全同意你所說的。當然可以有多個管理員(可以通過用戶表中的布爾字段指定),並且我對用戶只設置一個帳戶相當感興趣,但是引入角色確實更有意義。我也喜歡你所說的關於構建域的數據而不是特定的規則。如果可能的話,我試圖避免使用另一張表格,但它看起來似乎更符合您解釋它的方式。謝謝! – Compeek

1

你的解決方案是好的。

如果您不熟悉所有者列可以爲空,您可以依靠一些神奇的用戶記錄(可能爲零),這將是「系統用戶」。因此,新創建的帳戶將由用戶零擁有,直到其所有權被適當地重新定義。無論如何,這似乎比允許賬戶擁有一個空主人更難聞。

+0

是的,我同意 - 「用戶0」似乎更加尷尬。我對空列沒有任何問題。我只是想確保沒有一些潛在的問題,我沒有想到會出現在路上。 – Compeek

0

enter image description here

對於目前的要求有每個用戶

alter table UserAccount add constraint un_user_account unique(UserID); 

只有一個帳戶,並在要求改變許多一對多,刪除約束

alter table UserAccount drop constraint un_user_account; 

對於只有一個所有者,只需在應用程序級別執行該操作。

+0

感謝您的圖表和示例,但這不是我所需要的。我真的沒有機會需要爲每個用戶擁有多個帳戶;如果我決定做我想做的事,我一定會像第三張桌一樣做。我主要只是詢問記錄哪個用戶是賬戶所有者的最佳方式。我認爲只是一個布爾字段,類似於你所擁有的(用戶表中除外),但我認爲只有第三個表跟蹤用戶角色纔是最好的方式。 – Compeek

相關問題