【问题标题】:Most Performant Way to Store Non-Standard Data存储非标准数据的最佳性能方式
【发布时间】:2015-07-07 05:58:00
【问题描述】:

背景

我必须存储有关一组产品的信息。此信息将通过 PHP 提取到网站上,可能与 WordPress 一起使用,可能使用原始 PHP。问题是这些产品的属性不一致。示例:

产品A

  • 宽度 => 6"
  • 高度 => 5 英寸
  • 重量 => 2 磅
  • 颜色 => 黑色

产品 B

  • 重量 => 3 磅
  • 制造商 => 微软
  • 日期 => 2015-02-01

简单的答案是 SQL 中的单个表,其列数量不断增加,其中大部分为空,以涵盖所有可能的属性。不过,考虑到可能的属性数量和对可扩展性的需求,我认为这不是要走的路。


想法 1

我的一个想法是设置一个表,每一行都是一个产品,并有一个 ID。第二个表的每一行都是一个属性,由产品 ID 链接。

表 1

Product | ID
Phone   | 0001
Table   | 0002

表 2

Product ID | ID   | Attribute Label | Attribute Value
0001       | 0001 | Height          | 2"
0001       | 0002 | Width           | 3"
0001       | 0003 | Weight          | 2lb
0002       | 0004 | Company         | Apple
0002       | 0005 | Color           | Black
0002       | 0006 | Weight          | 2lb

我看到的问题是表 2 的行数很大。


想法 2

嵌套数组,以某种方式存储

表格

Product | Attributes | ID
Phone   | ARRAY      | 0001
Table   | ARRAY      | 0002

ARRAY 是一个键值对数组。也许序列化并存储?我认为我可以拥有无​​限的键值对集。


我的问题

实现存储此类数据的最高效方法是什么?有最佳实践吗?是否有完全不同类型的数据库?我听说过 JSON 这个短语,它在这里有用吗?

【问题讨论】:

  • 存储数据的最佳方式取决于数据的使用方式。您的问题不包含任何此类相关信息。
  • 添加了使用信息。
  • 首先,我们必须停止使用“性能”这个词。 ¯\_(ツ)_/¯
  • 产品类别如何?这有助于使事情正常化。
  • 这是我正在考虑的一件事。一组至少可以部分归一化的类别。但是对于我正在使用的产品,即使是同一类别的产品也不完全正常。

标签: php mysql database schema


【解决方案1】:

JSON 是您正在寻找的,但前提是您不想通过这些“额外”属性之一来搜索或排序您的数据库。用法极其简单,内置了json_encodejson_decode PHP函数。 json_encode 将结构数据(例如您的参数数组)转换为字符串表示形式,然后可以将其保存在 MySQL 的 TEXT 列中。如果您使用的是 postgres,那么还有 JSON 和 JSONB 类型。 json decode 完全相反,将文本转换回参数数组。

JSON 序列化 绝对可以在您的场景中为您提供尽可能高的性能。

如果需要按这些属性进行搜索或排序,那么属性表可能更适合您的需要。

【讨论】:

    【解决方案2】:

    如果您不需要系统地查询/搜索数据,可以使用 JSON json_encode() 或 PHP serialize() 来存储数据。

    如果您确实需要系统地查询/搜索数据,我个人更喜欢非标准存储在数据库中的键/值对。我建议使用两张桌子。例如:

    TABLE PRODUCTS:
    
    ID    | ProductName    | Category | Price  | ...
    ------+----------------+----------+--------+----
    12345 | Toothbrush     | Misc.    |   2.99 | ...
    12115 | MS Windows DVD | Software |  99.00 | ...
    76354 | AMD FX-8350    | CPUs     | 189.00 | ...
    
    TABLE PRODUCTSPECS:
    
    ID   | ProductID | KeyName   | Value
    -----+-----------+-----------+-------
    0001 |     12345 | Width     | 6"
    0001 |     12345 | Height    | 8"
    0002 |     12115 | Depth     | 6"
    0003 |     12115 | Mfg.      | Microsoft
    0004 |     76354 | Socket    | AM3+
    

    您可以更进一步,使用两个“关键”列,一个用于简短表单,一个用于描述性表单,尽管这实际上取决于您的应用程序。

    ID 对于每一行都是唯一的,最好设置为 auto_increment。 ProductID 应该使用约束,引用您的 products 表的 ID。

    【讨论】:

      【解决方案3】:

      也许您会“更快乐”使用基于文档的数据库,例如MongoDB.
      这与提出的 JSON 解决方案没有什么不同。例如文档说

      MongoDB 中的文档结构是支持所有 BSON 类型的 BSON 对象;但是,BSON 文档在概念上类似于 JSON 对象,并且具有以下结构:

      但您不会失去直接在数据库中搜索文档的能力 具有某些属性。

      【讨论】:

        【解决方案4】:

        您正在考虑的模型类型称为Entity-Attribute-Value Model,这对于您所描述的情况相当普遍。我不会在这里使用 JSON,它只是在存储或检索数据时增加了一层复杂性。

        【讨论】:

          【解决方案5】:

          为产品的常用属性创建一个表:

          products (product_id PK, product_name)
          

          以及相关的可选属性集的表格:

          weights (product_id PK/FK, weight)
          sizes (product_id PK/FK, width, height)
          colors (product_id PK/FK, color)
          manufactured (product_id PK/FK, company_id FK, date)
          

          EAV 模式使得强制完整性或查询变得困难,并且随着属性的数量而变得更糟。在购买之前做一些研究。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2010-09-28
            • 1970-01-01
            • 1970-01-01
            • 2018-12-01
            • 2013-09-10
            • 2014-07-28
            • 2012-05-10
            相关资源
            最近更新 更多