【问题标题】:Is it possible to have a table linking to a table that is linking back to the first table using foreign keys?是否可以将表链接到使用外键链接回第一个表的表?
【发布时间】:2019-06-06 07:52:47
【问题描述】:

我现在正在玩 MySQL,学习有关数据库设计的知识,并且想知道一些我在 Google 中找不到答案的东西。

想象一个名为“products”的表,其主键为“id”以及两个名为“name”和“primary_image_id”的附加列,其中“primary_image_id”是链接到第二个表的外键。

第二个表命名为“product_images”,主键为“id”,另外两列称为“path”(图像的路径)和“product_id”。 “product_id”当然是链接回第一个表的外键。

+----+-----------+------------------+
| id |   name    | primary_image_id |
+----+-----------+------------------+
| 1  | product_A |         3        |
+----+-----------+------------------+
| 2  | product_B |         6        |
+----+-----------+------------------+

+----+-----------+------------------+
| id |   path    |    product_id    |
+----+-----------+------------------+
| 1  | /image_01 |         2        |
+----+-----------+------------------+
| 2  | /image_02 |         1        |
+----+-----------+------------------+
| 3  | /image_03 |         1        |
+----+-----------+------------------+
| 4  | /image_04 |         1        |
+----+-----------+------------------+
| 5  | /image_05 |         2        |
+----+-----------+------------------+
| 6  | /image_06 |         2        |
+----+-----------+------------------+

这个想法是有一个包含所有产品图像的表格,而每个产品只有一个图像是预览图像(主图像)。这种类型的外键链接甚至可能吗?如果是,它是好的数据库设计还是我应该使用其他方法?

提前谢谢你!

【问题讨论】:

  • 我想你可以自己回答这个问题:当你尝试它时,它有效吗?
  • “良好的数据库设计”有些固执己见。您必须定义“好”是什么意思。但是,您可以选择另外做两个表:“PrimaryProductImages”,它通过 ids 将产品与主图像 1:1 关联,以及“ProductImages”,它仅通过 id 1:n 将所有图像关联到产品(产品:图像)。
  • 或者...您在 images 表中引入第四列:bool "isPrimary" ....

标签: mysql database database-design


【解决方案1】:

这是一个有效的用例,如果您打算只使用“获取产品 ID 1 的所有图像路径”或“获取产品 ID 1 的主图像”或“获取所有主图像的路径”。

如果存在对删除/更新事件的级联依赖,人们倾向于避免表中的外键引用循环。您需要回答诸如“如果删除产品 1,图像 2、3、4 会发生什么”或“如果图像 3 被删除,产品 1 会发生什么”之类的问题。

答案将帮助您设计出满足您要求的设计

【讨论】:

    【解决方案2】:

    只使用没有FOREIGN KEYs的索引。

    【讨论】:

      【解决方案3】:

      更典型的方法是将主要标志移动到图像表中。这两种方法都有可能产生不合逻辑的数据——

      您的方式将允许产品 1 将图片 A 命名为其主要产品,而图片 A 可以将产品 2 识别为其产品。

      如果标志管理不善,我的方法是允许产品有 0 或 2+ 个主图像。

      根据您对不一致的担心程度,您可以尝试通过触发器或约束来管理它,尽管与其他 DBMS 相比,MySQL 在这些方面稍有欠缺。

      绝对防止问题的一种方法是在 images 表中使用主要标志,但将其用作 int(等级),而不是具有最小等级为“主要”约定的布尔值 - 创建一个唯一的(产品 ID、排名)组合上的索引 - 并通过可以为您实现排名约定的存储过程或视图访问此数据,例如select * from images a where product_id = whatever and does not exist (select 1 from images b where a.product_id = b.product_id and a.rank > b.rank)

      看起来有点矫枉过正,但您需要判断潜在的数据完整性问题对您的应用程序有多重要。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-09-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多