【问题标题】:Does MySQL require a primary key for a many-to-many link table?MySQL 是否需要多对多链接表的主键?
【发布时间】:2013-11-18 23:57:48
【问题描述】:

Mod 的注意事项:我阅读了大约十几篇似乎与此问题有关的帖子,但没有一个回答我的问题。请不要将此帖子标记为删除;这不是重复的问题。

我正在为一个包含多对多关系的网络图库构建一个数据库。例如,标签和图像。显然,要完成此操作,将创建第三个链接表。我可以在 tags 表和 images 表中看到一个主键列的用途,但我无法想象它在 links 表中的用途。它只会占用服务器空间。所以,我正在考虑在链接表中没有主键列。 MySQL允许这样做吗?或者,是否有任何令人信服的理由在链接表中有一个主键?谢谢。

链接表:

+--------------+---------+-----------+
| primary key? | tag ids | image ids |
+--------------+---------+-----------+

澄清

不会在表中拥有主键会破坏数据库吗?

【问题讨论】:

  • 主键是否必需?没有。几乎总是有候选人吗?是的。您可以使用根本没有索引的表,但这不是提高速度的好方法。 :-)

标签: mysql relational-database primary-key


【解决方案1】:

不要求您有主键。

但是,也没有要求主键只能是一个字段。在这种情况下,您可以将主键声明为 (tag_id, image_id)。

您在回复另一篇帖子时遇到了一个问题,这让我觉得您可能认为您应该将这两个字段连接起来作为主键。不。将键定义为

alter table link add primary key (tag_id, image_id);

不要说

alter table link add primary key (tag_id + image_id);

(我认为“+”是 MySQL 中的连接运算符。已经有一段时间了。SQL 标准是“&”,但 MySQL 将其用于其他用途。)

两者有很大区别,即第一种情况25,34和253,4是两个不同的值,而第二种情况都变成了2534。

您会始终从一个标签转到另一个图片,还是您也想从一个图片转到另一个标签?如果你需要双向,那么你应该创建两个索引,或者一个主键和一个索引,其中的字段是双向的。喜欢:

create index link_tag_image on link(tag_id, image_id);
create index link_image_tag on link(image_id, tag_id);

如果你只做第一个(例如),那么考虑这个查询:

select tag.name
from image
join link on image.image_id=link.imagae_id
join tag on tag.tag_id=link.tag_id
where image.foo='bar'

这似乎很合理:找到与满足特定条件的图像匹配的所有标签。但是如果没有第二个索引,这个查询可能会花费很长时间,因为 db 必须顺序读取整个链接表才能找到具有给定 image_id 的所有记录。

【讨论】:

    【解决方案2】:

    链接表中不需要主键。虽然复合键是个好主意。唯一性可以通过使用 UNIQUE ( tag_ids, image_ids) 来实现

    【讨论】:

    • UNIQUE 键在这种情况下与PRIMARY 键基本相同。 stackoverflow.com/questions/158392/…
    • @ceejayoz - 关键是您可以在复杂表中拥有多个唯一约束。并且该主键不是强制性的。但是在这种情况下,唯一的行为与主键相同。
    【解决方案3】:

    是的,您的主键应该是tag_id 和image_id 的复合/复合键,即PRIMARY KEY (tag_id, image_id)。在这种情况下,不需要额外的自动增量列。

    【讨论】:

    • 复合/复合对我来说是一个新名词。是不是说如果tag_id=23 和image_id=54,那么linke_id(主键)应该是2354?拥有主键列有什么好处?
    • 在这种情况下,主键可以保护您避免多次添加相同的标签,并且可以加快从表中检索数据的速度。
    • 谢谢,这很有帮助。
    【解决方案4】:

    在使用 MySQL Workbench 时,这是非常可取的,因为如果没有主键,它将不允许对您的表进行除只读之外的任何访问,这在尝试测试数据库时会很痛苦。尽管拥有一个永远不会在关系中被引用的 PK 似乎确实很浪费。

    【讨论】:

      猜你喜欢
      • 2010-10-21
      • 2011-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-04
      • 1970-01-01
      相关资源
      最近更新 更多