2017-06-01 144 views
1

我建立一個聊天系統的後端的,我有一個Message表看起來像這樣:兩個外鍵引用一個表

enter image description here

的問題是,我需要2個外鍵指向在同一個表ID上。

沒有問題,但在情況下,用戶發送多封郵件,數據庫說

唯一約束違反

例子:

13 Testmessage1 01.06.17 08:15:01,456554000 2 (sender_id) 23 (receiver_id) 
14 Testmessage2 01.06.17 07:09:08,517000000 2 (sender_id) 23 (receiver_id) 

最後兩個標識是用戶ID都是相同的!

我該如何處理?

+0

好吧,如果一封郵件可能有多個收件人,您希望爲郵件收件人創建一個表,並將其用於郵件和收件人ID之間的多對多關係。 –

+0

消息只有一個收件人,而不是乘法。我有一個用戶表。消息表中必須包含用於用戶標識的外鍵。如果發件人向同一用戶寫入多個郵件,它會帶來「違反唯一約束」錯誤。那就是問題所在!我還將這兩個鍵設置爲unique = False。 – Tim

+0

那麼你的獨特約束是錯誤的。它不能僅基於發件人和收件人ID,還必須包含其他內容。 –

回答

1

問題解決 我看着我的約束,我看到,我已經結合了我的Django模型中的唯一約束。我刪除了它,並遷移了我的數據庫,現在我可以創建多個消息。謝謝你的回答!

0

設計對我來說似乎很好,但您在Messages表中定義的關鍵應該不同。這是完全正常的用戶X將消息發送到用戶Y多次,所以我看到兩個選項供您定義的關鍵是:

  • sender_id/receiver_id/gendate:它不應該發生,從相同的兩個消息用戶相同的用戶在同一時間被髮送
  • ID:你已經提供了代理鍵,您可以使用

編輯(進一步的解釋)

當你定義一個表格時,你也可以定義它的唯一性約束。假設你的表格有一個唯一的鍵(sender_idreceiver_id);那麼,你告訴dbms「嘿,不要讓我插入兩條具有相同值sender_idreceiver_id的消息,因爲這些是我想用來唯一標識一行的標準」。這樣,只要你選擇一個發件人和一個接收者,你肯定會得到不超過一條消息。

如果您的表中有一行值爲2和23,嘗試插入另一個具有相同值的行會導致該錯誤消息。

我的第一個選項是說,如果你改變唯一的密鑰也包括gendate相反,DBMS會向你保證,不會有兩行具有相同sender_idreceiver_idgendate值。那麼導致你的錯誤的行將被認爲是不同的。

第二個選項表示,如果您的唯一密鑰爲ID,則只要您爲插入的每行生成不同的ID值,您甚至可以在同一用戶之間同時發送多封郵件。

+0

不是選項1與我具有相同的結構嗎? – Tim

+0

表格結構不需要更改,可以選擇任一選項;需要改變的是你在其上定義的約束。你當前的密鑰可能被定義爲('sender_id' /'receiver_id'),我的第一個選項將'gendate'添加到那個;這樣,目前違反唯一性約束的兩行將是可接受的,因爲它們不同於'gendate' –

+0

對不起,但你能給我一個例子嗎?我真的不明白你的意思 – Tim

0

關鍵是不違反唯一性約束,我覺得問題不在這裏,你需要提供一個完整的表結構,我不明白一件事,爲什麼我們必須設置一個外鍵,我認爲這會降低系統的靈活性和可維護性,爲開發增加一點難度,我認爲我們應該擺脫外鍵。