2012-04-15 59 views
2

我不是在询问索引和分区,而是询问有关选择的问题,在添加大号数据之间。或者将数据添加为行。 说明:我们目前有一个设计要求,用于处理多个属性及其某些特定产品的值 产品可能会达到1亿条记录,并且每个产品可能具有多个属性,因此ProductProperties的表可能会达到数十亿。 有些人认为将属性添加为ProductProperties表中的属性,属性1和值1,属性2和值2等。 如果产品不包含该属性的值,则该属性的相关字段将为空。此外,他们将添加约80-100属性,以便能够动态地覆盖各种属性。 建筑师拒绝这种方法,因为这不是一个好设计。 任何人都可以告诉我如何达到良好的设计加上良好的性能。 谢谢具有大型数据集的数据库性能

+0

鉴于给定产品具有M种特性可能性的所有产品的特性的N个可能性;通用数据库设计将表明,随着时间的推移,属性的数量可能会发生变化,行将是合乎逻辑的选择;因为它不需要随着时间的推移而改变结构。 – xQbert 2012-04-15 16:05:52

+0

@Hossam - 您可能想考虑在[dba.se](http://dba.stackexchange.com/)[[这不仅仅是针对数据库管理员]](http://dba.stackexchange。 COM /常见问题)和标记这个MODS迁移。像这样的问题往往会迷失在SO上的噪音中,并经常得到不正确的答案。 – ConcernedOfTunbridgeWells 2012-04-15 18:20:39

回答

0

我会创建两个表:ProductProductProperties

Product将包含单个产品的基本属性。那种东西,需要和项目,如nameweightselling_quantity

ProductProperties将包含一切之间常见。规范化属性的属性,命名它们并创建你的表。所有你需要的是FK到Product,你准备好了。如果大多数属性都为空(我怀疑每个产品都需要80-100个属性,但我不知道您列出的产品是什么类型),那么表之间的1:n关系要好得多, 。

我在使用数十亿行时没有任何第一手经验,但数据库应该规范化,而不是用空列填充。这个答案似乎支持我的想法:Optimal database structure - 'wider' table with empty fields or greater number of tables?

我觉得你的第一个问题出现时,你的ProductProperties表有更多的行比unsigned bigint可以处理。这可能需要一段时间,我希望...

5

这个问题出现在一些伪装。就你而言,似乎你有一系列产品,其中每一种产品都可能有不同的属性。我认为你需要一种可扩展的方式来存储这些属性,以便你可以将新产品添加到系统中。

方法1:在该行+补充的元数据的通用领域

你建议,可以稍微修改了第一种方法通过标准化的产品属性的元数据到它自己的表:

  • 使用一些通用字段(代码1,代码2,IntVal1,IntVal2,FloatVal1 ...)构建产品表格

  • 构建父级子引用的补充集表格ProductTypeProductAttribute(或某些类似)可以指导产品表上哪些列包含哪些属性。

  • 构建功能来将其解释为应用程序的数据访问层。

这样做的主要优点是结构的查询效率高。缺点是product表的内容在没有补充元数据的情况下是不透明的。然而,其他方法的低效率和复杂性通常大大超过了这个缺点。

如果不同产品类型的数量相对较少,您还可以使用元数据生成视图或解释元数据的产品表上的一系列视图。这可以缓解很多不透明的问题。

另一个优点是,对产品有多个过滤条件的查询不必针对非常大的子表执行多个连接。如果表中的单个字段为空,则每个字段的开销(通常为每列一个字节,具体取决于平台)。未使用的字段会浪费记录中的空间。

方法2:实体属性值

这通常建议作为解决这一类的问题。在这种情况下,您有ProductProductAttribute表与子产品关系中的某些参考数据,这些参考数据根据产品类型过滤产品属性类型。

这种方法看起来在概念上是优雅的并且是可扩展的,但是查询和占用相当多的磁盘空间是烦琐和低效的。一些数据库设计的黑客可以在各种平台上使用,以缓解性能问题。你还没有指定你正在使用的DBMS平台,所以很难指出你正确的方向。主要优势和EAV结构的缺点是:

  • ,灵活度极高,而无需更改数据库schena(+)

  • 低效和繁琐的查询,特别是如果你想通过多个属性过滤( - )

  • 更多的磁盘空间使用情况。 ( - )

除非您有令人信服的要求,否则不建议使用EAV结构。

方法3:XML领域

套用弗雷德里克Lundh开发:'now you have two problems'。 XML字段是无限可扩展的 - 您可以将任何想要的东西放入它们中,但对于除应用程序之外的任何东西都是不透明的,而且它们查询速度慢并且很费劲。从SQL查询中的XML字段中获取数据要比存储在列上的数据更有效。

通常,在数据库中使用XML字段来存储非固有的XML文档是一个坏主意。很多人都写过关于在数据库中滥用XML字段的非智慧。我个人对构建ETL过程以从XML领域提取数据的经验使我同意。最好避免,除非你有一个令人信服的理由。

结论

方法1是类似于你最初提出的,但移动列元伸到自己的结构。尽管它看起来并不高雅,但它几乎在所有情况下都是最好的选择。

+0

拥有超过80个产品属性的表格真的很有效率吗?第一种方法是否表明我误解了你的解释?现在我很难应付这样一个事实,即需要80多个物业。也许应该将产品组织成组,并向DB添加一些表格,以便产品组A使用来自一个表格的属性和来自另一个表格的组B。 – 2012-04-15 17:37:16

+1

@ ZZ-bb如果您有80个可为空的列,则开销通常为每行80位或80个字节,具体取决于物理实现。如果您将其折叠到使用外部元数据设置的通用列,则该值将更小。一个EAV结构要求你多次加入一个大的子表,以获得所有的属性,而对这种类型的结构的复杂搜索可能效率很低。 – ConcernedOfTunbridgeWells 2012-04-15 17:44:45

+0

感谢您的信息。希望@Hossam可以判断产品分组是否有助于进一步最小化空字段。如果您拥有数百万种产品,很难想象分组/标准化不是一种选择。我希望Hossam没有一个有数百个指甲的产品表,唯一不同的是它们有多长或多长(但其中每一个都是独特的产品)... – 2012-04-15 17:53:45

0

现有的答案是正确的,非常好。这是一个新的想法:显然,将设计分成两个表格(Products,ProductAttributeValues)是最正常和最正确的方法。

但是,性能可以超过建筑的纯度。重要的唯一设计目标是将总体解决方案的成本降至最低。没有其他数字。如果非规范化模式提高了性能,以至于可以在其他地方节省性能,或者降低硬件成本,那么这是正确的。 只有TCO很重要。那很简单。

非规范化,如果它保存了你即使长期工作,或者它在硬件上保存。

+0

总的来说,我同意但你如何确定TCO是主观的。今天,在要求已知的情况下,可能会使数据不规范化,从而降低TCO。但是在9个月内需求增加了20个,而且如果我们开始使用规范化的数据,那么该解决方案的TCO成本要高出很多......您是否计划未来或者不是?是关于您现在知道的或您未来预期的投资回报率?但我会离开对其他讨论离开@ConcernedOfTunbridgeWells。 – xQbert 2012-04-15 21:17:15

+0

您可以在无限的未来优化预期的TCO,并且您可以预见它。这就是我们偏向主观性的地方......对于任何一种解决方案都没有硬性的论据。你期望有人回答“总是做X”吗?答案是:这取决于。你需要估计你期望发生的事情。 – usr 2012-04-15 21:19:25