2014-05-07 24 views
1

因爲我一直在閱讀Mongo文檔,所以這並不意味着消極。我對這個概念很陌生。 Mongo被吹捧爲這個殺死MySQL的超高效數據庫,但是我讀的所有Mongo語句似乎都是可以縮減的,因此沒有更高效的SQL。也許我採取了錯誤的做法。此Mongo查詢與此SQL查詢相同嗎?我是否正確地考慮Mongo?

比方說,你有兩個表:

User 

ID Name FavoriteColor 
1  John 1 
2  Jona 2 
3  Jack 1 

Color 

ID Name 
1  Red 
2  Green 
3  Blue 

要得到用戶的顏色,我會做

SELECT 
    `u`.`Name`, 
    `c`.`color` 
FROM `user` AS `u` 
LEFT JOIN `color` AS `c` ON `u`.`FavoriteColor` = `c`.`id` 

不知道這句法是正確的,我沒有在MySQL的前我。

現在,Mongo不支持連接(人們說這就是Mongo的重點),所以如果我要這樣做,我會迭代用戶集合,然後對每條記錄進行查詢,然後查詢顏色數據庫以反映該用戶最喜歡的顏色ID和「迭代」顏色集合(應該只返回一行)。但是,這似乎是完全一樣的東西(在PHP):

<? 
     $query = "SELECT `Name`, `FavoriteColor` FROM `users`"; 
     $result = mysql_query($query); 
     while($row = mysql_fetch_array($result)) { 
      $username = $row["Name"]; 
      $query = "SELECT `Name` FROM `Color` WHERE `id` = " . $row["FavoriteColor"] . " LIMIT 1"; 
      $result = mysql_query($query); 
      $color = ""; 
      //I know we return only one row but I am illustrating the concept of scanning the entire color table 
      while($row2 = mysql_fetch_array($result)) { 
        $color = $row2["Name"]; 
      } 

      echo "Hi I'm $username and my favorite color is $color <br>"; 
     } 
?> 

從效率的角度來看,我不能看到的MongoDB如何能得到任何速度比SQL(加入或PHP迭代的方式似乎仍是一樣的東西)。在一天結束時,它必須掃描整個用戶表,並且對於每個用戶,它必須掃描整個顏色表以使colorID符合最喜歡的顏色。

我應該試圖從邏輯上減少MongoDB存儲下來的行\ colums \表,還是MongoDB本質上執行不同?

+0

下面是我對一個非常好的問題+1。現在我只需要等待Mongo狂熱者試着解釋這個,而不用挖掘他自己的墳墓:) –

回答

1

對於MongoDb中缺少加入支持,您是正確的。它允許MongoDB集合被自動分發而沒有風險,被要求在兩個分佈式集合(表)之間進行連接。如果可能的話,這將導致服務器上的大量工作,並且根本無法擴展。

所以它不支持連接,但它是面向文檔的數據庫,它支持嵌入式文檔。它顯着影響數據庫結構設計。現在您可以選擇是嵌入還是創建新的集合(表格),具體選擇取決於數據本身和數據使用模式,因此您需要了解您的數據使用模式。 讓我們回到你的例子,這兩個表可能可以在一個集合user合併,你可能有這樣的事情:

{ 
    name: John, 
    favoriteColor: Red 
} 

在這種情況下,沒有必要的聯接來檢索相同的數據。它是完全不同的結構設計。但是,MongoDB不支持約束(唯一性除外),並且您需要注意不要使用不存在的顏色。爲此,您可以單獨收集color,並在將數據插入收集user時檢查數據。

結束語: MongoDB的效率並不是在快速執行相同的操作,而是在於使用不同的範例來模擬老問題。

+0

我也可以在SQL用戶表中放置「Red」,但有時候人們有兩個表,因爲我們可以說Red,Green ,而藍色是唯一可用的顏色。我有一個單獨的表格,這樣我就可以查詢它來填充下拉列表或其他東西。在MongoLand中,你只是按照你所描述的做了什麼,然後爲可用的顏色提供一個單獨的集合? – user3612042

+0

如果您需要約束值,您仍然會在MongoDB中爲顏色分開收集。這裏沒有黑魔法。你也可以在SQL用戶表中放入Red(儘管它會破壞標準化)。但讓我們超越這個簡單的例子,想象用戶可以有多種不同的顏色,也可以有一些偏好,也可以有一些設置。在MongoDb中,您可以將所有這些東西放在一個文檔中,並提供豐富的選項以供查詢,此外還可以通過副本集和通過分片分發來提供持久性。 –

-1

首先,Mongo可能會殺MYSQL,但它甚至不接近MYSQL。

User 

ID Name FavoriteColor 
1  John RED 
2  Jona GREEN 
3  Jack RED 

這就是你的數據在mongo中的樣子。 Mongo不支持連接,但支持嵌入式文檔。如果您要頻繁查詢數據,建議您始終將數據放入mongo的單個集合中。總之,沒有顏色表/集合。最有可能的是,獲取用戶和顏色的查詢將是

db.collection.find({},{name:1,favoriteColor:1}) 

並且您的集合文檔將如下所示。

{ 
    id: 1 
    name: John 
    FavCol: RED 
} 
+0

您知道這不會輕微回答這個問題嗎? –

+0

@ N.B。我覺得是這樣的。 –

+0

我不會試圖向你解釋這個問題,但你基本上重複了OP在他的文章中提到的內容。把這個作爲答案是很愚蠢的。 –

1

爲了能夠理解MongoDb,您需要嘗試從您使用RDBMS學到的東西中剝離您的想法。

MongoDB是一個「動態模式」系統,一個基於文檔的數據庫,圍繞着對象概念的數據。

在您發佈的示例中,您正在使用的結構仍在爲您的設計實現更多的關係數據庫方法。爲了擴展複雜的數據和開發速度,並且記住沒有加入支持,我建議你重新設計你的設計,並且即使你認爲它看起來多餘也會「去規範化」你的收藏(基於如何數據庫已經設計了過去40年)