Sql 一个订单上多个不同产品的表格设计

Sql 一个订单上多个不同产品的表格设计,sql,relational,data-modeling,Sql,Relational,Data Modeling,如果我有一个销售苹果和显示器的在线购物网站,并且它们存储在不同的表中,因为苹果的区别属性是颜色,显示器的区别属性是分辨率,那么我如何将这两个属性添加到发票表中,同时仍然保留参考完整性,并且不合并这些表 Invoices(InvoiceId) | InvoiceItems(ItemId, ProductId)

如果我有一个销售苹果和显示器的在线购物网站,并且它们存储在不同的表中,因为苹果的区别属性是颜色,显示器的区别属性是分辨率,那么我如何将这两个属性添加到发票表中,同时仍然保留参考完整性,并且不合并这些表

                        Invoices(InvoiceId)
                                 |
                  InvoiceItems(ItemId, ProductId)
                                 |
                       Products(ProductId)
              |                                            |
Apples(AppleId, ProductId, Colour)   Monitors(MonitorId, ProductId, Resolution)

首先,我会将它们存储在一个Products表中,而不是两个不同的表中

其次,(除非每个发票只针对一种产品),我不会将它们添加到单个发票表中,而是设置一个发票产品表,以链接表之间的链接


我建议您研究一下。

所以发票表有一个ProductID FK,ProductID可以是AppleID(PK颜色)或MonitorID(PK分辨率)

如果是这样,您可以引入一个ProductTypeID,其值为0=apple、1=monitor,或者如果只有两种产品类型,则可以引入一个isProductTypeApple布尔值,并将其包含在ProductID表PK中


您还需要在Apple表和Monitor表PK中包含ProductTypeID字段。

我喜欢这些表的名称-值表……重新设计可能更容易,所以它会变成“Product”,然后是“Product details”…Product details保存产品id、详细信息类型,然后是值。这将允许您在同一个表中保存苹果和监视器,而不考虑标识属性(并将其保留为打开状态,以便稍后添加其他产品)

发票表中也可以采用类似的方法……有一个“product_type”列,告诉您要查看哪个表(apple或monitor),然后是一个“product_id”,它引用apple/monitor表中的任何id列。对这样的设置进行查询有点困难,可能会迫使您使用动态sql…只有在您无法控制上述重新设计的情况下,我才会采用这种方法(此处发布的其他答案请参阅)


第一种解决方案是优先选择的,我认为……将此db上的设计更改为产品的名称-值对,这样以后编写查询时就省去了麻烦。

您的数据模型的一个问题是,您需要一个参考方案来识别产品吗?也许吧

然后通过指定SKU将每个苹果识别为产品。监视器也是如此。然后在发票项目中使用SKU。大概是这样的:

产品{sku} 密钥{sku}

发票项目{发票id,sku} 密钥{发票id,sku}

苹果{颜色,sku} 键{color} 密钥{sku}

监视器{大小,sku} 键{size} 密钥{sku}


有适当的限制。。。特别是,apple{sku}和monitor{sku}==product{sku}的联合。

如果我将它们存储在一个组合产品表中,这难道不意味着拥有一个可空的分辨率和颜色列,该列将仅根据特定产品是monitor还是apple来填充吗?规范化建议仅在表中包含与主键直接相关的列。关于链接表,这一点很好。我过分简化了问题,忽略了这个细节。我将更新问题。发票(InvoiceId)|发票项目(ItemId,ProductId)|产品(ProductId)| |苹果(AppleId、ProductId、color)监视器(MonitorId、ProductId、Resolution)没有名称值表意味着只有字符串(varchar)值?如果某些属性是数字或日期值,需要具有可比性/类型安全性,该怎么办?显然,这里的查询/用户界面很复杂,但我面临的主要困难似乎首先是数据库结构。我想也许我可以制作4个不同的名称值表,每个表包含不同的类型(int、float、datetime、varchar)但是这就产生了一个新的问题,即知道如何链接到正确的名称-值表!是的,您对这个限制是正确的…varchar或nvarchar是您唯一可以处理抛出的几乎任何数据类型的数据类型。有可能会有一个“datatype”列与该值一起使用,尽管这会迫使您以后使用更动态的sqln to do转换为不同的数据类型。您为什么不能将其存储为varchar并在查询中引用它时转换为所需的任何数据类型?