【问题标题】:How to write foreign key constraint which deals with multiple fields如何编写处理多个字段的外键约束
【发布时间】:2013-01-06 02:08:54
【问题描述】:

问题

我要为Answer做的foreign keys的设置是否是正确的Idea以及如何编写SQL on Add外键约束处理多个字段?

会话表:

SessionId (PK) SessionName
1              AAA
2              AAB

问题表:

QuestionId(PK)  SessionId(PK)  QuestionContent
1               1              What is 2+2?
2               1              What is 3+3?
1               2              What is 4+4?
2               2              What is 5+5?

答案表:

AnswerId(auto, PK)  QuestionId(fk)  SessionId(fk)  Answer
1                   1               1              A
2                   1               1              D
3                   2               1              C
4                   2               1              A
5                   1               2              True
6                   2               2              A
7                   2               2              B

现在我遇到的问题是Answer 表的外键,我想知道哪个外键是正确的。

我所做的是我在SessionId 中添加了一个外键,这意味着如果我点击一行的SessionId,它将匹配Session 表中的SessionId

然后我想我会在链接到Question 表的Answer 表中为QuestionId 提供一个外键。问题在于,如果在一行中单击QuestionId,那么它将显示QuestionId 中包含相同QuestionId 的所有行。所以如果我想查一下这个Answer:

AnswerId(auto, PK)  QuestionId(fk)  SessionId(fk)  Answer
1                   1               1              A

当我点击上面的 QuestionId 外键时,它会在下面输出:

QuestionId(PK)  SessionId(PK)  QuestionContent
1               1              What is 2+2?
1               2              What is 4+4?

答案不属于这两个问题,它只属于一个问题,但因为QuestionId 相同,所以它显示两个问题。

所以我在想的是我想要一个外键约束,如果用户连续单击QuestionId,它将同时查找QuestionIdSessionId,以便它知道该问题和会话(考试)该答案属于,因此它在下面输出:

QuestionId(PK)  SessionId(PK)  QuestionContent
1               1              What is 2+2?

我的问题是我不知道如何编写处理两个字段的外键约束?也只为SessionIdSessionId and QuestionId 设置外键是否正确?

【问题讨论】:

    标签: mysql sql database foreign-keys


    【解决方案1】:

    您可以使用以下语法为您的 Answers 表创建复合外键:

    FOREIGN KEY (QuestionId, SessionId) REFERENCES Questions (QuestionId, SessionId)
    

    但是,您的 Questions 表的 SessionId 列是复合主键的一部分似乎很奇怪,考虑到您有一个使用该名称的列作为主键的 Sessions 表。您可能应该考虑将 Questions.SessionId 设置为 Sessions 表上的外键,并将 QuestionId 设置为标准的单个主键。

    如果您这样做,您会发现您的 Answers 表中不需要 SessionId 列。

    下面是一个你可以做的例子:

    -- Sessions table
    SessionId (PK) | SessionName
    
    -- Questions table
    QuestionId (PK) | SessionId (FK) | QuestionContent
    
    -- Answers table
    AnswerId (PK) | QuestionId (FK) | Answer
    

    【讨论】:

    • 如果我只是将QuestionId 设为主键,那么我会得到重复项。我知道你要说什么,为什么不将QuestionId 设为自动并将其存储在一个名为QuestionNo 的新字段中,原因是我想在答案表中使用QuestonId,如您所见,这样我们就可以确定答案所属的问题以及答案所属的考试
    • 如果你想展示你将以你的方式构建三个表的方式,那么我会看看,我只是一直想按照我的方式来做,但我知道你有更多的经验和更多的知识
    • 更新了一个示例,说明了它的外观。
    • 好的,我将更改它并将 QuestionId 设为自动并包含为问题编号提交的 QuestionNo,然后我只需将使用 QuestionId 找到问题编号的查询中的 whre 子句更改为 QuestionNo并显示属于QuestionNoSessionIdQuestionId。谢谢:)
    • 真的吗?这是我在此之前回答的确切解决方案?尽管如此,祝你好运......
    【解决方案2】:

    您是对的,在您当前的架构中,您希望在 Answer 表上有 2 个索引; 1 在 SessionId 列上;和 1 在 SessionId 和 QuestionId 列上。这是一个关于如何做到这一点的帖子:

    Multiple-column foreign key in MySQL?

    在旁注中,我可能会考虑将 QuestionId 也设为身份/自动。不确定您是否收到任何附加值,使其在每个会话中重置。可以帮助简化您所需的一些索引。

    【讨论】:

    • questionId 真的是我的题号,每个题的题号值都存储在 questionId 列中。 sessionId 是考试的 id。所以我认为最适合Answer 表的所需索引是知道答案属于哪个问题。因此,为什么我们需要限制知道答案所属的考试和问题编号
    • 祝你好运 Manixman -- 不知道你为什么不接受我完全相同的答案......
    • 我知道你首先回答了这个问题,但他确实确保我改变了我的数据库设计。我的问题是还要说我的架构是否正确,但正如 PinnyM 所提到的,如果我将其更改为他所说的架构,那么我不需要多列外键会更好。我已经赞成你的回答,但给你一些声誉点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-02
    • 1970-01-01
    • 2020-04-16
    相关资源
    最近更新 更多