RDBMS - 存储与一条记录相关的多个键值的最佳方式
RDBMS - Best way to store several key value related to one record
我正在开发一个类似于市场的网站,注册卖家可以在其中销售不同种类的商品。对于每个项目,都有公共属性和可选属性。看看下面的,我会尽力解释的。
场景
- 卖家添加新商品(例如iPhone 6 16 gb black)
- 他构建了指定项目属性的插入(例如 价格、运费、条件 ,图片,描述,等等)。这种属性对于任何项目都是必需的和通用的。
- 一旦填写了所有必需的属性,卖家就可以指定仅与该商品相关的其他类型的属性(例如 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 使用文本缓存方案来存储项目信息以提高性能。
我正在开发一个类似于市场的网站,注册卖家可以在其中销售不同种类的商品。对于每个项目,都有公共属性和可选属性。看看下面的,我会尽力解释的。
场景
- 卖家添加新商品(例如iPhone 6 16 gb black)
- 他构建了指定项目属性的插入(例如 价格、运费、条件 ,图片,描述,等等)。这种属性对于任何项目都是必需的和通用的。
- 一旦填写了所有必需的属性,卖家就可以指定仅与该商品相关的其他类型的属性(例如 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
orBLOB
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 使用文本缓存方案来存储项目信息以提高性能。