Mysql 具有奇数一对多关系的高效SQL模式设计
我试图找出一种有效的方法来实现MySQL数据库中两个表之间的以下关系,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。尽管它们具有相同的项目名称和成本,但它们来自不同的
列表(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。由于联接表的行长很小,且列已编制索引,因此,为了提高效率,请选择高效。最后,从联接表中得到所需的一小部分项索引值,然后由联接使用。