摘要:在處理關(guān)聯(lián)關(guān)系,嵌套對象和父子關(guān)聯(lián)關(guān)系中,我們會討論幾種可行方案的優(yōu)點和缺點。在關(guān)系數(shù)據(jù)庫中,處理關(guān)聯(lián)關(guān)系的方式讓你不會感到意外每個實體或者行,在關(guān)系世界中可以通過一個主鍵唯一標(biāo)識。但是關(guān)聯(lián)關(guān)系很重要。
數(shù)據(jù)建模(Modeling Your Data)
ES是一頭不同尋常的野獸,尤其是當(dāng)你來自SQL的世界時。它擁有很多優(yōu)勢:性能,可擴(kuò)展性,準(zhǔn)實時的搜索,以及對大數(shù)據(jù)的分析能力。并且,它很容易上手!只需要下載就能夠開始使用它了。
但是它也不是魔法。為了更好的利用ES,你需要了解它從而讓它能夠滿足你的需求。
在ES中,處理實體之間的關(guān)系并不像關(guān)系型存儲那樣明顯。在關(guān)系數(shù)據(jù)庫中的黃金準(zhǔn)則 - 數(shù)據(jù)規(guī)范化,在ES中并不適用。在處理關(guān)聯(lián)關(guān)系,嵌套對象和父子關(guān)聯(lián)關(guān)系中,我們會討論幾種可行方案的優(yōu)點和缺點。
緊接著在為可擴(kuò)展性而設(shè)計中,我們會討論ES提供的一些用來快速靈活實現(xiàn)擴(kuò)展的特性。對于擴(kuò)展,并沒有一個可以適用于所有場景的解決方案。你需要考慮數(shù)據(jù)是如何在你的系統(tǒng)中流轉(zhuǎn)的,從而恰當(dāng)?shù)貙δ愕臄?shù)據(jù)進(jìn)行建模。針對基于時間的數(shù)據(jù)比如日志事件或者社交數(shù)據(jù)流的方案比相對靜態(tài)的文檔集合的方案是十分不同的。
最后,我們會討論一樣在ES中不會擴(kuò)展的東西。
處理關(guān)聯(lián)關(guān)系(Handling Relationships)
在真實的世界中,關(guān)聯(lián)關(guān)系很重要:博客文章有評論,銀行賬戶有交易,客戶有銀行賬戶,訂單有行項目,目錄也擁有文件和子目錄。
在關(guān)系數(shù)據(jù)庫中,處理關(guān)聯(lián)關(guān)系的方式讓你不會感到意外:
每個實體(或者行,在關(guān)系世界中)可以通過一個主鍵唯一標(biāo)識。
實體是規(guī)范化了的。對于一個唯一的實體,它的數(shù)據(jù)僅被存儲一次,而與之關(guān)聯(lián)的實體則僅僅保存它的主鍵。改變一個實體的數(shù)據(jù)只能發(fā)生在一個地方。
在查詢期間,實體可以被聯(lián)接(Join),它讓跨實體查詢成為可能。
對于單個實體的修改是原子性,一致性,隔離性和持久性的。(參考ACID事務(wù)獲取更多相關(guān)信息。)
絕大多數(shù)的關(guān)系型數(shù)據(jù)庫都支持針對多個實體的ACID事務(wù)。
但是關(guān)系型數(shù)據(jù)庫也有它們的局限,除了在全文搜索領(lǐng)域它們拙劣的表現(xiàn)外。在查詢期間聯(lián)接實體是昂貴的 - 聯(lián)接的實體越多,那么查詢的代價就越大。對不同硬件上的實體執(zhí)行聯(lián)接操作的代價太大以至于它甚至是不切實際的。這就為在單個服務(wù)器上能夠存儲的數(shù)據(jù)量設(shè)下了一個限制。
ES,像多數(shù)NoSQL數(shù)據(jù)庫那樣,將世界看作是平的。一個索引就是一系列獨立文檔的扁平集合。一個單一的文檔應(yīng)該包括用來判斷它是否符合一個搜索請求的所有信息。
雖然在ES中改變一份文檔的數(shù)據(jù)是符合ACIDic的,涉及到多份文檔的事務(wù)就不然了。在ES中,當(dāng)事務(wù)失敗后是沒有辦法將索引回滾到它之前的狀態(tài)的。
這個扁平化的世界有它的優(yōu)勢:
索引是迅速且不需要上鎖的。
搜索是迅速且不需要上鎖的。
大規(guī)模的數(shù)據(jù)可以被分布到多個節(jié)點上,因為每份文檔之間是獨立的。
但是關(guān)聯(lián)關(guān)系很重要。我們需要以某種方式將扁平化的世界和真實的世界連接起來。在ES中,有4中常用的技術(shù)來管理關(guān)聯(lián)數(shù)據(jù):
應(yīng)用端聯(lián)接(Application-side joins)
數(shù)據(jù)非規(guī)范化(Data denormalization)
嵌套對象(Nested objects)
父子關(guān)聯(lián)關(guān)系(Parent/child relationships)
通常最終的解決方案會結(jié)合這些方案的幾種。
應(yīng)用端聯(lián)接(Application-side Joins)
我們可以通過在應(yīng)用中實現(xiàn)聯(lián)接來(部分)模擬一個關(guān)系型數(shù)據(jù)庫。比如,當(dāng)我們想要索引用戶和他們的博客文章時。在關(guān)系型的世界中,我們可以這樣做:
PUT /my_index/user/1 (1) { "name": "John Smith", "email": "john@smith.com", "dob": "1970/10/24" }
PUT /my_index/blogpost/2 (2) { "title": "Relationships", "body": "It"s complicated...", "user": 1 (3) }
(1)(2) 索引,類型以及每份文檔的ID一起構(gòu)成了主鍵。
(3) 博文通過保存了用戶的ID來聯(lián)接到用戶。由于索引和類型是被硬編碼到了應(yīng)用中的,所以這里并不需要。
通過用戶ID等于1來找到對應(yīng)的博文很容易:
GET /my_index/blogpost/_search { "query": { "filtered": { "filter": { "term": { "user": 1 } } } } }
為了找到用戶John的博文,我們可以執(zhí)行兩條查詢:第一條查詢用來得到所有名為John的用戶的IDs,第二條查詢通過這些IDs來得到對應(yīng)文章:
GET /my_index/user/_search { "query": { "match": { "name": "John" } } }
GET /my_index/blogpost/_search { "query": { "filtered": { "filter": { "terms": { "user": [1] } (1) } } } }
(1) 傳入到terms過濾器的值是第一條查詢的結(jié)果。
應(yīng)用端聯(lián)接最大的優(yōu)勢在于數(shù)據(jù)是規(guī)范化了的。改變用戶的名字只需要在一個地方操作:用戶對應(yīng)的文檔。劣勢在于你需要在搜索期間運行額外的查詢來聯(lián)接文檔。
在這個例子中,只有一位用戶匹配了第一條查詢,但是在實際應(yīng)用中可能輕易就得到了數(shù)以百萬計的名為John的用戶。將所有的IDs傳入到第二個查詢中會讓該查詢非常巨大,它需要執(zhí)行百萬計的term查詢。
這種方法在第一個實體的文檔數(shù)量較小并且它們很少改變時合適(這個例子中實體指的是用戶)。這就使得通過緩存結(jié)果來避免頻繁查詢成為可能。
反規(guī)范化你的數(shù)據(jù)(Denormalizing Your Data)
讓ES達(dá)到最好的搜索性能的方法是采用更直接的辦法,通過在索引期間反規(guī)范化你的數(shù)據(jù)。通過在每份文檔中包含冗余數(shù)據(jù)來避免聯(lián)接。
如果我們需要通過作者的名字來搜索博文,可以在博文對應(yīng)的文檔中直接包含該作者的名字:
PUT /my_index/user/1 { "name": "John Smith", "email": "john@smith.com", "dob": "1970/10/24" }
PUT /my_index/blogpost/2 { "title": "Relationships", "body": "It"s complicated...", "user": { "id": 1, "name": "John Smith" } }
現(xiàn)在,我們可以通過一條查詢來得到用戶名為John的博文了:
GET /my_index/blogpost/_search { "query": { "bool": { "must": [ { "match": { "title": "relationships" }}, { "match": { "user.name": "John" }} ] } } }
對數(shù)據(jù)的反規(guī)范化的優(yōu)勢在于速度。因為每份文檔包含了用于判斷是否匹配查詢的所有數(shù)據(jù),不需要執(zhí)行代價高昂的聯(lián)接操作。
http://blog.csdn.net/dm_vincent/article/details/47710367
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/64523.html
閱讀 1010·2021-11-22 13:52
閱讀 924·2019-08-30 15:44
閱讀 570·2019-08-30 15:43
閱讀 2424·2019-08-30 12:52
閱讀 3473·2019-08-29 16:16
閱讀 637·2019-08-29 13:05
閱讀 2943·2019-08-26 18:36
閱讀 1975·2019-08-26 13:46