2014-10-31 46 views
1

我需要知道哪种数据库模型对性能更好。用于MYSQL产品特性的电子商务数据库结构(innoDB)

首先数据库模型

三表。功能,产品,功能值。

功能表

+----+-----------+ 
| id | name  | 
+----+-----------+ 
| 1 | Brand  | 
| 2 | Color  | 
| 3 | Dimension | 
| 4 | Model  | 
+----+-----------+ 

和特征值表

+----+---------+------------+ 
| id | name | feature_id | 
+----+---------+------------+ 
| 1 | Sony |   1 | 
| 2 | Samsung |   1 | 
| 3 | Red  |   2 | 
| 4 | Blue |   2 | 
| 5 | 20 " |   3 | 
| 6 | 30 " |   3 | 
| 7 | Model A |   4 | 
| 8 | Model B |   4 | 
+----+---------+------------+ 

和产品表。

+----+--------------------+----------+ 
| id | product_name  | features | 
+----+--------------------+----------+ 
| 1 | Sony Television | 1-3-5-7 | 
| 2 | Samsung Television | 2-4-6-8 | 
+----+--------------------+----------+ 

正如你在这个结构中看到,如果用户想根据功能搜索产品,我需要在我的查询中使用REGEXP或全文搜索。

二数据库模型

在第二个数据库模型,我会删除产品表的功能,我会添加新的表称为product_features。

+----+--------------------+ 
| id | product_name  | 
+----+--------------------+ 
| 1 | Sony Television | 
| 2 | Samsung Television | 
+----+--------------------+ 

和新表product_features;

+----+------------+------------+ 
| id | feature_id | product_id | 
+----+------------+------------+ 
| 1 |   1 |   1 | 
| 2 |   3 |   1 | 
| 3 |   5 |   1 | 
| 4 |   7 |   1 | 
| 5 |   2 |   2 | 
| 6 |   4 |   2 | 
| 7 |   6 |   2 | 
| 8 |   8 |   2 | 
+----+------------+------------+ 

现在,如果用户想根据功能搜索产品,我需要搜索product_features然后加入产品。

问题

我的问题是,如果我使用第二种模式,我有在产品表20十亿行,并认为至少有10种功能的每一个产品,所以product_features表将有超过200亿行。根据功能查询也许会很慢。

如果我使用第一个模型,当用户根据要素进行搜索时,我必须用全文搜索或REGEXP以20亿行查询。

我不知道哪种方式更好?你有什么建议?

回答

1

第一模型

它甚至不是在1NF形式,因为它具有非原子值在特征属性。此外,添加,更新或删除产品表中的任何新功能将非常困难。所以它根本不可行。

第二种模式

这是标准化的,直到5NF和看起来不错,优化搜索使用子查询和PRODUCT_ID和FEATURE_ID使用索引。尽量避免在如此大的数据中使用JOIN。

+0

谢谢您的回答。是的第一个模型不是1NF形式,但是第二个模型的性能如何。如果我在产品中有20亿个行,并且认为每个产品至少有10个功能,那么product_features表就会有200多亿行。 – 2014-10-31 06:54:04

+0

什么是您的搜索参数和预期输出是什么,那么我将能够更好地为您提供帮助。 – 2014-10-31 06:55:53

+0

我只需要知道这两个模型之间对于大型数据集的性能。当用户想要根据功能查找产品时,产品表中有20亿个行,哪种模式可以更快地获得结果。 – 2014-10-31 07:05:13

1

正如Rockse所说,你应该坚持第二种模式。对于大型数据集,一旦您增长到某个数据库实例开始变得太大的特定大小,您需要开始“横向”扩展(跨越多个实例)。缩放如此庞大的数据集的一种常见方式称为“分片”:将数据集分为多个子集并将其存储在不同的数据库服务器上。然后提出一个算法,告诉你的应用程序要去哪个数据库获取某个产品的信息。

例如,我们将数据集分成4个块,每个块约5亿行。然后使用“product_id%4”(即模4)作为“密钥”,它将告诉你哪个数据库实例包含有关该特定产品的信息。一个非常粗糙的伪代码可能是这样的:

connections = [] 

function initConnections() { 
    ... connect to 4 different databases or create pools ... 
    connections = [conn1, conn2, conn3, conn4]; 
} 

function getProductDbConnection(productId) { 
    return connections[productId%4]; 
} 

function getProductFeatures(productId) { 
    conn = getProductDbConnection(productId); 
    ... run whatever queries you need to get features ... 
} 

这里是谈论如何Instagram的分片他们的数据,以跟上需求的一篇文章:http://instagram-engineering.tumblr.com/post/10853187575/sharding-ids-at-instagram