database - 具有大量数据的数据库性能

标签 database performance normalization

我不是在问索引或分区,我问的是一个选择,在添加大号之间。列或将数据添加为行。
说明:我们目前有一个设计请求,以处理某些特定产品的多个属性及其值
products 可能达到 1 亿条记录,每个产品可能有多个属性,因此 ProductProperties 表可能达到数十亿。
有人想到在 ProductProperties 表中添加属性作为列,Property1 和 value1,Property2 和 value2 等等......
如果产品不包含该属性的值,则该属性的相关字段将为空。他们还将添加大约 80-100 个属性,以便能够动态覆盖广泛的属性。
建筑师拒绝了这种方法,因为这不是一个好的设计。
谁能告诉我如何达到良好的设计和良好的性能。
谢谢

最佳答案

这个问题以多种形式出现。在您的情况下,您似乎拥有一系列产品,每个产品可能具有不同的属性集。我认为您需要一种以可扩展的方式存储这些属性的方法,以便您可以将新产品添加到系统中。

方法 1:行上的通用字段 + 补充元数据

您建议的第一种方法可以通过将产品属性元数据规范化到自己的表中来稍微修改:

  • 使用一些通用字段(Code1、Code2、IntVal1、IntVal2、FloatVal1 ...)
  • 构建您的产品表
  • 建立一套补充的父子引用表ProductTypeProductAttribute (或一些类似的)具有指导您的产品表上的哪些列包含哪些属性。
  • 构建功能以将其解释为应用程序的数据访问层。

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

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

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

    方法二:实体-属性-值

    这通常被提议作为此类问题的解决方案。在这种情况下,您有 ProductProductAttribute具有父子关系的表,其中包含一些根据产品类型筛选产品属性类型的引用数据。

    这种方法在概念上看起来很优雅并且是可扩展的,但查询起来很繁琐且效率低下,并且占用了相当多的磁盘空间。可以在各种平台上使用一些数据库设计技巧来缓解性能问题。您尚未指定您正在使用哪个 DBMS 平台,因此很难为您指明正确的方向。 EAV结构的主要优点和缺点是:
  • 无限灵活,无需更改数据库架构 (+)
  • 查询效率低且繁琐,特别是如果您想按多个属性进行过滤 (-)
  • 更多的磁盘空间使用。 (-)

  • 通常不推荐使用 EAV 结构,除非您有令人信服的要求。

    方法 3:XML 字段

    套用 Fredrick Lundh 的话:'now you have two problems' . XML 字段是无限可扩展的——您可以将任何您想要的内容放入其中,但除了您的应用程序之外,它们对任何东西都是不透明的,而且查询起来既缓慢又繁琐。从 SQL 查询中的 XML 字段中获取数据比存储在列上的数据要多得多。

    通常,在数据库中使用 XML 字段来存储本质上不是 XML 文档的东西是一个坏主意。许多人写过关于在数据库中滥用 XML 字段的不明智的做法。我构建 ETL 流程以从 XML 字段中提取数据的个人经验使我同意这一点。除非您有令人信服的理由,否则最好避免。

    结论

    方法 1 类似于您最初提出的方法,但将列元数据移到其自己的结构中。尽管它看起来并不优雅,但它几乎是所有情况下的最佳选择。

    关于database - 具有大量数据的数据库性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10163599/

    相关文章:

    Javascript - 标准化带重音的希腊字符

    c# - 删除字符串中除 "ñ"以外的重音符号

    php - 如何在 PHP 中列出来自 MySQL 的规范化数据?

    php - 如果更新了旧记录,如何插入新记录?

    database - 无法决定设置为主 ID 的方式和值

    performance - 缓慢的 MongoDB 查询 : can you explain why?

    mysql - 定期将数据加载到表中的最佳方法是什么

    MYSQL:语法错误: 'DELETE' 在此位置输入无效

    database - Redis 不保存数据

    regex - 提高 PowerShell 过滤语句的性能