假设我需要在我的产品表中存放T恤和牛仔裤。他们分享成本,价格,数量等栏目,但腰部(仅适用于牛仔裤)和尺码(仅适用于T恤)。我应该将它们全部放在一张桌子还是单独的桌子上?如果我把它们放在一起,我会有很多空值,但如果我将它们分开,那么链接它们的最佳方法是什么?
非常感谢。
答案 0 :(得分:3)
有几种方法可以解决这个问题。
您已经描述了一个single-table inheritence(其中有一堆空列用于不相关的属性)。
RPM1984的回答建议class-table inhertience,其中共享数据进入主表,每个“类型”获得额外属性的自己的表。
或者,按照亚历克斯和邮递员的建议,你可以Entity/Attribute/Value。
每种方法都有利有弊。最大的问题是RDMBS很难在其中任何一个上强制执行参照完整性。
在做出决定之前,你应该非常认真地思考你的问题。 EAV提供了最大的灵活性(您可以分配任意属性,而不必更改架构),但最终您在应用程序层中进行了大量处理。并且,您无法轻松获得具有所有属性的单个结果行。
如果我非常确定我知道我需要建模的每个“类型”,并且我将来不太可能需要创建更多类型,那么我将继续使用类表继承。
使用类表继承,您可以使用简单的内连接(select * from products inner join pants
)按类型进行过滤,例如,只选择裤子。
答案 1 :(得分:2)
您可以拥有products_attributes
表格,其中腰围可能是5
而尺寸可能是8
(取决于具体方式)它已经建立)。这也允许您以后轻松添加新属性(甚至可以让最终用户添加新属性)。
然后你可以有像
这样的列| attribute_id | value | product_id |
=====================================
| 5 | "30cm"| 28 |
=====================================
答案 2 :(得分:2)
我会选择以下内容:
<强>产品强>
ProductID INT IDENTITY,
Cost DECIMAL(4,2),
Price DECIMAL(4,2),
Quantity INT
<强>让强>
ProductID INT,
Waist INT
<强>衬衣强>
ProductID INT,
Size INT
然后,您可以在Jean / Shirt表上将ProductID作为Product的ProductID列的外键。
这样,您扩展核心产品属性以适应更具体的产品。
此外,您可以添加更多特定产品(新表),而不会影响现有产品或产品表架构。
我们目前正在实施类似的结构,以便我们的应用程序ORM可以支持实体的“继承”。
要获得牛仔裤,您的查询将是:
SELECT Product.ProductID, Product.Cost, Product.Price, Product.Quantity, Jean.Waist
FROM Product Product
INNER JOIN Jean Jean
ON Product.ProductID = Jean.ProductID
当然,如果你正在寻找一个简单的改变,下面的答案就可以了。
但这是未来产品添加的数据库“面向未来”。
HTH
答案 3 :(得分:1)
您可以添加产品属性表,该表是多个属性的一个产品。
每个属性都有一个类型和值,这可以解决您的问题:)