【问题标题】:Two foreign keys referring to one table两个外键引用一个表
【发布时间】:2017-06-01 07:13:42
【问题描述】:

我正在构建一个聊天系统的后端,我有一个 Message 表,如下所示:

问题是我需要 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!

我该如何处理?

【问题讨论】:

  • 好吧,如果一条消息可能有多个收件人,您想为消息收件人创建一个表,并将其用于消息和收件人 ID 之间的多对多关系。
  • 一封邮件只有一个收件人,而不是多个收件人。我有一个用户表。消息表必须使用外键作为用户 ID。如果发件人向同一用户写入多条消息,则会带来“违反唯一约束”错误。那就是问题所在!我还将这两个键设置为 unique=False。
  • 那么你的唯一约束是错误的。它不能仅基于发送者和接收者 ID,您还必须在其中包含其他内容。
  • 同时显示用户表的结构并显示两者的创建语句,或显示两个表上的所有约束。

标签: sql database oracle foreign-keys unique


【解决方案1】:

问题已解决 我查看了我的约束,我看到,我已经在我的 Django 模型中结合了独特的约束。我删除了它,并迁移了我的数据库,现在我可以创建多个消息。感谢您的回答!

【讨论】:

    【解决方案2】:

    设计对我来说似乎不错,但是您在 Messages 表上定义的键应该不同。用户 X 多次向用户 Y 发送消息是完全没问题的,所以我看到两个选项供您定义密钥:

    • sender_id / receiver_id / gendate:不应该同时发送从同一用户到同一用户的两条消息
    • ID: 你已经提供了一个代理键,你可以使用它

    编辑(进一步解释)

    在定义表时,还可以在其上定义唯一性约束。

    假设您的表具有定义为 (sender_id, receiver_id) 的唯一键;这样,您就是在告诉 dbms “嘿,不要让我插入两条具有相同值 sender_idreceiver_id 的消息,因为这些是我想用来唯一标识一行的标准”。这样一来,无论何时选择发送者和接收者,都可以确保收到的消息不会超过一条。

    如果您的表中有一行具有值 2 和 23,则尝试插入具有相同值的另一行会导致该错误消息。

    我的第一个选项是,如果您将唯一键更改为也包含 gendate,则 dbms 将向您保证不会有两行具有相同的 sender_idreceiver_idgendate 值.导致您的错误的行将被视为不同的行。

    第二个选项是说如果你的唯一键是ID,你甚至可以同时在同一个用户之间有多个消息,只要你为你插入的每一行生成一个不同的ID值。

    【讨论】:

    • 选项 1 和我的结构不一样吗?
    • 表结构不需要改变,任你选择;需要更改的是您在其上定义的约束。您当前的密钥可能被定义为 (sender_id / receiver_id),我的第一个选项添加了 gendate;这样,当前违反唯一性约束的两行将是可以接受的,因为它们对于 gendate 不同
    • 对不起,你能给我举个例子吗?我不太明白你的意思
    • 我看到您找到了解决问题的方法,但是我更新了我的答案,如果其他人将来偶然发现您的问题。
    • 好吧,现在我明白你的意见是什么了^^。
    【解决方案3】:

    关键是不要违反唯一性约束,我认为问题不在这里,需要提供完整的表结构,我不明白一件事,为什么我们必须设置外键,我认为这样会降低系统的灵活性和可维护性,给开发增加一点难度,我觉得应该去掉外键。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-18
      • 2011-01-11
      • 2012-07-02
      • 2017-01-04
      • 2014-06-04
      • 1970-01-01
      • 1970-01-01
      • 2020-08-14
      相关资源
      最近更新 更多