RDBMS - 存储与一条记录相关的多个键值的最佳方式

RDBMS - Best way to store several key value related to one record

我正在开发一个类似于市场的网站,注册卖家可以在其中销售不同种类的商品。对于每个项目,都有公共属性和可选属性。看看下面的,我会尽力解释的。

场景

  1. 卖家添加新商品(例如iPhone 6 16 gb black
  2. 他构建了指定项目属性的插入(例如 价格运费条件图片描述,等等)。这种属性对于任何项目都是必需的和通用的。
  3. 一旦填写了所有必需的属性,卖家就可以指定仅与该商品相关的其他类型的属性(例如 RAM容量尺寸重量型号年份OS核心数,等等)。这种属性是可选的。卖家指定键(例如容量)和值(例如16 gb),它们仅与该单个项目相关。另一位卖家出售的 iPhone 6 16 gb black 可能具有不同的属性。

实际上我们有一个名为 items 的 table,其中包含所有待售物品,另一个 table 称为 item_attr 其中包含常见的项目属性。因此,一个项目可能与 0 个、1 个或多个可选属性相关。

我们正在研究两种方法来存储每个项目的可选值,但这两种方法都可能带来问题。

案例A

Create a new table called item_additional_attr where each record will represents an additional attribute for a single item. There will be a one-to-many relationship between items and item_additional_attr. This seems to be the most "database-friendly" solution, but I'm worried about the size of this table could have. If items contains 100.000 records and each item is related to an average of 5 optional attributes, item_additional_attr will contains 500.000 records. Of course that will be a huge table.

案例 B

Create a new field type TEXT or BLOB into item_attr called optional_attributes. This field will contains an array of optional attributes and will be handled in PHP. Of course the array will be stored as serialized or json encoded. I think this kind of approach could bring problems with some queries, but it could be handled without problems in PHP.

我优先考虑 webserver/db 性能,但我也会避免查询问题。此外,附加属性将仅用于显示 table 中的技术规格,绝不会用于 filtering/sorting。那么,在您看来,实现这一目标的最佳方式是什么?

您可能想尝试使用 EAV(实体属性值)table。基本上你会维护几个tables。一个 table 应该存储项目列表。其他 tables 应该维护所有具有相似数据类型的属性。我创建了一个简单的模式来演示:

+---------+------------+
| item_id | item_name  |
+---------+------------+
|       1 | Cell Phone |
|       2 | Shirt      |
+---------+------------+
2 rows in set (0.00 sec)

+---------+--------------+----------------+-----------------+
| item_id | attribute_id | attribute_name | attribute_value |
+---------+--------------+----------------+-----------------+
|       1 |            2 | storage        | 8GB             |
|       1 |            3 | color          | Gray            |
|       2 |            4 | size           | XL              |
|       2 |            6 | shirt_color    | Red             |
+---------+--------------+----------------+-----------------+
4 rows in set (0.00 sec)

+---------+--------------+----------------+-----------------+
| item_id | attribute_id | attribute_name | attribute_value |
+---------+--------------+----------------+-----------------+
|       1 |            2 | price          |              49 |
+---------+--------------+----------------+-----------------+
1 row in set (0.00 sec)

第一个 table 是项目列表。第二个 table 是 varchar 类型的项目属性列表。第三个 table 列出项目的 int 类型属性。这将允许一个可扩展的数据库将属性分散到多个 tables。唯一的缺点是为了获得一个项目及其所有属性,您需要进行大量的连接。可以通过 php 使用文本缓存方案来存储项目信息以提高性能。