如何使一个字段引用另一个不是MySQL主键的字段?

如何使一个字段引用另一个不是MySQL主键的字段?,mysql,database,database-design,Mysql,Database,Database Design,我知道外键不仅需要引用主键,还可以引用具有唯一约束的字段。在我的场景中,我设置了一个小测验,每个测验我都有一组问题。我的桌子设计是这样的 关键是,在我的第二个表格中,我将放置所有答案选项,我希望问题编号字段链接到第一个表格问题编号。我该怎么做?或者这种设计还有其他选择吗 谢谢你添加另一个表格纯粹用于回答,并通过“问题编号”字段链接它们 DB表应该包含关于一种项目的信息。问题和答案是不同种类的信息,所以应该放在不同的表格中。添加一个单独的表还允许独立更改问题和答案。此外,如果它们是分开的,您可以在

我知道外键不仅需要引用主键,还可以引用具有唯一约束的字段。在我的场景中,我设置了一个小测验,每个测验我都有一组问题。我的桌子设计是这样的

关键是,在我的第二个表格中,我将放置所有答案选项,我希望问题编号字段链接到第一个表格问题编号。我该怎么做?或者这种设计还有其他选择吗


谢谢你

添加另一个表格纯粹用于回答,并通过“问题编号”字段链接它们


DB表应该包含关于一种项目的信息。问题和答案是不同种类的信息,所以应该放在不同的表格中。添加一个单独的表还允许独立更改问题和答案。此外,如果它们是分开的,您可以在每个表中添加一个
语言
字段,并进行多语言测验

理想情况下,
测试问题
表中应该有一个
问题id
主键列,您可以将其用作
测试答案
表中的外键

使用
test\u question
表中的复合主键,您应该创建相应的复合外键:

CONSTRAINT FOREIGN KEY (test_id, question_no) REFERENCES test_question (test_id, question_no)

这是仅用于测试id列的外键之外的外键。

简短回答:

您可以对任何列或表达式进行
JOIN
。对
外键
主键
唯一键
或其他任何东西都没有“要求”

长答案:

然而,。。。对于性能(在大型表中),有些事情会产生影响

如果要将加入到主键、唯一键甚至索引列中,查询的冷运行速度会更快

为什么要使用
外键
?FK是两件事:

  • 表示该值必须存在于另一个表中的“约束”。此外,对于类似于DELETE CASCADE上的
    ,它可以提供在删除指定行时要采取的操作。该约束要求每次写入时查看另一个表(例如
    INSERT
  • 索引。也就是说,指定FK会自动添加索引(如果尚未存在)以加快约束
获取id

以下是执行一对插入的“常用”方法,其中需要第二个插入“指向”第一个插入:

INSERT INTO t1 ...  -- with an AUTO_INCREMENT id
grab LAST_INSERT_ID()  -- that id
INSERT INTO t2 ...  -- and include the id from above
要使
AUTO_INCREMENT
起作用,它必须是某个键的第一列。(注意:
主键
是一个
唯一的
是一个键(aka
索引

(可选)可以在第二个表上指定FK,以指出表之间的连接

而且,正如其他答案所述,FK可能涉及多个专栏

实体和关系

有时,像您这样的一组桌子最好是这样“设计”的:

  • 确定“实体”:用户、测试、问题、答案
  • 关系以及它们是1:1、1:many还是many:many。。。用户:测试是多对多;测试:问题为1:多(除非您希望在测试之间共享问题)
  • 答案
    更为复杂,因为每个答案取决于用户和问题

    1:1——很少实用;不妨把这些表合并在一起。 1:many——一个表与另一个表之间的链接(FK?)。
    many:many——需要一个具有(通常)2列的桥接表,即链接到两个表的ID。

    该列不必具有唯一约束,只需具有索引即可。虽然引用非唯一列通常没有意义。但似乎
    testid
    question\u no
    的组合是
    test\u question
    表的主键。因此,您当然可以在
    test\u answer
    表中的外键中引用该对。@Barmar SQL标准要求FK引用的列列表显示在唯一约束中。(即使引用集只需要是某个唯一集的超集。)索引不是SQL标准的一部分。某些数据库管理系统允许FK访问不在唯一约束中的列列表。可能仅限于索引中的那些。(唯一与否。)(虽然非唯一目标作为FK没有意义,但将其解释为要求引用表中的非空子代码位于引用表中仍然是一种约束/限制。)@philipxy AFAIK MySQL不强制执行这些要求。@Barmar Yeah MySQL允许引用索引和引用非唯一性(在后一种情况下不能正确操作)。@DaveyRoy,是的,但我仍然必须在问题字段之间建立链接。我如何做到这一点,因为它不是主键或唯一的?我喜欢表的设计。它以一种简单的方式确保每个问题都有一个正确答案。不过,我会打电话给另一张表,说明里面只有错误的答案。谢谢everyone@ThorstenKettner是的,谢谢你的邀请suggestion@Bramar,是的,testid可以参考上表,但问题是testid会有几个问题。\u否。它不会唯一识别一个问题。你是对的,我误解了。在
    test\u question
    表中应该有一个
    question\u id
    列。我也考虑过这一点。你的意思是说把它作为主键?我已经更新了答案。是的,但这可能吗?就像疑问句一样,no只是一个正规域