Mysql 具有奇数一对多关系的高效SQL模式设计

Mysql 具有奇数一对多关系的高效SQL模式设计,mysql,database-schema,Mysql,Database Schema,我试图找出一种有效的方法来实现MySQL数据库中两个表之间的以下关系,列表(ListID,ListName)和项目(ItemID,ItemName,Cost,Description,QuantityNeeded,QuantityPurchased): 列表可以有许多项。但是,项目表中的说明、需要的数量和购买的数量属性特定于列表。例如,假设一个项目的属性为1,纸巾,5.99,NULL,4,2,另一个项目的属性为2,纸巾,5.99,NULL,7,0。尽管它们具有相同的项目名称和成本,但它们来自不同的

我试图找出一种有效的方法来实现MySQL数据库中两个表之间的以下关系,
列表(ListID,ListName)
项目(ItemID,ItemName,Cost,Description,QuantityNeeded,QuantityPurchased)

列表可以有许多项。但是,
项目
表中的
说明
需要的数量
购买的数量
属性特定于列表。例如,假设一个项目的属性为
1,纸巾,5.99,NULL,4,2
,另一个项目的属性为
2,纸巾,5.99,NULL,7,0
。尽管它们具有相同的
项目名称
成本
,但它们来自不同的列表


我可以采取什么最佳方式来实现这一点?我曾考虑过在
Items
表中添加一个属性
ListID
,这样每个项都“知道”它是哪个列表的一部分,但这可能会导致执行非常长的
,其中执行的
(正确吗?),我希望这能尽可能高效。

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

或将项目替换为

-- 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

如果您不知道直截了当的模型的选项,那么您就不必担心“效率”。您需要更多的设计(包括约束)和查询经验。实际上,通过订单和订单(行)项(而不是列表和项)进行信息建模的任何简介都会介绍您的情况。

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

或将项目替换为

-- 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

如果您不知道直截了当的模型的选项,那么您就不必担心“效率”。您需要更多的设计(包括约束)和查询经验。事实上,任何通过订单和订单(行)项目而不是列表和项目进行信息建模的介绍都会提到您的情况。

规则1:没有一对多关系。客户会告诉你是这样,然后6个月后改变主意。对架构中的每个关系使用联接表。它将支持1对多、多对多或多对1,使您在代码中处理建立关系的方式标准化,并且当客户机发现“哦,我们错了,这是多对多”时,您远远领先于他们。听起来需要做更多的工作,但一旦你编写了“在这两个表中的这两个记录之间建立关系”函数,你就完成了,所以实际上更容易了。@ChrisCaviness,所以你是说我需要另一个表。这会是沿着
itemslist(ItemID,ListID)
的思路,在这两个列表中形成键吗?但这会遇到同样的问题吗?比如说,我想调出给定列表中的所有项目。我不是必须使用
WHERE
子句来搜索所有元组中具有给定
ListID
的所有内容吗?如果是这样,效率有多高?您可以使用联接表作为主要源。。。选择b.*FROM items在a.ItemID=b.ItemID上列出联接项b,其中a.ListID=12345。由于联接表的行长很小,且列已编制索引,因此,为了提高效率,请选择高效。最后从联接表中得到所需的一小部分项索引值,然后由联接使用。规则1:没有一对多关系。客户会告诉你是这样,然后6个月后改变主意。对架构中的每个关系使用联接表。它将支持1对多、多对多或多对1,使您在代码中处理建立关系的方式标准化,并且当客户机发现“哦,我们错了,这是多对多”时,您远远领先于他们。听起来需要做更多的工作,但一旦你编写了“在这两个表中的这两个记录之间建立关系”函数,你就完成了,所以实际上更容易了。@ChrisCaviness,所以你是说我需要另一个表。这会是沿着
itemslist(ItemID,ListID)
的思路,在这两个列表中形成键吗?但这会遇到同样的问题吗?比如说,我想调出给定列表中的所有项目。我不是必须使用
WHERE
子句来搜索所有元组中具有给定
ListID
的所有内容吗?如果是这样,效率有多高?您可以使用联接表作为主要源。。。选择b.*FROM items在a.ItemID=b.ItemID上列出联接项b,其中a.ListID=12345。由于联接表的行长很小,且列已编制索引,因此,为了提高效率,请选择高效。最后,从联接表中得到所需的一小部分项索引值,然后由联接使用。