我無法回答何時使用鍵值(此處爲kv)數據存儲的問題,但我可以向您展示一些示例,並回答您的stackoverflow示例。
有了數據庫訪問,大部分你需要的是一個kv商店。例如,用戶使用用戶名「joe」登錄。所以你在你的數據庫中查找「user:joe」並檢索他的密碼(當然是散列)。或者,也許你在「user:pass:joe」下有他的密碼,那真的沒關係。如果它是堆棧溢出並且您正在渲染頁面http://stackoverflow.com/questions/6935566/when-to-use-a-key-value-store-for-web-development
,則會查找「question:6935566」並使用它。很容易看出kv商店如何解決你的大部分問題。
我想說kv商店是傳統RDMS提供的功能的一個子集。這是因爲傳統RDMS的設計提供了許多縮放問題,並且在縮放時通常會丟失功能。 KV商店不會提供這些功能,所以它們不會限制您。但是,這些功能通常可以創建,無論從核心設計還是可擴展的(因爲如果不是這些功能就顯而易見)。
但是,這並不意味着有些事情是你無法做到的。例如你提到查詢。這是許多KV商店的陷阱,因爲它們通常不知道價值(不總是正確的,例如,redis和更多),並且無法找到您正在尋找的東西。更糟糕的是,它們並不是設計得很快,它們只是快速地按鍵快速查找。
解決此問題的一個辦法是按照字典順序對鍵進行排序並允許範圍查詢。這基本上是「在問題1和問題5之間給我一切」。現在這個例子相當無用,但是範圍查詢有很多用途。
你說你想要所有的房子超過100000美元。如果你想能夠做到這一點,你會創建一個房價指數。假設你有下列房屋。
house:0 -> {"color":"blue","sold":false,"city":"Stackoverville","price":500000}
house:1 -> {"color":"red","sold":true,"city":"Toronto","price":150000}
house:2 -> {"color":"beige","sold":false,"city":"Toronto","price":40000}
house:3 -> {"color":"blue","sold":false,"city":"The Blogosphere","price":110000}
在SQL你的每個字段存儲在列而不是擁有一切在一個(在這種情況下JSON)文檔。並可以SELECT * FROM houses WHERE price > 100000
。這似乎一切都很好,但如果沒有建立索引,則需要查看桌子上的每個房屋並檢查其價格,如果您擁有幾百萬間房屋,則可能會很慢。所以對於一家kv商店,你也需要一個索引。主要的區別在於SQL數據庫會默默地做緩慢的事情,在那裏kv存儲將無法做到。
如果您沒有範圍查詢,您需要將索引粘貼到單個文檔中,這樣可以安全地更新它,這意味着您必須再次下載每個查詢的整個索引,從而限制了可伸縮性。
house:index:price -> [{"price":500000,"id":"0"},{"price":150000,"id":"1"},{"price":110000,"id":"3"},{"price":40000,"id":"2"}]
但如果你有範圍查詢(通常稱爲keyscans),你可以創建這樣一個指標:
house:index:price:040000 -> 2
house:index:price:110000 -> 3
house:index:price:150000 -> 1
house:index:price:500000 -> 0
然後你可以要求house:index:price:100000
和house:index:price::
(之間的鍵「:」字符是'9'後的字符),你會得到[3,1,0]
,這是所有的房子比$ 100 000更昂貴(他們也有幫助)。另一個好處就是它們可能位於羣集的一個「分區」上,因此這個查詢將與單獨獲取的時間大致相同(加上額外的傳輸開銷),或者如果您的範圍恰好超過一個服務器邊界(但這些可以並行完成!)。
這樣就顯示瞭如何在kv商店中查詢。你可以查詢任何可以作爲字符串排序的東西(幾乎任何東西),並很快查找它。如果你沒有範圍查詢,你需要將你的整個索引存儲在一個很糟糕的密鑰下,但是如果你有範圍查詢,它是非常好的,而且速度非常快。這是一個更復雜的例子。
我想要多倫多的房屋價格低於100000美元。我只需要設計我的索引。 (我在一些房屋中增加了它,使它更有意義)起初以爲你可能會爲每個房產建立另一個索引,但你很快就會意識到這意味着你必須選擇每個未售出的房子並從數據庫中下載它。 (當我說縮放問題立刻就很明顯時,這就是我的意思。)解決方案是使用多索引。一旦建成,你可以選擇你想要的值。
house:index:sold:city:price:f~Fooville~000010:5 -> ""
house:index:sold:city:price:f~Toronto~040000:2 -> ""
house:index:sold:city:price:f~Toronto~140000:4 -> ""
house:index:sold:city:price:t~Stackoverville~500000:0 -> ""
house:index:sold:city:price:t~The Blogosphere~110000:3 -> ""
house:index:sold:city:price:t~Toronto~150000:1 -> ""
現在,不像最後一個例子,我把id放在關鍵字中。這允許兩個房屋具有相同的屬性。我可以將它們合併到值中,但添加刪除索引變得更加困難。我還選擇將我的數據與~
分開。這是因爲它在所有字母后按字母順序排列,確保全名將被排序,並且我不必爲每個城市填充相同的長度。在生產系統中,我可能會使用字節255或0。
現在範圍house:index:sold:city:price:f~Toronto~100000
- house:index:sold:city:price:f~Toronto~~
將選擇與查詢匹配的所有房屋。重要的是要注意的是,查詢與結果的數量呈線性關係。這確實意味着你必須爲你想索引的每一組屬性建立索引(儘管我們的例子中的索引也適用於已售出和已售出的城市查詢)。這可能看起來像很多工作,但最終你意識到只是你在做,而不是你的數據庫。我敢肯定,我們將開始看到庫這種事情很快出來了:d
拉伸的話題了一下後,我已經表明:
我認爲你會發現,KV-商店足以讓許多應用往往可以提供更好的性能和可用性比傳統的關係數據庫管理系統。這就是說,每個應用程序是不同的,因此,不可能回答原來的問題。
敢肯定你可以做鍵值存儲的過濾器,如果你想 - 部分取決於商店的執行,也許在你自己的聰明才智。 –