2014-10-31 43 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