我有一张叫做汽车的桌子,但是每辆车都有数百个属性,随着时间的推移它们会不断增加(马力,扭矩,空调,电动车窗等......)我的桌子将每个属性都作为一个列。当我有数千行和数百列时,这是正确的方法吗?此外,我将每个属性设为一列,以便于高级搜索/过滤。
使用 MySQL 数据库。
由于
答案 0 :(得分:4)
我想明显的问题是,那么:为什么没有表car_attrs(car,attr,value)?每个属性都是一行。大多数查询都可以重写以使用此表单。
答案 1 :(得分:4)
这是一个有趣的问题恕我直言,答案可能取决于您的具体数据模型和实施。在这种情况下,最重要的因素是数据密度。
平均每行实际填充了多少?
让我们使用您提到的案例,并进行一些模拟。
在第一种情况下,范围分区,我们的想法是根据范围或用法实现分区。作为按使用情况分区的一个例子,假设检索到的字段最多的是Model,Year,Maker和Color。这些字段可以组成您的主[CAR]表,ID字段的所有者将专门识别车辆。 现在让我们说发动机,马力,扭矩和气缸也不时用于搜索,但不是那么频繁。这些可能存在于辅助表[CAR_INFO_1]上,该辅助表通过CAR_ID字段(外键)的存在与第一个表绑定。继续创建所需的分区。
优势:更简单的查询。如果您进行联合查询(例如在VIEW内),您可以合并关于车辆的所有信息。
下行:维护。每个新字段都必须在模型本身中实现,并且您需要更新的数据模型来定位实际存储所需字段的位置(或在视图中抽象它。)
元数据格式更加优雅,但需要更多数据库引擎。查看@ JayC和@Nitzan Shaked的答案以获取详细信息。
优点:100%的数据密度。你永远不会有空的数据值。另外维护 - 通过将其作为行添加到元数据标识符表来创建新属性。数据结构也不那么复杂。
下行:复杂查询以及更复杂的执行计划。假设您需要2010年制造的所有福特汽车都是蓝色的。在第一个案例中,这将是非常微不足道的:
SELECT * FROM CAR WHERE Model='Ford' AND Year='2010' AND Color='Blue'
现在对元数据结构模型进行相同的查询:
假设存在这两个表,
CAR_METADATA_TYPE
ID DESC
1 'Model'
2 'Year'
3 'Color'
和
CAR_METADATA [CAR_ID], [METADATA_TYPE_ID], [VALUE]
查询本身就像这样:
SELECT * FROM CAR, CAR_METADATA [MP1], CAR_METADATA [MP2], CAR_METADATA [MP3]
WHERE MP1.CAR_ID = CAR.ID AND MP1.METADATA_TYPE_ID = 1 AND MP1.Value='Ford'
AND MP2.CAR_ID = CAR.ID AND MP2.METADATA_TYPE_ID = 2 AND MP2.Value='2010'
AND MP3.CAR_ID = CAR.ID AND MP3.METADATA_TYPE_ID = 3 AND MP3.Value='Blue'
所以,这一切都取决于你的需求。但鉴于你的情况,我的建议是元数据格式。
(但首先进行模型清理 - 没有重复的字段,1:N数据在他们自己的表上而不是内联字段,如Color1,Color2,Color3,这种东西;)
答案 2 :(得分:2)
如果完全是关于功能,请创建一个features
表,将所有功能列为行并为其提供某种自动ID,并创建一个car_features
使用外键到你的cars
表和你的features
表,它将汽车与功能相关联,可能还有与该关系相关的任何值(一个乘客电动座椅等)。
答案 3 :(得分:-2)
如果您要更改属性,请考虑将它们存储在一个列中的XML blob或文本结构中。这种结构不是关系型的。然后,最重要的属性将在其他列中重复,以便您可以创建查询以搜索它们,因为Blob将无法从SQL查询中搜索。这将减少该表中的列数,并允许在不更改数据库架构的情况下进行扩展。
与其他人一样,如果您想要表中的所有属性,请使用属性表来定义它们。然后将取决于您的要求和应用程序的需求。