【问题标题】:Efficient SQL Schema Design with Odd One-to-Many Relationship具有奇数一对多关系的高效 SQL 模式设计
【发布时间】:2017-01-27 14:30:36
【问题描述】:

我正在尝试找出一种有效且高效的方法来在 MySQL 数据库中实现两个表 Lists(ListID, ListName)Items(ItemID, ItemName, Cost, Description, QuantityNeeded, QuantityPurchased) 之间的以下关系:

一个列表可以有很多项目。但是,Items 表中的 DescriptionQuantityNeededQuantityPurchased 属性特定于列表。例如,假设一项具有属性1, Paper Towels, 5.99, NULL, 4, 2,另一项是2, Paper Towels, 5.99, NULL, 7, 0。尽管它们具有相同的 ItemNameCost,但它们来自不同的列表。

我可以采取的最佳实施方式是什么?我曾考虑将属性ListID 添加到Items 表中,以便每个项目“知道”它属于哪个列表,但这可能会导致非常冗长的WHERE 执行(正确?),我想要这要尽可能高效。

【问题讨论】:

  • 规则 1:不存在一对多的关系。客户会告诉你它是,然后 6 个月后改变主意。为架构中的每个关系使用连接表。它将支持 1 对多、多对多或多对 1,您可以标准化处理在代码中建立关​​系的方式,当客户发现“哎呀,我们错了,这是多对多”时,您就遥遥领先其中。这听起来像是更多的工作,但是一旦你编写了“在这两个表中的这两个记录之间建立关系”函数,你就完成了,所以它实际上更容易。
  • @ChrisCaviness 所以你说我需要另一张桌子。这是否与ItemsLists(ItemID, ListID) 类似,两者构成关键?但这会遇到同样的问题吗?比如说,我想提取给定列表中的所有项目。难道我不必使用WHERE 子句在所有元组中搜索具有给定ListID 的所有内容吗?如果是这样,效率如何?
  • 您将使用连接表作为主要来源... SELECT b.* FROM ItemsLists a JOIN items b ON a.ItemID = b.ItemID WHERE a.ListID = 12345 至于效率,高度高效,因为您的连接表行长度很小,并且列被索引。您最终会从连接表中获得所需的 Item 索引值的一小部分,然后由连接使用。

标签: mysql database-schema


【解决方案1】:

应用程序关系不在表之间,它们在值(或如此标识的实体)之间并由表表示。

添加

-- list ListID has member ItemId
-- UNIQUE/PK (itemID)
-- FK (listID) references Lists
-- FK (itemID) references Items
Member(ListID, itemID)

或将项目替换为

-- list ListID has member ItemId and item ItemId ...
-- UNIQUE/PK (ItemID)
-- FK (ListID) referencing Lists
ItemsX(ListID, ItemID, ItemName, Cost, Description, QuantityNeeded, QuantityPurchased)

前者很难在 SQL 中约束为也具有等效的 FK 项 (ItemID) 引用成员,即每个项都必须是某个列表的成员。所以通常会使用后者。

注意

ItemsX = ListID, i.* from Member m join Items i on m.ItemID = i.ItemId
Items = select ItemID,... from ItemsX
Member = select ListID, ItemID from ItemsX

如果您不了解简单模型的选项,那么您就没有足够的知识来担心“效率”。您需要更多的设计(包括约束)和查询经验。您的情况几乎在任何信息建模介绍中都通过订单和订单(行)项目而不是列表和项目来解决。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-25
    • 2021-09-13
    • 2012-03-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-03
    • 1970-01-01
    相关资源
    最近更新 更多