欧美在线观看视频网站,亚洲熟妇色自偷自拍另类,啪啪伊人网,中文字幕第13亚洲另类,中文成人久久久久影院免费观看 ,精品人妻人人做人人爽,亚洲a视频

一種利用簡單路徑特征優(yōu)化樹狀結構數據的方法及系統(tǒng)與流程

文檔序號:11620651閱讀:292來源:國知局
本發(fā)明涉及數據處理
技術領域
:,特別涉及一種利用簡單路徑特征優(yōu)化樹狀結構數據的方法及系統(tǒng)。
背景技術
::隨著計算機網絡和大數據處理技術的發(fā)展,傳統(tǒng)關系型數據已經越來越不能滿足網絡和大數據環(huán)境下對數據定義和使用的要求,而以json和protocolbuffers為代表的半結構化數據因為既能夠充分的表達編程語言中對象(object)的數據,同時還能夠根據數據的格式變化對原有的數據格式進行修改和擴充,故而其在實際環(huán)境中被廣泛的使用。樹狀結構數據的定義:tvalue=tprimitive|tobject|tarraytprimitive=string|number|boolean|nullrecord=tobject如上所示,樹狀結構數據定義如下:1.樹狀結構數據中的值可以是以下的3種:object結構的數值;array結構的數值;原子類型的數值;2.object結構的數值由花括號包括,內部由多個鍵值對(keyvaluepair)對構成,鍵值對的個數可以是任意多個,但是要求不能有重復的key存在在object結構的對象中;3.array結構的數據由方括號包括,內部由多個值(value)構成,值的個數可是任意多個,且可能會有重復的值出現;4.原子類型的數據可以是字符串(string),數值(number),布爾值(boolean)和空(null)等;5.如上2中所述的鍵值對中,鍵的取值只能是(string)類型的。6.每一個樹狀結構的數據都是object結構的。常見的數據的來源由以下幾個方面:1)數據資料(datafeeds)以twitter為代表的在網絡中使用json格式對數據進行傳輸。用戶及相關api程序可以通過監(jiān)聽相應的端口獲得相應的數據更新。由于其數據內容豐富、結構相對復雜、數據來源比較穩(wěn)定并且提供的數據量足夠大,故本發(fā)明的實驗和數據分析的過程中主要基于twitter數據集。如下,本發(fā)明分析了對twitter數據中的嵌套層次和重復域的個數進行了相應的分析。2)在線數據服務(onlinedataservice)使用json格式的數據進行在線的數據服務。常見的類型為傳輸客戶端的相應操作內容和返回對應的操作結果等。本發(fā)明研究了不同來源的在線數據服務的半結構化數據,例如雅虎(yahoo),新浪微博和imdb等。通常用戶可以使葉子節(jié)點層次沒有重復域1個重復域多余2個重復域總計1160016261203335121476411942450120126012012總計129668203用json根據一定api接口格式編輯數據服務的需求,發(fā)送給相應的數據服務器之后,解析json格式的返回數據從而完成一次數據服務。本發(fā)明中對微博api的在線數據服務進行了相關的分析如圖1所示。本發(fā)明重點分析了其路徑中包含的重復的域的個數:圖中黑色部分為從根到葉子節(jié)點沒有重復域的路徑,淺色部分為僅有1個重復域的路徑,白色部分為有2個以上重復域的路徑。本發(fā)明中使用統(tǒng)計直方圖的方式顯示其構成的比例:大部分語法樹中從根到葉子節(jié)點的路徑最多只有1個重復的域。3)通信協(xié)議本發(fā)明分析了apachehadoop和hadoophbase中通信相關的協(xié)議格式,其使用的是protocolbuffers定義的半結構化數據進行通信相關的數據傳輸。在以上的系統(tǒng)中,定義了多種不同類型的半結構化通信格式,用于不同機器間的相互通信和控制。大部分用于通信的半結構化數據的格式十分簡單。本發(fā)明中對apachehadoop的通信協(xié)議進行了相關的分析如圖2所示。本發(fā)明重點分析了其路徑中包含的重復的域的個數:圖2中黑色部分為從根到葉子節(jié)點沒有重復域的路徑,淺色部分為僅有1個重復域的路徑,白色部分為有2個以上重復域的路徑。本發(fā)明中使用統(tǒng)計直方圖的方式顯示其構成的比例:大部分語法樹中從根到葉子節(jié)點的路徑最多只有1個重復的域。4)公用數據集通過分析dbpedia和data.gov中的數據,其使用json格式的數據進行公用數據集的存儲。但是區(qū)別于傳統(tǒng)意義上的半結構化數據文件,這些數據集中的數據僅由一條json數據組成。這條記錄主要分為兩部分:第一部分由一個嵌套子結構(json中的object)構成,存儲了之后數據集合中數據的格式;第二部分則由一個數組存儲每條記錄的內容,且每條記錄均為沒有嵌套的結構。本發(fā)明可以很輕松的將這條記錄拆分成數據定義和數據內容兩部分,進而使用傳統(tǒng)的半結構化數據處理的方法進行處理。5)傳感器數據最新的傳感器平臺,例如arduino,dragonboard,beaglebone等,均能夠產生和處理json類型的數據。本發(fā)明分析了以上來源的數據,發(fā)現其數據內部的格式更加的簡單:數據中所有域的嵌套深度最多為2且最多只會有一個多值域出現在從根到葉子節(jié)點的路徑上。但是現階段已有的數據處理系統(tǒng)不能對以上來源的json格式的半結構化數據進行很好的處理:既能夠提供完整功能的前提下,同時各項操作有較好的性能。本發(fā)明分析了大量支持半結構化數據管理系統(tǒng),其對半結構化數據的處理思路主要有以下三點:1)擴展傳統(tǒng)的關系型數據庫的功能例如postgresql和oracle等,將json等半結構化數據以文本或者內部編碼的二進制格式的以一個連續(xù)的數據塊的形式存儲關系型數據庫的表中。在進行相應的查詢操作時,調用內部的解析函數對數據塊中的內容進行解析,讀取需要的域中的數據值。接下來調用關系型數據庫中的運算函數對其進行相應的查詢操作。2)nosql數據處理系統(tǒng)內部使用更加靈活的方式對半結構化數據進行二進制的編碼,例如mongodb等。其優(yōu)勢在于能夠實現對原生的半結構化數據進行解析、存儲和查詢操作,具有較強的數據存儲和查詢優(yōu)勢。其在實現的過程中,根據半結構化數據的結構特點,新定義了或者擴展了一些查詢相關的操作。3)列式數據格式對數據進行處理googleprotocolbuffers和apachehive+parquet支持對半結構化數據進行數據的處理和查詢等操作。相較于以上兩類基于行式數據的數據處理系統(tǒng),列式數據處理系統(tǒng)能夠在大部分情況下能夠提供更好的查詢分析性能,但是其內部實現更加的復雜:內部通常使用列簇的形式對數據進行存儲。對于半結構化數據解析和查詢操作的實現有較高的難度。現階段以上3種實現半結構化數據處理系統(tǒng)的方法均存在不同程度的問題。1)擴展已有的關系型數據庫支持半結構化數據的處理相當低效通過分析現階段可支持半結構化數據處理的關系型數據庫,發(fā)現大部分的數據庫都沒有針對半結構化數據的結構和數據特點進行對應的數據編碼和優(yōu)化。其主要是將半結構化數據存儲為文本數據塊的形式,通過其內部實現的一些數據解析函數對文本類型的數據塊進行解析,從而得到每條記錄中需要的信息。這樣在數據庫中直接存儲文本類型的json格式數據浪費了大量的空間。同時在數據查詢的過程中,需要大量的字符串比較和查詢操作,從而極大的限制了數據處理的效率。根據本發(fā)明已有的研究,雖然很多系統(tǒng)支持半結構化數據的運算,但是當數據量增加時,其查詢的運行時間往往太長而導致其難以滿足實時性的要求。關系型數據庫同時還不能很好的支持半結構化數據中一些新的結構特點。例如直接支持對嵌套和重復域的語法定義、擴展sql查詢語法支持半結構化數據結構特點。2)nosql數據處理系統(tǒng)對數據的編碼和查詢效率不夠好本發(fā)明分析并研究了被廣泛使用的nosql數據處理系統(tǒng)mongodb。由于json數據語義的靈活性,mongodb內部定義了冗余且繁瑣的數據編碼格式。研究中發(fā)現,其編碼的效率十分低下,在大部分情況下,其編碼后的數據文件會大于原有的文本格式的數據。數據內部的編碼并沒有有效的減少json文本數據中的冗余信息,相反在查詢過程中還會帶來額外的性能消耗。這就使得其數據處理的性能相對有限,尤其是對于海量數據的處理。同時,這些nosql數據處理系統(tǒng)由于其內部設計的局限性導致其有些操作無法執(zhí)行。例如,mongodb中無法高效的完整實現sql中的join連接運算(雖然在最新版本中加入了相關的類似的運算符,但是依然沒有完全滿足sql中定義的join連接運算且執(zhí)行的效率太低)。3)列式數據格式處理數據在關系型數據庫中,列式數據庫的存儲和查詢性能一般都會優(yōu)于行式數據庫。這是因為其在查詢過程中不需要讀取并處理記錄中和當前查詢無關的域的數據。但是其內部原理復雜、功能實現相對困難。類似的,在支持對半結構化數據處理的系統(tǒng)中,使用列式數據進行存儲和查詢的系統(tǒng)內部也更加復雜。大部分使用行式數據的管理系統(tǒng)中對json內部格式沒有語法的限制,既其數據的內容不需要預先的定義、在使用過程中數據的結構可以不斷的衍變。但是對于列式的數據管理系統(tǒng)而言,需要預先給出列式數據的定義(schema)且在使用過程中無法動態(tài)變化數據的結構。這就極大的限制了半結構化數據的靈活性。此外,現階段也沒有很多的基于列式數據的半結構化數據處理系統(tǒng)可供用戶選擇??晒┯脩羰褂玫牧惺较到y(tǒng)現階段只有基于java實現的apachehive+parquet。由于java編程語言的限制,其查詢的效率還有進一步優(yōu)化的空間。而其運行的平臺需要apachehadoop和hdfs的支持,所以系統(tǒng)初始化和運行的代價都很高。本發(fā)明在進行對半結構化數據進行處理等相關研究時,發(fā)現現有的三種可行性方案均因對半結構化數據處理時對數據結構和實現的局限性導致的。首先,半結構化數據中內部的結構特點導致對其的數據處理不能通過擴展關系型數據庫得到。兩者對于數據格式有不同的假設,所以在使用關系型數據庫處理半結構化數據時會產生更高的代價以至于難以承受。所以本發(fā)明重新設計并實現了面向于半結構化數據數據處理系統(tǒng),使得其能滿足對復雜結構的半結構化數據的處理。其次,考慮到半結構化數據定義的靈活及使用過程中可能會出現結構變化等特點,現階段大部分nosql數據管理系統(tǒng)直接使用類本文結構的數據對其進行存儲。這就導致了其存儲效率太低且查詢時的取值過程代價很高。在本發(fā)明的設計中,從數據中提取的結構存儲在schema語法定義中,在數據中僅保留最少的結構信息。這樣就簡化了數據中重復的結構信息,同時也使得針對數據內容的一些查詢優(yōu)化成為可能。最后,現階段基于java實現的列式半結構化存儲需要很多基礎模塊的支持,例如文件存儲系統(tǒng)、調度系統(tǒng)等。這些都會導致其對系統(tǒng)的功能和使用有一些額外的限制且會導致其執(zhí)行的效率不高。本發(fā)明基于c/c++實現的本數據處理系統(tǒng)(steed)完全獨立開發(fā),這就使得系統(tǒng)從成整體進行優(yōu)化成為可能;也不會有諸如需要預先對數據的格式進行定義且無法改變等由于平臺而產生的限制。技術實現要素:針對現有技術的不足,本發(fā)明提出一種利用簡單路徑特征優(yōu)化樹狀結構數據的方法及系統(tǒng)。本發(fā)明提供一種利用簡單路徑特征優(yōu)化的樹狀結構數據處理方法,包括:步驟1,設置簡單路徑,其中所述簡單路徑為在樹狀結構數據定義的語法樹中,從根節(jié)點到葉子節(jié)點最多只存在一個多值的域的路徑;步驟2,通過存儲所述簡單路徑中葉子節(jié)點的相關結構信息,從樹狀結構數據定義的語法樹中獲取完整的路徑結構信息;步驟3,在使用列式結構數據進行查詢的過程中,使用簡單路徑對列式結構數據到行式結構數據的組裝過程進行優(yōu)化:簡化行式結構數據中的嵌套關系,僅通過葉子節(jié)點表示從根節(jié)點到葉子節(jié)點的路徑而忽略路徑中所有的非葉子節(jié)點。利用半結構化數據定義中葉子節(jié)點的相關信息從語法樹中獲得整個路徑的結構信息。對列式結構樹狀數據組裝為行式結構數據之前,對待組裝的每一條列式結構的路徑按照葉子節(jié)點的id進行相應的排序,之后,依次按照順序從每個列式數據讀取器中讀取中每條記錄所有的列數據項,依次將讀出的數值與相關的結構信息寫入到組裝的結果中。對于語法樹中的非簡單路徑,依然按照樹狀結構數據典型的使用多層嵌套結構表示其結構和數據的方法進行存儲。還包括:1)當語法樹中從根節(jié)點到葉子節(jié)點的路徑上沒有重復節(jié)點的域:僅需要存儲葉子節(jié)點的id與相應域的數值;2)當語法樹中從根節(jié)點到葉子節(jié)點的路徑上只有一個重復節(jié)點的域:按照以下兩種結構進行存儲:a)將每個重復域的數值都作為一個獨立的值存儲在扁平的行式結構數據中,所以,數據中會有多項有相同id的值,其個數決定于重復域中其值的個數;b)將重復的域作為一個整體存儲在扁平的行式結構數據中,其中數據中僅有一個重復域的id表示其在數據中多次出現的值,且所述重復域是由一個數組形式的結構表示多個數值;3)語法樹從根節(jié)點到葉子節(jié)點的路徑上有多個重復的節(jié)點:使用默認的樹狀數據存儲結構,其中在扁平結構的數據中存儲的id為路徑上嵌套層次為1的id,其對應的偏移量指向存儲完整嵌套結構的位置。本發(fā)明還提出一種利用簡單路徑特征優(yōu)化的樹狀結構數據處理系統(tǒng),包括:簡單路徑模塊,用于設置簡單路徑,其中所述簡單路徑為在樹狀結構數據定義的語法樹中,從根節(jié)點到葉子節(jié)點最多只存在一個多值的域的路徑;獲取數據模塊,用于通過存儲所述簡單路徑中葉子節(jié)點的相關結構信息,從樹狀結構數據定義的語法樹中獲取完整的路徑結構信息;組裝模塊,用于在使用列式結構數據進行查詢的過程中,使用簡單路徑對列式結構數據到行式結構數據的組裝過程進行優(yōu)化:簡化行式結構數據中的嵌套關系,僅通過葉子節(jié)點表示從根節(jié)點到葉子節(jié)點的路徑而忽略路徑中所有的非葉子節(jié)點。利用半結構化數據定義中葉子節(jié)點的相關信息從語法樹中獲得整個路徑的結構信息。對列式結構樹狀數據組裝為行式結構數據之前,對待組裝的每一條列式結構的路徑按照葉子節(jié)點的id進行相應的排序,之后,依次按照順序從每個列式數據讀取器中讀取中每條記錄所有的列數據項,依次將讀出的數值與相關的結構信息寫入到組裝的結果中。對于語法樹中的非簡單路徑,依然按照樹狀結構數據典型的使用多層嵌套結構表示其結構和數據的方法進行存儲。還包括:1)當語法樹中從根節(jié)點到葉子節(jié)點的路徑上沒有重復節(jié)點的域:僅需要存儲葉子節(jié)點的id與相應域的數值;2)當語法樹中從根節(jié)點到葉子節(jié)點的路徑上只有一個重復節(jié)點的域:按照以下兩種結構進行存儲:a)將每個重復域的數值都作為一個獨立的值存儲在扁平的行式結構數據中,所以,數據中會有多項有相同id的值,其個數決定于重復域中其值的個數;b)將重復的域作為一個整體存儲在扁平的行式結構數據中,其中數據中僅有一個重復域的id表示其在數據中多次出現的值,且所述重復域是由一個數組形式的結構表示多個數值;3)語法樹從根節(jié)點到葉子節(jié)點的路徑上有多個重復的節(jié)點:使用默認的樹狀數據存儲結構,其中在扁平結構的數據中存儲的id為路徑上嵌套層次為1的id,其對應的偏移量指向存儲完整嵌套結構的位置。由以上方案可知,本發(fā)明的優(yōu)點在于:1,半結構化數據的行式存儲結構;實現對半結構化數據的行式二進制存儲,使其能夠完整的表達半結構化數據的語義并適應其數據定義變化的特點。此外,要求其結構簡單、易于表達,具有較高的存儲效率;2,半結構化數據的列式存儲結構;實現對半結構化數據的列式二進制存儲,使其能夠使用列式存儲完整表達半結構化數據的結構。要求其能夠表達半結構化數據復雜的結構特點并高效的存儲數據的內容;3,半結構化數據行式和列式兩種格式的相互轉化實現;使用解析和組裝算法實現二進制行式和列式數據相互轉化;4,半結構化數據定義的語法樹實現;使用樹形結構存儲數據中結構的定義信息;5,對半結構化數據進行查詢操作;使用行式及列式數據對其進行類sql的查詢操作;6,基于半結構化數據的特點,擴展sql的查詢語法;由于半結構化數據中存在多值域,定義“any”、“all”和路徑表達式解決查詢過程中的數據歧義性的問題;7,基于半結構化數據中簡單路徑的優(yōu)化;簡單路徑是指從根節(jié)點到葉子節(jié)點上最多只存在一個多值域。本發(fā)明發(fā)現常見的半結構化數據中存在大量這樣的結構,提出并實現了針對這樣結構的存儲和查詢優(yōu)化,極大的提高了查詢的效率。如附圖4所示,本發(fā)明使用不同大小的數據集進行了數據已經加載到內存中(hotcached)和數據還沒有加載到內存中(coldcached)的查詢分析實驗。實驗中,本發(fā)明使用不同的sql查詢語句以得到相應的運算操作的性能對比,包括project映射,filter過濾,group分組,sort排序和join連接操作。根據圖4所示的查詢性能,在coldcached數據沒有加載到內存的實驗中,steed相對于hive+parquet有4.1到17.8倍的性能加速比,相對于mongodb有55.9到105.2倍的加速比,相對于postgresql有33.8到1294倍的加速比;而在hotcached的實驗中,steed對mongodb有19.5到59.3倍的加速比,對hive+parquet有19.5到59.3倍的加速比,對postgresql有16.9到392倍的加速比。附錄中詳細列出了本發(fā)明的各個查詢操作的查詢語句。附圖說明圖1微博api定義的json數據格式分析;圖2apachehadoop通信協(xié)議的相關分析;圖3是steed的組成模塊圖;圖4是steed的查詢性能對比圖;圖5是protocolbuffers建立語法樹的過程圖;圖6是行式數據復合類型結構示意圖;圖7是列式數據存儲結構示意圖;圖8是列式數據優(yōu)化存儲結構示意圖;圖9是steed各查詢操作示意圖;圖10是分組操作運算過程中存儲結構示意圖;圖11是經過優(yōu)化的行式存儲結構示意圖;圖12是可供選擇的行式存儲結構的優(yōu)化方案示意圖。具體實施方式鑒于以上現有技術的不足,本發(fā)明重新設計并實現了一個半結構化數據處理系統(tǒng)steed。以下介紹了steed系統(tǒng)的整體架構并簡要介紹每一個模塊的功能需求,之后分析這幾個模塊間的接口定義,同時簡要說明steed內部是如何處理和存儲數據。如圖3所示,steed主要由三個模塊構成:(1)數據解析模塊:讀取文本數據,并將其解析為行式或者列式的二進制格式數據,存儲在數據存儲模塊中。在數據解析的過程中,動態(tài)生成語法樹,存儲半結構化數據的定義。對json格式的數據進行解析時,由于其沒有定義相應的數據格式(語法樹,schematree),所以本發(fā)明只能在解析數據的過程中動態(tài)生成數據格式的定義;而對protocolbuffers格式的數據,文本格式的數據和數據相關的定義會在數據解析前一同被提供,所以本發(fā)明在解析文本格式的數據前可以根據其定義建立語法樹。根據語法樹中域的定義,本發(fā)明將文本結構的數據轉化為行式及列式的二進制格式數據。(2)數據存儲模塊:存儲了經過數據解析模塊生成的行式及列式二進制文件。其在內部可以實現對這兩種格式數據的相互轉換,以及將其直接輸出為文本格式的json數據。在steed系統(tǒng)中,本發(fā)明還根據行式和列式數據存儲的特點對其存儲結構進行了一定的優(yōu)化,使之能夠有較高的存儲和查詢效率。(3)查詢分析模塊:基于行式及列式格式的數據,對半結構化數據進行查詢操作,包括projector映射,filter過濾,group分組,sort排序和join連接等。當steed需要執(zhí)行一次查詢時,先由queryparser查詢解析器根據查詢語句中的內容生成此次查詢所需建立的操作樹(operatortree),樹中的每一個節(jié)點都是一個sql操作。數據在操作樹中按照從葉子到根節(jié)點的順序完成各個部分的運算直至到達根節(jié)點完成此次查詢操作。本發(fā)明還實現了一些操作的多線程版本,支持projector映射,filter過濾和group分組等操作。steed系統(tǒng)一共分為三個模塊,接下來本發(fā)明將逐一介紹每個模塊的實現細節(jié)和過程。第1部分數據解析模塊這一部分詳細介紹了steed的數據解析模塊的實現細節(jié)和內部的關鍵算法,同時根據半結構化數據的結構特點,說明了steed是如何分別針對json和protocolbuffers解析并建立語法樹的過程。1.1數據解析模塊結構概述數據解析模塊主要由以下三部分構成:(1)datatype數據類型:用于描述和定義json和protocolbuffers文本數據中域的二進制數據類型。steed系統(tǒng)中定義了一些基本的數據類型,例如int,double,string等。對于json格式的數據,只需要將文本數據的值映射到系統(tǒng)內部的數據類型即可;而對于protocolbuffers而言,使用其schema定義的數據復合數據類型對steed默認的數據類型進行相應的轉換,以供稍后建立語法樹的過程使用。(2)schematree數據語法樹:建立半結構化數據的定義,既語法樹。對于protocolbuffers的文本數據,在解析數據前首先根據其schema定義文件中對schema定義動態(tài)生成語法樹。在數據解析過程中,定義的語法樹的內容和結構保持不變。json格式的數據則需要本發(fā)明在數據解析的過程中根據其數據中的格式和內容動態(tài)生成此語法樹的定義。本發(fā)明假設每個域中數值的類型都保持不變,同時數組中的每個元素的值的類型都是相同的。steed存儲了每個數據集對應的語法樹定義。在查詢分析模塊中,steed將按照語法樹中數據的定義對數據集進行相應的查詢操作。(3)parser:用于將文本格式的半結構化數據拆分成為鍵值對(keyvaluepairs)的形式,并稍后解析成steed內部定義的行式或者列式的存儲結構。對于protocolbuffers數據,在解析的過程只需要按照語法樹的定義對數據進行格式的轉換;而對于json格式的數據,本發(fā)明在解析的過程中還需要分析數據中是否出現新定義的域,進而對現有的語法樹進行修改。1.2datatype類型1.2.1steed支持的基本數據類型steed系統(tǒng)內部定義了一些二進制格式的數據,用于行式和列式格式數據的存儲和運算:1)整形數:typeint(8/16/32/64)分別表示8/16/32/64位的整形數;2)浮點數:type(float/double)分別表示float和double類型的浮點數;3)字符串:typestring表示的字符串;4)時間戳:typetimestamp表示時間戳,內部用typeint64具體實現。以上的這些數據類型均可支持對其值的判空,本文和二進制數據的相互轉化,比較操作等。1.2.2json數據類型的轉化json定義了其數據中每個域中數據可能的類型。本發(fā)明將其定義的每個數據類型映射成steed的對應的內部數據類型,如下表所示:對于基本的數據類型,直接將json定義的類型映射成為steed內部的基本數據類型;而對于json中object和array這些嵌套的復雜數據類型,steed內部也定義了其對應的行列存儲的方式,具體的存儲方式請見下一章數據存儲模塊。1.2.3protocolbuffers數據類型的轉化與json相似,protocolbuffers也定義一些內部基本的數據類型。在steed的內部實現中,本發(fā)明直接將這些基本的數據類型轉化為c++中的類型(c++type),并將其值存儲在解析后的結果中。參見https://developers.google.com/protocol-buffers/docs/proto3#scalar。此外,protocolbuffers的schema中還可以定義復合的數據類型message。使用復合數據類型,本發(fā)明可以定義多層嵌套的數據格式定義。同時,在復合類型的定義中,本發(fā)明可以選擇域的賦值屬性,既required一定會出現的域,optional可能會出現的域和repeated會重復出現的域。1.3語法樹(schematree)在這一小節(jié)中,本發(fā)明將介紹steed是如何使用語法樹(schematree)描述半結構化數據的。同時還會介紹在解析過程中是如何針對json和protocolbuffers的數據以及結構特點建立語法的。1.3.1語法樹的定義半結構化數據存在以下一些結構特點:1)數據中存在大量的嵌套結構:每個域的定義是有深度的,和傳統(tǒng)的關系型扁平的數據相比更加的復雜;2)數據中的很多多值域:在一條記錄中,可能會有很多個值對其中的某個域進行復制。3)數據中存在大量的稀疏域:大量的域在大部分的數據中并沒有被賦值,而使用傳統(tǒng)的關系型數據庫以表的方式對其進行處理會使得存儲和查詢十分的低效。為了能夠高效的描述半結構化數據中每個域的以上特點,同時提高行式和列式的存儲以及查詢效率,本發(fā)明按照如下的定義了填充半結構化數據中語法樹的每一個節(jié)點:節(jié)點中不但描述了節(jié)點本身的相關信息:數據類型,嵌套層次和域中可能被賦值的個數等;還通過schemanode語法節(jié)點id將節(jié)點相互的關聯,形成樹型結構。接下來本發(fā)明將分別介紹如何在解析過程中為json和protocolbuffers分別建立語法樹。1.3.1json語法樹的建立由于json并沒有數據相關的定義,所以本發(fā)明只能在解析數據的過程中通過數據動態(tài)的建立語法樹。在這里,本發(fā)明假設每個域的值的類型是不會改變的且數組中的成員類型都是一致的。在建立語法樹的過程中,本發(fā)明只需要根據數據中值的類型確定其值的類型。另一方面。由于json數據中的每個域在記錄中是否出現都是不確定的,所以本發(fā)明將值為array的json的域定義為repeated重復出現的,其余節(jié)點均定義為optional不一定會出現。在解析過程中,steed需要先根據parent父親節(jié)點id和fieldname對應的域名通過符號表查找有無相關的結構定義。如果沒有這個節(jié)點的定義,則向schematree語法樹中添加相關的節(jié)點;否則則對這個節(jié)點的值進行解析,詳細的解析過程請見下一小節(jié)。1.3.2protocolbuffers語法樹的建立,如圖5所示:如下例所示,protocolbuffers在proto文件中會定義message作為新的數據類型。其中包含的每個域既可以是基本的數據類型,也可以是其他的復合類型的數據。本發(fā)明在建樹的過程中,首先解析proto文件,擴展新的數據類型;之后再按照用戶指定的根節(jié)點(root)將這些數據類型的定義逐一擴展并組裝成為數據結構的語法樹(schematree)。之后本發(fā)明就可以按照語法樹的定義逐一對每一條文本數據進行解析。1.4數據解析在這一小節(jié)中,本發(fā)明將介紹steed的數據解析算法。這里本發(fā)明忽略了系統(tǒng)中許多底層基礎類的實現,僅列出了和文本格式數據解析相關的算法。由于半結構化數據分別定義了兩種復合的數據結構,既對象(object)和數組(array),所以在解析的過程中,本發(fā)明對這兩種不同的復合結構使用不同的方法對其分別進行解析。另一方面,對于行式和列式二進制數據的輸出,json和protocolbuffers在本發(fā)明實現的過程中是一致的,所以接下來本發(fā)明首先分別介紹在json和protocolbuffers的解析算法,再說明稍后是如何將其數據輸出為二進制行式和列式的數據。1.4.1json數據解析過程算法如下的算法所示,本發(fā)明這里對原子數據類型和復合數據類型采用不同的策略進行解析:對于原子類型的數據,本發(fā)明直接根據其文本格式的值轉化為二進制格式的數據進行存儲或輸出;對于復合結構的數據,本發(fā)明需要分析并解析其結構直至所有的孩子域都是原子數據類型。之后再按照其行式或者列式的存儲結構將其寫入到存儲文件中。對json文本格式的數據解析過程中,本發(fā)明需要對每一個域進行比對,判斷其是否是新增的節(jié)點,進而修改既有的語法樹。對于半結構化數據中的嵌套結構(上文本框左部分),首先將同層的域拆分成為“鍵值對”的形式,之后再按照每個鍵值對分別進行分析。之后分析每個鍵的定義是否曾經出現過,若沒有出現則更新相應的schematree,同時在schematree中記錄對應域的值。之后按照schematree中每個節(jié)點記錄的值遞歸進行解析:如果是復合的數據類型,則調用相應的復合結構解析函數繼續(xù)解析;如果是簡單類型的值,則直接將其輸出到最后的結果中去。而對于多值域的數組(上文本框右部分),由于其表示同一個域的多個重復出現的值,所以本發(fā)明僅需要依次調用相應的解析函數對其內容進行解析而不用分析其對schematree的修改。1.4.2protocolbuffers數據解析過程算法對于protocolbuffers格式的數據而言,文本格式數據的解析過程相對于protocolbuffers更加簡單:由于其在數據解析之前已經定義了數據的格式,所以本發(fā)明在解析的過程中不需要檢查和修改語法樹,僅需要對記錄中每個域的值分別進行解析即可。具體的解析方法和json類似:復合類型調用相應的解析函數進行解析;簡單類型則直接將其值輸出到結果中。1.4.3行式和列式數據的輸出算法在解析的過程中,steed可以將數據解析成為行式或者列式的二進制格式。這里本發(fā)明將介紹其輸出為行式或列式格式數據的具體過程:(1)行式復合類型數據輸出算法:如以上算法所示,對于object和array的復合數據類型,行式結構的數據分別使用其行式結構的對象對每一個域的值進行添加直至整條記錄完成了解析。(2)列式復合類型數據輸出算法:相對于行式結構的數據文件輸出,列式結構數據輸出的過程中僅需要將其葉子節(jié)點上具體的值及其結構信息直接輸出到文件中。所以在解析的過程中,本發(fā)明不需要保留語義上的的object和array的結構,僅記錄其結構相關信息并輸出到列式存儲的文件中。這樣就會使得輸出二進制格式的過程相對簡單和高效。第2部分數據存儲模塊在數據解析模塊完成數據行式或者列式的解析后,數據存儲模塊對解析的結果進行存儲和一定的結構轉換,如行式和列式格式的相互轉換,將二進制格式的數據直接以文本格式進行輸出等。在這一章中,本發(fā)明首先介紹和行式和列式二進制數據的底層存儲結構。之后,基于googledremel的組裝算法,本發(fā)明還將說明steed是如何實現列式結構的數據轉化為行式結構數據的組裝算法。2.1行式存儲結構概述在前一章解析過程的描述中,本發(fā)明使用原子類型的二進制格式對其數據進行存儲;而另兩種復合結構object對象和array數組,本發(fā)明則按照如圖6的方法格式進行存儲:行式和列式的存儲結構比較類似,主要由以下的幾部分組成:(1)headerinformation結構頭信息:記錄這個存儲結構的相關信息,如存儲結構的大小,其中包含的元素個數等。(2)(id)offsetarrayid和偏移量數組:對于object對象而言,本發(fā)明需要標記其中每個域的id用于表示其值的存在;而對于array數組,其中的每個值都是相同的域的賦值,所以其僅保留了每個值的offset偏移量信息。(3)valuearray數值的數組:行式的存儲結構都將values重復出現的數值存儲為數組的形式進行存儲,其中值的類型既可以是原子類型的數據,也可以是復合類型的數據。在object對象中,由于表示的是不同域的賦值,所以每個值的類型可以不相同;但在array數組中,表示的是相同域的多個賦值,所以這里本發(fā)明默認每個值的類型都是相同的。根據之前每個值的offset偏移量信息,本發(fā)明可以對任意的域的值進行隨機訪問。2.2列式存儲結構概述列式存儲結構相對于行式結構相對復雜,本發(fā)明定義了如下的相關概念用于在列式結構上表示并存儲其結構信息:(1)repetitionlevel:repeatedvaluerepeatatwhichfieldinthefield’spath.數據中的重復是在哪一個層次上進行的重復。(2)definitionlevel:numberoffieldinthepathcouldbeundefinedbutpresent.數據中可以省略的域(optional和repeated)有幾層是出現的。關于列式結構的數據如何使用這些相關的信息進行列式到行式數據轉換的過程詳解下一小節(jié),這里本發(fā)明僅介紹其在行式結構數據中的存儲結構。cab(columnalignblock)是本發(fā)明列式存儲的基本單元。在解析過程中,每個值(value)都會產生一條columnitem(列數據項)存儲在cab中。因為半結構化數據中會有很多重復的域,每個重復的域可能會導致一條記錄中會有多條columnitem插入到cab中。本發(fā)明為了提高存儲和查詢的效率,對cab使用recordid對齊的方式進行存儲,每個cab都存儲相同多的record記錄而不考慮具體的columnitem的條數。圖7中列出了cab的具體的結構圖。主要由以下四部分構成:(1)header頭信息:用于描述cab的相關信息,包括其大小和存儲的記錄條數等。(2)repetitionarray數組:用于記錄每條columnitem的repetition值。因為repetition的最大值為每個域的最大深度,所以這里本發(fā)明使用若干bit代替整數來存儲其值。通過對數據內容的分析,本發(fā)明總結了以下幾種template來對其可能出現的模式進行總結和優(yōu)化,如圖8所示。a)nonerepeated非重復的域:嵌套層次中沒有可以重復的域,記錄中這個域最多只有一個值,既沒有重復賦值的情況。steed在解析的過程中如果某些域沒有值時會插入null使得每條記錄能夠自然對齊。這樣,每條記錄有且只有一條columnitem在對應的列式數據文件中。因此,本發(fā)明在存儲結構中省略了這個數組。b)singlerepeated只會在某個嵌套層次進行重復:嵌套層次中有且僅有一個可以重復的層次。本發(fā)明僅需要標記每條記錄的第一條columnitem(recordboundary)。所以本發(fā)明僅需要1bit去標記每條記錄的第一條columnitem或者其唯一重復的嵌套層次。c)multirepeated會在多個嵌套層次進行重復:如果從根到葉子節(jié)點中存在多個可以重復的域,本發(fā)明就需要多個比特指出其重復的域。在對數據進行了具體的分析后,本發(fā)明發(fā)現絕大部分的域都是最多只會在一層上重復。所以通過使用這3個template模板進行存儲,本發(fā)明的列式存儲結構提高了存儲和操作的效率。(3)valuearea數值區(qū)域:這一部分記錄了全部columnitem的值。對于變長和定長的兩種數據格式,本發(fā)明使用了兩種不同的存儲策略:a)定長的數據類型:每個數據的長度一樣,所以本發(fā)明在header中記錄了每個值所占用的空間,每次只需要移動固定的長度即可讀取下一個數值;不需要額外的offset數組。b)變長的數據類型:每個數據的長度不一樣,所以本發(fā)明需要在offset數組中記錄每個值的存儲位置;對于值的內容大量重復的域(例如用戶語言等),我們僅存儲一個具體的變長值,通過在不同的columnitem中復用該具體值的offset提高其存儲的效率。2.3行式和列式格式轉換算法在這一部分中本發(fā)明將介紹在存儲模塊行式和列式文件相互轉化的算法。對于行式數據文件而言,每一個半結構化數據集在解析完成之后都會生成一個行式數據文件存儲所有記錄中的全部域值和相關的結構信息。另一方面,對于列式數據文件而言,每個文本數據集會產生若干個列式存儲文件。每個域都會產生一個列式存儲文件存儲全部記錄的這個域的所有的值。這樣在運行過程中,存儲模塊就需要實現存儲數據的行列格式轉換操作。同時,也需要實現滿足直接將數據輸出為json文本格式的需求。2.3.1行式到列式的數據解析行式結構數據到列式結構數據的轉換過程與文本結構數據解析的過程相似,這里不再贅述。由于在解析過程中不需要對文本數據的結構進行字符的匹配,而使用已經解析好的行式的object或array的存儲結構;同時不需要進行文本格式數據到二進制的格式轉換,行式到列式結構轉換的效率要明顯優(yōu)于字符解析的效率。2.3.2列式到行式的數據組裝將列式數據文件按照一定的規(guī)則組裝成行式格式的文件就可以完成列式結構的數據轉化為行式結構的數據。基于googledremel的組裝算法,這里本發(fā)明在steed內部使用類似的算法完成對列式文件的組裝。具體算法如下所示:在組裝過程中,steed按照有限狀態(tài)自動機的順序和columnitem中的repetitionvalue從columnreader(列式數據讀取器)中讀取columnitem,之后再根據definitionvalue判斷并輸出相應的嵌套層次信息。當讀取的最后一個columnreader讀完本條記錄的最后一個columnitem時,既遍歷完成所有的columnreader,assembler組裝器就完成了一條記錄的組裝。assembler組裝器會不斷的運行,直到所有的記錄都完成組裝,此時所有的columnreader都應讀取到文件結尾eof。在以下的算法中,除了具體的組裝過程assemblerecd,move和return兩個函數分別使用definitionvalue判斷數據的嵌套層次的結構信息。在如下的偽代碼中,本發(fā)明需要從根節(jié)點開始使用深度優(yōu)先算法遍歷schematree,之后按照其葉子節(jié)點出現的順序對列式文件進行排序,按照排序后的順序依次讀取各個列式文件中columnitem的內容。根據讀取的的columnitem的內容,本發(fā)明可以控制數據嵌套的層次結構信息:首先輸出當前列中表示嵌套結構的相關信息,之后將值輸出到待組裝的行式結構中,然后再判斷要跳轉并讀取的下一個列文件,最后從下一列中預讀一條columnitem判斷需要返回的嵌套層次的層次并輸出相關的結構信息。當所有的列式文件都至少完成一次的讀取后,本發(fā)明就完成了一條記錄的組裝。重復以上的過程,直到所有的列式文件都讀完,本發(fā)明就完成了對整個數據集合的組裝。第3部分查詢分析模塊基于行式和列式結構的數據,steed可以進行類似于sql的查詢分析。但是相比于傳統(tǒng)的表結構的關系型數據,半結構化數據的由于其存在嵌套和多值域而導致其在查詢時會存在一定的歧義。為此本發(fā)明擴展了查詢的語法,使其在一定程度上能夠消除數據歧義。本發(fā)明還實現了sql中一些基本的運算,如projector映射,filter過濾,groupby分組和sort排序等。在本章中,本發(fā)明首先介紹針對半結構化數據的擴展后的語義。之后,針對系統(tǒng)中已經實現的多種半結構化數據的運算,本發(fā)明會依次介紹其實現的具體算法。3.1sql針對半結構化數據的語義擴展傳統(tǒng)的關系型數據使用表結構存儲扁平的數據:所有的值都在同一層,不存在嵌套子結構;每個域有且只有一個數值能給其賦值;在設計表時會拆分表,使其不會存在大量的稀疏的域。而對于半結構化數據而言,其以上的這些特點都不適用。而為了支持半結構化數據的操作,本發(fā)明新定義了如下的一些運算符:(1)“.”:用于間隔域的路徑表達式中的嵌套層次。(2)“any”:表示重復的域中任意的一個數值;(3)“all”:表示重復的域中所有的數值。輸出的結果本發(fā)明有多重的選項:(1)json格式的數據:(2)忽略嵌套結構的類json數據;3.2steed支持的運算類型如圖9所示,steed支持基于行式和列式數據的多種類型的運算。在各個operator之間,數據使用pull的方式依次流動,直到在頂層的outputoperator完成從二進制的到文本格式數據的轉換。接下來,本發(fā)明會依次介紹其內部的各種實現細節(jié)。3.2.1rowfromoperator(行式數據讀取運算)steed從行式的數據文件中讀取一整條行式結構的數據。由于每一條記錄在行式數據文件中是按照記錄為單位進行的存儲,每條記錄都是以rowobject行式對象為存儲的格式進行存儲的。所以在讀取記錄時,本發(fā)明每次都從行式二進制數據文件中讀取一個rowobject行式對象依次進行讀取,直到到達文件結尾eof。3.2.2schemafilter(whereorhavingclause)operator(基于schema定義的where和having字句中的過濾運算)在這個operator中,本發(fā)明對行式數據進行filter過濾操作。這個操作可以用于steed在讀取行式數據之后,對其進行where字句中的條件進行判斷;而在groupby字句中生成新的行式的數據之后,也可以使用其對aggregation聚集的結果進行過濾操作。在具體的filter過濾操作過程中,本發(fā)明定義了rowcondition(行式條件類)用于判斷記錄中相關的域是否滿足每一個謂詞(predicate)的條件。具體的判斷過程如下所示:本發(fā)明首先對where字句進行解析,將每一個謂詞實例化為可以進行數據比較的對象:可以從行式數據結構中讀取數據;之后對讀取的值進行比較,判斷每個謂詞(predicate)的真值,決定其是否通過這個operator中的條件運算。3.2.3projectoperator(映射運算)在行式結構的數據中本發(fā)明存儲了每條記錄中所有的域,但是大部分的查詢語句僅需要一些域的值即可。這樣在整個的查詢過程中,就會有大量的于查詢無關的域的數據在各operator運算間拷貝了多次。這些額外的內存拷貝會降低本發(fā)明查詢的效率。所以本發(fā)明對行式結構的數據實現了projector運算用于提取和查詢相關的域,這樣在拷貝過程中僅拷貝了查詢相關的域從而提高了查詢的效率。在運算過程中,本發(fā)明使用調用遞歸函數應對半結構化數據中的嵌套結構。在每一個域中,本發(fā)明分別讀取原數據中該域的賦值,對其進行解析之后僅將和查詢相關的域寫入到運算的結果中。這樣就能忽略行式數據中大量的無關的域,提高查詢過程的效率。對于多值域,如果其在葉子節(jié)點重復,steed僅需要直接拷貝這個域的數組中連續(xù)存儲的多個值。如果在非葉子節(jié)點重復,則對以每一個數組中的子結構分別遞歸及解析。需要注意的是,在提取子樹的過程中,本發(fā)明僅保留了被賦值的子樹;既,如果這個子樹中的相關的域沒有被賦值,則在projector的結果中這個子樹將不會被保留。3.2.4assembleoperator(列式到行式數據的組裝運算)在這個operator運算過程中,steed完成了將查詢相關的域從行式結構數據轉化為列式結構數據的組裝過程。具體的組裝算法請見之前。steed首先通過queryparser查詢語句解析器解析需要執(zhí)行的sql語句得到所有和查詢相關的域,使用其建立一個有限狀態(tài)自動機(fsm)以控制在組裝過程中行式結構數據的讀取順序。之后按照先前的組裝算法完成從列式到行數數據的格式轉換,這里不再贅述。3.2.5columnfilteroperator(提供過濾操作的列式到行式數據的組裝運算)相比于assembleroperator(列式到行式數據的組裝運算),columnfilteroperator(提供過濾操作的列式到行式數據的組裝運算)不但實現了列式結構到行式結構的組裝,還能在組裝過程中對每個記錄進行filter過濾操作。由于在查詢過程中,where子句會過濾掉一些不滿足條件的記錄,所以如果本發(fā)明在組裝過程中不組裝這些無效的記錄,會極大的提高查詢效率。所以在查詢過程中,本發(fā)明每次讀取一個cab進行filter過濾操作并設立相應的bitmap位圖記錄其比較的結果,最后根據記錄的結果中再決定是否進行組裝。3.2.6joinoperator(連接運算)steed中使用hashjoin(哈希連接)實現連接操作,現階段僅支持兩個表的連接操作。在執(zhí)行這個操作的過程中,steed根據其中一個數據集記錄中的joinkey具體值計算其對應的哈希值并將整條記錄存儲在哈希表中。稍后遍歷另一個數據集合,查找具有相同hashkey哈希鍵的對應哈希表中的位置(bucket)。之后將這兩個行式結構的數據進行合并,并等待這條記錄被pull(拉)到上一層的operator運算。現階段steed并沒有使用關系型數據庫中查詢優(yōu)化器進行優(yōu)化,故而在查詢過程中建議將較小的數據集作為from子句中第一個出現的數據集,以得到較高的存儲效率。3.2.7groupoperator(分組運算)在查詢操作現階段所支持的內部操作中,group分組是最復雜的操作。本發(fā)明將會介紹在運算過程中一些新定義的類,并對相應的執(zhí)行過程進行分析。和joinoperator連接操作類似,groupoperator分組操作使用hashtable哈希表存儲相應的groupkey分組的鍵值。在運算的過程中,首先由從行式結構的數據中讀取數據,計算其hashkey哈希值并添加到哈希表中。之后再根據需要判斷其有無aggregation聚集運算對hashvalue哈希值中的內容進行運算。其中hashvalue哈希值的數據存儲結構如圖10所示:本發(fā)明首先定義了hashvalueitemcontainer用于存儲每個在哈希表中的每一個存儲單元(bucket),哈希表中具體的value值為指向這些hashvalueitem的地址。每個這樣的對象都有如圖10所示的結構:(1)本發(fā)明首先在中間層保存記錄存儲的具體地址和每個需要計算的aggregation聚集的內容。(2)在blockbuffer對象中,存儲了被保存的記錄的實際內容。需要指出的是,這些記錄除了那些groupedfield基于值進行分組的域,都是沒有被賦值的表示aggregation聚集結果的域。當整個group分組運算完成之后,本發(fā)明再將aggregation聚集的結果輸入到相應的位置,并等待結果被上層的其他operator操作pull拉起。3.2.8orderoperator(排序操作)對于orderby排序操作運算,本發(fā)明需要將所有的記錄存儲到buffer緩存中,之后對其比較排序??紤]到內存空間分配效率的問題,本發(fā)明每次僅向操作系統(tǒng)申請固定大小的內存,這樣可以省去realloc重新分配內存中過程中內存拷貝的代價。同時,為了避免在排序過程中多次拷貝數據的代價,本發(fā)明在比較過程中使用一個數組記錄每條記錄的起始地址并在排序過程中改變指針在數組中的位置。最終達到對這個數組順序訪問時,訪問到的記錄都是滿足排序要求的結果。此外根據排序的條件,本發(fā)明定義了comparer比較器用比較記錄,其按照如下的方式進行運算:(1)這個comparer比較器可以從行式存儲結構中讀取所有域的數值用于比較操作。(2)為了提高比較效率,本發(fā)明如下實現了比較及輸出的過程:a)在每條記錄中保留了8字節(jié)存儲第一個需要比較的域中數據的高8位。對于所有的數值類型而言,這個空間足以存儲其對應的值而不需要復雜的對行式結構的數據進行取值;對于字符串而言,前8位的比較在大多數情況下也能得到確定的比較結果。所以在比較過程中,本發(fā)明先使用緩存的這8字節(jié)進行比較。當數據的類型為字符串且前綴的比較相同時,本發(fā)明才會進行下一步比較。b)使用comparer比較器根據需要排序的域的順序,依次取值并進行排序,直到得到比較的結果。c)具體的比較函數的實現本發(fā)明使用stl::sort函數進行比較。d)在比較過程中沒有對記錄的本身進行數據拷貝,只修改了記錄輸出順序的指針數組,這樣避免了內存的多次拷貝操作。而在被上層operator操作pull拉數據的過程中,本發(fā)明也僅提供了對應的指針,以提高其數據處理的效率。第4部分利用簡單路徑特征優(yōu)化樹狀結構數據的方法及系統(tǒng)在這一部分中,本發(fā)明根據現有多種數據來源的相關數據,總結并歸納出了簡單路徑的概念,并且在steed中利用該特征進行了查詢優(yōu)化4.1簡單路徑的定義在分析了多種不同來源的數據,我們發(fā)現在各數據集的語法樹中,存在著大量的從根到葉子節(jié)點最多只有一個重復域的路徑。本發(fā)明在查詢的過程中可以利用這些數據中的結構特點優(yōu)化查詢過程、提高查詢效率。所以,本發(fā)明對簡單路徑定義如下:在數據集的語法樹中,從根到葉子節(jié)點的路徑上最多只能存在一個域(語法樹中的某個節(jié)點)是多值的,我們稱這樣的路徑為簡單路徑。steed中可以利用簡單路徑對樹狀結構數據進行存儲及查詢過程相關的優(yōu)化。4.2半結構化數據行式存儲的結構如前所述,steed在行式存儲結構中為了準確表達樹狀結構數據中的層次信息使用了相對復雜存儲結構。經過分析,本發(fā)明認為從數據的表達上看,已經不能對其進行進一步的優(yōu)化和改進。但是通過以上簡單路徑的分析可知,本發(fā)明可以通過簡化數據中存儲的結構信息以提高數據在系統(tǒng)內部的表示效率,使得其解析和查詢的效率有進一步的提升。本發(fā)明設想的更好的行式存儲結構如圖11所示:對于簡單路徑的數據,steed可以在數據中僅存儲葉子節(jié)點(域)的相關結構信息來代替原有的嵌套存儲結構來指代相應的路徑。而使用簡單路徑進行優(yōu)化之后,steed可以利用數據中葉子節(jié)點的相關信息從系統(tǒng)中的語法樹(schematree)獲得整個路徑上所有節(jié)點的相關信息。這樣,steed通過簡化數據中存儲的結構信息提高了行式數據的表達效率和查詢的執(zhí)行效率。4.3flattenassemble(扁平行式結構組裝器)steed在數據的組裝過程中,需要花費大量代價來恢復數據的層次結構。如前所述,在大多數的數據集中的域中重復的層次都不超過2層,所以數據中絕大部分的值都可以利用簡單路徑進行相應的優(yōu)化。而steed中對于簡單路徑的域的組裝過程則更加的簡便:使用flattenassembler扁平行式結構組裝器忽略默認二進制數據中的層次關系,既僅使用葉子節(jié)點表示從根節(jié)點到葉子節(jié)點的路徑而忽略路徑中所有的非葉子節(jié)點。這樣,本發(fā)明就實現了將行式結構數據的嵌套層次限制為一層的目的,從而在數據查詢的過程中節(jié)約了數據在內存中的空間消耗并且提高了數據的查詢效率。具體的組裝算法如上所示:在組裝之前,需要對待組裝的每一個列按照葉子節(jié)點的id進行相應的排序。之后,依次按照順序讀取每個columnreader中每條記錄的所有columnitem,依次將讀出的數值和相關的結構信息寫入到組裝的結果中去。這里由于組裝的結果僅保留了一個嵌套的層次,所以在組裝過程中steed只需要將每個域的值追加到當前的對象中,而不需要考慮組裝結果的嵌套關系。4.4扁平行式數據的存儲結構本發(fā)明中,steed在查詢過程使用扁平結構的行式數據進行查詢和存儲等方面的優(yōu)化。對于語法樹中的非簡單路徑,由于steed需要識別數據中不同嵌套層次的多值域,本發(fā)明繼續(xù)使用系統(tǒng)默認的樹狀結構數據的表達方法。而對于簡單路徑,本發(fā)明使用如圖11的結構對其進行存儲或組裝:1)語法樹中從根到葉子節(jié)點的路徑上沒有重復節(jié)點的域:扁平數據存儲結構中僅需要存儲葉子節(jié)點的id和相應域的數值;2)語法樹中從根到葉子節(jié)點的路徑上只有一個重復節(jié)點的域:扁平數據存儲結構中可以按照以下兩種結構進行輸出,詳見圖12:a)將每個重復域的數值都作為一個具體的值存儲在扁平結構中----數據中會有多項有相同id的值,其個數決定于重復域的個數;b)將重復的域作為一個整體存儲在扁平結構中----數據中僅有一個重復域的id表示其具體的值,而這個域是由一個數組形式的結構表示多個數值。3)語法樹從根到葉子節(jié)點的路徑上有多個重復的節(jié)點:扁平數據存儲結構無法表達路徑上多個可重復的域的數值是在哪一層上發(fā)生的重復,本發(fā)明中繼續(xù)使用原有的默認的樹狀數據存儲結構----扁平結構的數據中依然使用葉子節(jié)點的id,但是相應的值為偏移量,指向存儲完整嵌套結構的位置。本發(fā)明提出一種利用簡單路徑特征優(yōu)化樹狀結構數據的系統(tǒng),包括:簡單路徑模塊,用于設置簡單路徑,其中所述簡單路徑為在數據集的語法樹中,從根節(jié)點到葉子節(jié)點,最多只能存在一個多值的域的路徑;獲取數據模塊,用于通過存儲所述簡單路徑中葉子節(jié)點的相關結構信息,獲取原有嵌套存儲結構中的數據;組裝模塊,用于對所述簡單路徑中葉子節(jié)點進行組裝,其中忽略默認二進制數據中的層次關系,僅通過葉子節(jié)點表示從根節(jié)點到葉子節(jié)點的路徑而忽略路徑中所有的非葉子節(jié)點。利用數據集中葉子節(jié)點的相關信息從語法樹中獲得整個簡單路徑上所有節(jié)點的相關信息。在組裝之前,對待組裝的每一個列數據按照葉子節(jié)點的id進行相應的排序,之后,依次按照順序讀取每個columnreader中每條記錄的所有columnitem,依次將讀出的數值與相關的結構信息寫入到組裝的結果中。對于語法樹中的非簡單路徑,識別數據中各嵌套層次的多值域。本發(fā)明系統(tǒng)使用如圖11的結構進行存儲或組裝,具體如下所示:1)當語法樹中從根節(jié)點到葉子節(jié)點的路徑上沒有重復節(jié)點的域:僅需要存儲葉子節(jié)點的id與相應域的數值;2)當語法樹中從根節(jié)點到葉子節(jié)點的路徑上只有一個重復節(jié)點的域:按照以下兩種結構進行輸出:a)將每個重復域的數值都作為一個具體的值存儲在扁平結構中,其中,數據中會有多項有相同id的值,其個數決定于重復域的個數;b)將重復的域作為一個整體存儲在扁平結構中,其中數據中僅有一個重復域的id表示其具體的值,且所述重復域是由一個數組形式的結構表示多個數值;3)語法樹從根節(jié)點到葉子節(jié)點的路徑上有多個重復的節(jié)點:使用默認的樹狀數據存儲結構,其中扁平結構的數據中依然使用葉子節(jié)點的id,id表示為偏移量,指向存儲完整嵌套結構的位置。當前第1頁12當前第1頁12
當前第1頁1 2 
網友詢問留言 已有0條留言
  • 還沒有人留言評論。精彩留言會獲得點贊!
1
大石桥市| 大安市| 德保县| 黑山县| 丘北县| 防城港市| 沾化县| 双桥区| 延长县| 高安市| 离岛区| 辉南县| 博野县| 沙河市| 晋州市| 漯河市| 湘阴县| 高雄县| 桦南县| 中阳县| 林口县| 宁武县| 秦安县| 福安市| 大田县| 青龙| 即墨市| 孟村| 奇台县| 色达县| 当雄县| 山西省| 宝丰县| 江川县| 临邑县| 财经| 巩义市| 星座| 无锡市| 鱼台县| 鹤山市|