本發(fā)明屬于數(shù)據(jù)存儲(chǔ),尤其涉及一種基于基數(shù)樹的大規(guī)模鍵值數(shù)據(jù)的存儲(chǔ)方法。
背景技術(shù):
1、內(nèi)存數(shù)據(jù)庫是很常見的大規(guī)模數(shù)據(jù)管理媒介,諸如oracle/sql-server/mysql,甚至輕量級(jí)的sqlite在底層對(duì)于數(shù)據(jù)存儲(chǔ)及訪問的操作都做了極深刻的優(yōu)化,使時(shí)空復(fù)雜度接近了最優(yōu)的平衡。
2、然而它們都屬于通用數(shù)據(jù)類型的數(shù)據(jù)庫,底層會(huì)采用b(b+/b-)樹、哈希、鏈表、堆、圖形、前綴樹、位圖索引、日志結(jié)構(gòu)、對(duì)象等數(shù)據(jù)結(jié)構(gòu)組織元素。而對(duì)于具有定長比特流(串)特征的主鍵,上述這些組織形式卻無法使檢索等操作效率達(dá)到最優(yōu)。
3、基數(shù)樹是基于單個(gè)位的分叉樹形組織形式,更適合諸如mac地址、各類uuid等定長比特?cái)?shù)據(jù)的存儲(chǔ)和訪問。經(jīng)過優(yōu)化的底層位操作指令,可以使數(shù)據(jù)元素的訪存和遍歷變得極為迅速,以至于成為通用型數(shù)據(jù)庫的有益補(bǔ)充。
4、基數(shù)樹的基本構(gòu)成原理:
5、如圖5所示的基數(shù)樹的基本構(gòu)成,二叉樹的每條邊都表示一個(gè)0/1比特,從根到葉(由頂至底)的一條路徑就能唯一表示一串比特流。以存儲(chǔ)mac地址為例,由于mac地址是固定的48位長,那么一棵深度為48的滿二叉樹從理論上就能表示所有的mac地址。而現(xiàn)實(shí)中受限于實(shí)際存儲(chǔ)介質(zhì)的容量限制,不可能也沒必要存儲(chǔ)全部的mac地址,往往是根據(jù)具體應(yīng)用的實(shí)際需要和規(guī)模,存儲(chǔ)mac地址空間中的一小部分實(shí)例而已。并且會(huì)輔以老化(aging)和緩存(caching)機(jī)制,保持一個(gè)最佳的容量上限,存儲(chǔ)最近一段時(shí)間較為活躍的,或者是靜態(tài)可配置的一部分mac地址實(shí)例。所有葉結(jié)點(diǎn)的后繼(左右子樹)指針可被復(fù)用,以指向同該mac地址相關(guān)聯(lián)的衛(wèi)星數(shù)據(jù)。
6、圖6展示了mac地址(00-60-b3-09-12-11)的基數(shù)樹完整表示。當(dāng)有新的mac地址需要插入時(shí),會(huì)從樹根root開始,沿已有的樹枝路徑,將結(jié)點(diǎn)中表示的二進(jìn)制位,同新插入的mac地址,逐比特一一進(jìn)行比較。當(dāng)發(fā)現(xiàn)有不同的位時(shí)則產(chǎn)生分叉。例如圖7展示了在圖6基礎(chǔ)上,插入新的mac地址(00-60-b3-52-04-18)后的表示形式。
7、以上普通形式的比特存儲(chǔ)方式是較為浪費(fèi)內(nèi)存的,因?yàn)槊恳晃欢夹枰加靡粋€(gè)二叉樹結(jié)點(diǎn),哪怕是多個(gè)不同的mac能夠共享其中的一部分結(jié)點(diǎn),也無濟(jì)于事。如果共享的比特片段較少,即位差異出現(xiàn)的越早,結(jié)點(diǎn)利用率也就越低,則浪費(fèi)的內(nèi)存量也就相應(yīng)的增大。
技術(shù)實(shí)現(xiàn)思路
1、本發(fā)明的目的是提供一種基于基數(shù)樹的大規(guī)模鍵值數(shù)據(jù)的存儲(chǔ)方法,解決了通過引出壓縮的存儲(chǔ)方式,采用位片段的表示方法,實(shí)現(xiàn)優(yōu)化內(nèi)存的使用,提高信息復(fù)用密度的技術(shù)問題。
2、為實(shí)現(xiàn)上述目的,本發(fā)明采用如下技術(shù)方案:
3、一種基于基數(shù)樹的大規(guī)模鍵值數(shù)據(jù)的存儲(chǔ)方法,包括如下步驟:
4、步驟1:設(shè)計(jì)內(nèi)存數(shù)據(jù)庫的整體架構(gòu),定義核心基數(shù)樹模塊的接口和數(shù)據(jù)流,制定內(nèi)存管理策略,制定在并發(fā)環(huán)境下的操作規(guī)則,具體為設(shè)定系統(tǒng)的模塊分層,明確基數(shù)樹作為數(shù)據(jù)存儲(chǔ)和檢索的核心模塊,規(guī)劃數(shù)據(jù)流的流轉(zhuǎn)路徑,并為并發(fā)操作設(shè)定鎖機(jī)制;模塊分層包括數(shù)據(jù)存儲(chǔ)模塊、內(nèi)存管理模塊和數(shù)據(jù)接口模塊;
5、步驟2:數(shù)據(jù)存儲(chǔ)模塊為存儲(chǔ)定長比特流創(chuàng)建一個(gè)空的基數(shù)樹結(jié)構(gòu),具體為初始化基數(shù)樹,創(chuàng)建一個(gè)空的根節(jié)點(diǎn),為后續(xù)數(shù)據(jù)的插入和管理做好準(zhǔn)備;
6、步驟3:數(shù)據(jù)存儲(chǔ)模塊將定長比特流數(shù)據(jù)逐一插入基數(shù)樹中,具體為根據(jù)每一個(gè)比特位進(jìn)行路徑匹配,逐位沿著已有的樹枝路徑插入新數(shù)據(jù),使樹結(jié)構(gòu)能夠反映數(shù)據(jù)的二進(jìn)制特征;
7、步驟4:數(shù)據(jù)存儲(chǔ)模塊和內(nèi)存管理模塊協(xié)作優(yōu)化基數(shù)樹的內(nèi)存使用效率,具體為通過位片段共享技術(shù),將相同的比特流片段合并,減少冗余數(shù)據(jù)的存儲(chǔ);
8、步驟5:數(shù)據(jù)存儲(chǔ)模塊創(chuàng)建數(shù)據(jù)查詢,具體為制定從根節(jié)點(diǎn)開始的遍歷機(jī)制,通過逐層匹配位片段,定位到目標(biāo)數(shù)據(jù)或確認(rèn)數(shù)據(jù)不存在;數(shù)據(jù)接口模塊提供查詢?cè)L問接口;
9、步驟6:數(shù)據(jù)存儲(chǔ)模塊創(chuàng)建刪除數(shù)據(jù),保持樹結(jié)構(gòu)的優(yōu)化,具體為通過檢索定位目標(biāo)數(shù)據(jù)節(jié)點(diǎn),執(zhí)行刪除操作后,對(duì)樹結(jié)構(gòu)進(jìn)行聚合調(diào)整,以去除冗余節(jié)點(diǎn);數(shù)據(jù)接口模塊提供刪除訪問接口;
10、步驟7:數(shù)據(jù)存儲(chǔ)模塊維持基數(shù)樹在數(shù)據(jù)增刪后的優(yōu)化狀態(tài),具體為基于數(shù)據(jù)插入和刪除操作,動(dòng)態(tài)調(diào)整基數(shù)樹結(jié)構(gòu),使基數(shù)樹的深度和寬度始終處于最優(yōu)狀態(tài);內(nèi)存管理模塊負(fù)責(zé)內(nèi)存的重分配;
11、步驟8:數(shù)據(jù)接口模塊為基數(shù)樹操作提供標(biāo)準(zhǔn)化的接口,供系統(tǒng)其他模塊調(diào)用。
12、優(yōu)選的,在執(zhí)行步驟1時(shí),具體包括如下步驟:
13、步驟1-1:確定基數(shù)樹的核心數(shù)據(jù)結(jié)構(gòu)設(shè)計(jì);
14、步驟1-2:設(shè)計(jì)基數(shù)樹的交互接口,包括數(shù)據(jù)插入、刪除、檢索的操作對(duì)應(yīng)的接口;
15、步驟1-3:制定系統(tǒng)的內(nèi)存管理策略,包括老化機(jī)制和緩存機(jī)制;
16、步驟1-4:制定并發(fā)環(huán)境下的操作,設(shè)計(jì)鎖機(jī)制和數(shù)據(jù)一致性保障。
17、優(yōu)選的,在執(zhí)行步驟2時(shí),具體包括如下步驟:
18、步驟2-1:創(chuàng)建基數(shù)樹的根節(jié)點(diǎn);
19、步驟2-2:初始化根節(jié)點(diǎn)的左右子節(jié)點(diǎn)指針為nil;
20、步驟2-3:設(shè)置根節(jié)點(diǎn)的位片段長度為0,用于表示初始狀態(tài)下沒有存儲(chǔ)任何數(shù)據(jù)。
21、優(yōu)選的,在執(zhí)行步驟3時(shí),具體包括如下步驟:
22、步驟3-1:讀取待插入的定長比特流,將其轉(zhuǎn)換為二進(jìn)制比特流;
23、步驟3-2:從根節(jié)點(diǎn)開始,逐位與現(xiàn)有樹節(jié)點(diǎn)中的比特進(jìn)行比較:如果發(fā)現(xiàn)位不同,在該位處創(chuàng)建新枝節(jié)點(diǎn);如果位相同,則繼續(xù)沿當(dāng)前路徑向下比較;
24、步驟3-3:插入新的位片段并更新節(jié)點(diǎn)指針和元數(shù)據(jù)。
25、優(yōu)選的,在執(zhí)行步驟4時(shí),具體包括如下步驟:
26、步驟4-1:檢查路徑中是否有公共位片段;
27、步驟4-2:共享公共位片段,減少冗余存儲(chǔ);
28、步驟4-3:使用位操作處理位片段;
29、步驟4-4:更新壓縮存儲(chǔ)后的位片段長度和元數(shù)據(jù)。
30、優(yōu)選的,在執(zhí)行步驟5時(shí),具體包括如下步驟:
31、步驟5-1:將待檢索的定長比特流轉(zhuǎn)換為二進(jìn)制比特流;
32、步驟5-2:從根節(jié)點(diǎn)開始,逐位與樹中的位片段進(jìn)行匹配;
33、步驟5-3:沿匹配路徑深入到葉節(jié)點(diǎn);
34、步驟5-4:返回匹配成功的葉節(jié)點(diǎn)數(shù)據(jù);
35、步驟5-5:如果匹配失敗,返回?cái)?shù)據(jù)不存在的信息。
36、優(yōu)選的,在執(zhí)行步驟6時(shí),具體包括如下步驟:
37、步驟6-1:與插入數(shù)據(jù)的原理類似,從根節(jié)點(diǎn)開始逐位匹配待刪除的定長比特流;
38、步驟6-2:當(dāng)匹配到對(duì)應(yīng)葉節(jié)點(diǎn)時(shí),刪除該節(jié)點(diǎn)的數(shù)據(jù);
39、步驟6-3:進(jìn)行聚合操作,將兄弟節(jié)點(diǎn)提升為父節(jié)點(diǎn);
40、步驟6-4:如果聚合后新節(jié)點(diǎn)能夠共享位片段,則更新位片段信息。
41、優(yōu)選的,在執(zhí)行步驟7時(shí),具體包括如下步驟:
42、步驟7-1:在插入新數(shù)據(jù)時(shí),檢測(cè)是否需要進(jìn)行裂解操作;裂解操作包括將公共位片段移至上層節(jié)點(diǎn);
43、步驟7-2:在刪除數(shù)據(jù)時(shí),檢測(cè)是否可以進(jìn)行聚合操作;聚合操作包括將父節(jié)點(diǎn)與子節(jié)點(diǎn)合并;
44、步驟7-3:持續(xù)監(jiān)控樹的結(jié)構(gòu),確保動(dòng)態(tài)調(diào)整后的樹保持優(yōu)化性能。
45、優(yōu)選的,在執(zhí)行步驟8時(shí),具體包括如下步驟:
46、步驟8-1:制定crud接口,用于基數(shù)樹的數(shù)據(jù)結(jié)構(gòu)兼容;
47、步驟8-2:制定接口的底層邏輯,包括位片段的操作和節(jié)點(diǎn)管理;
48、步驟8-3:提供并發(fā)訪問控制機(jī)制,確保安全操作;
49、步驟8-4:制定衛(wèi)星數(shù)據(jù)的更新和訪問接口;
50、步驟8-5:編寫測(cè)試用例,驗(yàn)證接口的功能和性能。
51、本發(fā)明所述的一種基于基數(shù)樹的大規(guī)模鍵值數(shù)據(jù)的存儲(chǔ)方法,解決了通過引出壓縮的存儲(chǔ)方式,采用位片段的表示方法,實(shí)現(xiàn)優(yōu)化內(nèi)存的使用,提高信息復(fù)用密度的技術(shù)問題,本發(fā)明基于鍵值為索引的數(shù)據(jù)增刪改查操作,具有普適性,用壓縮形式存儲(chǔ)的基數(shù)樹,可以最大限度減少位片段的數(shù)量,從而在由根到葉的搜索路徑上減少結(jié)點(diǎn)的比較次數(shù)。代碼實(shí)現(xiàn)上可充分利用位運(yùn)算的快速處理,使時(shí)間復(fù)雜度降到最低。本發(fā)明的空間復(fù)雜度也是很低的,用c語言實(shí)現(xiàn)可以把代碼量控制在200行以內(nèi)。采用位域(bit?field)的存儲(chǔ)方式,可以使結(jié)點(diǎn)本身占用的數(shù)據(jù)內(nèi)存也很小,鍵值本身不需要額外的空間來存放,而是以比特流的形式暗含在了由根到葉的樹形路徑中,所需的內(nèi)存小,在基數(shù)樹中的存儲(chǔ)方式是固定的,可預(yù)測(cè)的,從而使訪問時(shí)間也變得可預(yù)測(cè),具有很高的穩(wěn)定性,很容易在從極低資源配置的單片機(jī)系統(tǒng),直到極高性能和容量的大型服務(wù)器池,這樣寬廣的領(lǐng)域中靈活應(yīng)用,并且在任何操作系統(tǒng)間都可以方便的移植。