什么是最佳做法对这个问题(不同性质为不同的类别)?
-
03-07-2019 - |
题
我有一些产品,属于某些类别。
每个类别可以有不同的性质。
例如,
- 类别 车 具有的性质 颜色, 功率...
- 类别 宠物 具有的性质 重量, 年龄, ...
数量类别的约10-15。数量的性质在每个类别为3-15。的产品数量是很大的。
主要要求为这个程序是非常好的搜索。我们将选择类别,并输入标准的每个属于这一类别。
必须设计数据库,用于这种情况。(SQL服务器2005年)
解决方案
经典的设计方式将(星表示的主要关键列):
Product
ProductId*
CategoryId: FK to Category.CategroyId
Name
Category
CategoryId*
Name
Property
PropertyId*
Name
Type
CategoryProperty
CategoryId*: FK to Category.CategoryId
PropertyId*: FK to Property.PropertyId
ProductProperty
ProductId*: FK to Product.ProductId
PropertyId*: FK to Property.PropertyId
ValueAsString
如果你能活着的事实是,每一财产的价值将会去的数据库作为一串和类型转换的信息都存储在酒店表,在此布局就足够了。
查询就是这样的:
SELECT
Product.ProductId,
Product.Name AS ProductName,
Category.CategoryId,
Category.Name AS CategoryName,
Property.PropertyId,
Property.Name AS PropertyName,
Property.Type AS PropertyType,
ProductProperty.ValueAsString
FROM
Product
INNER JOIN Category ON Category.CategoryId = Product.CategoryId
INENR JOIN CategoryProperty ON CategoryProperty.CategoryId = Category.CategoryId
INNER JOIN Property ON Property.PropertyId = CategoryProperty.PropertyId
INNER JOIN ProductProperty ON ProductProperty.PropertyId = Property.PropertyId
AND ProductProperty.ProductId = Product.ProductId
WHERE
Product.ProductId = 1
这个条件你源(conjunctively,例如使用),更快的查询会。如果你有正确地编入索引表。
因为它是解决方案不是一个理想的全部文字索引的情况。一个额外的表格,用于存储的所有文本与ProductId在一个更加规范化的方式可能在这里帮助。这表将需要更新的通过触发器,听着变化ProductProperty表。
其他提示
如果用户的应用程序 已 选择类别之前,他们可以搜索,我要分开你的产品进入不同的数据库中的表格按类别。这种解决方案还表示的事实,分类本身有那么一点共同点。按类别还将使每一个搜索速度更快,由于时间不会被浪费在汽车的时候你的用户在寻找一个宠物。
一旦你有的产品分类,它应该可以很容易地创建表使用的共同属性的产品在每个类别。的用户界面的应用应当是动态的(我在想一个网络的形式),在这一特性的用户可以从中选择应该改变用户选择一个类别。
请注意,如果你有你想要的产品中所列的多个类别,这种解决方案将导致重复的数据表。有一个贸易之间的速度和正常化的时候设计一个数据库。如果你 不不 有的产品适合在多个类别,然后我觉得这将会是最快的解决方案(在搜索速度)。
大多数人都建议使用的变化的实体-Attribute-Value(EAV)的设计。这种设计是矫枉过正的为你的状况,并引入了一大堆的问题,例如:
- 你不能定义的数据类型的属性;你可以进入"香蕉"为一个整数属性
- 你不能宣布一个属性作为强制性的(即不是空中常规表)
- 你不能宣布一外国的关键制约因素的属性
如果你有一个小号的类别,最好来使用的解决方案,一个在波格丹*马克西姆的答复。就是说,要定义一个表格的产品属性的共同所有的类别,以及一个额外的表格为每一个类别,以储存的类别特定的属性。
只有如果你有无数个类别,或者如果你必须潜在支持一组不同的特性,每行在产品是EAV一个很好的解决方案。但是然后你不用一个关系数据库,因为EAV违反若干规则的正常化。
如果你真的需要那么多的灵活性,你最好存储数据在XML。事实上,你可能会看到卢旺达国防军和语义网框架喜欢 芝麻.
你也许想要考虑的一个 实体属性的价值 种类型的安排,在这里你可以的"标记",每个产品具有任意name/value对的属性。
你可以试试这个。我不太确定实际细节的问题,也许有人可以帮你翻译一个好一点。
5表。3存储的数据,2个用于储存之间的映射数据。
tProduct
productID
<other product details>
tCategory
categoryID
<other category details>
tProperty
propertyID
<other property details>
tProductXCategory
productyID
categoryID
tCategoryXProperty
categoryID
propertyID
你的查询将需要加入数据使用的图表,但是这种会让你有不同的许多对多关系之间的分类、属性和产品。
使用存储的过程参数化或查询,以获得更好的表现出你的搜索。
如果你想要的灵活在您的类别和特性,应当创建以下表:
- 商品名:ProductID
- 类别:类别Id,ProductID
- 财产:PropertyID来说,类别Id
当你想分享一个类别过更比一个产品,必须创建一个链接表n:m加入:
- productCategoryPointer:ProdCatID,ProductID,类别Id.
你会得到一些联接在你的查询,但有权索引,你shoulb能够查询数据的快。
你可以试试更多的东西对象的取向。
1.定义一个基本表格的产品
Products(ProductID, CategoryID, <any other common properties>)
2.定义表的类别
Categories(CategoryID, Name, Description, ..)
从这里你有很多选项,并几乎所有的他们会打破正常化的数据库。
A.方案
将可维护性的噩梦如果你需要添加新产品
A1。定义一个单独表的每个类别
Cars(CarID, ProductID, ..)
Pets(PetID, ProductID, ..)
A2。加入该表的基础上的关系,以便使用的数据
SELECT <fields> FROM Cars INNER JOIN Products ON Cars.ProductID = Products.ProductID
方案B。
维护噩梦不同类型的性质(即int、varchar等)
B1。定义表性
CategoryProperty (CPID, Name, Type)
B2。定义表举行的协会之间的类别和特性
PropertyAssociation (CPID, PropertyID)
B12。定义表举行的特性(选择B1和B2)
Properties(CategoryID, PropertyID, Name, Type)
B3。对每种类型的财产(int、双varchar,等等。) 添加价值表
PropertyValueInt(ProductID, CPID, PropertyID, Value)
-为int
PropertyValueString(ProductID, CPID, PropertyID, Value)
字符串
PropertyValueMoney(ProductID, CPID, PropertyID, Value)
-为了钱
B4。加入所有的表,以获取所需的财产。
通过使用这种方法,你会不会来管理中的所有属性单独表,但价值类型。基本上所涉及的所有表将查找表。缺点是,为了检索每个数值,则需要"情况下"为每一个值的类型。
在牢记这些文章(在这里, 和 在这里,)在选择任何这些做法。 这个论坛后 也是有趣的,并以某种方式相关的问题,虽然它是关于本地化。
你也可以使用 Tomalak的答案 和加强打字如果你觉得有必要。
我最近有做到这一点,我使用它能够在那里我有三个实体
产品类别的选项OptionCategory
一个产品具有1*类别
一个产品具有1*的选择
一个选项具有1OptionCategory
一旦这个是设定可以使用它能够缓存
欢呼