摘 要:隨著互聯(lián)網(wǎng)、物聯(lián)網(wǎng)的發(fā)展,軟件系統(tǒng)收集和產(chǎn)生了海量的數(shù)據(jù),單個(gè)數(shù)據(jù)庫由于各種限制已經(jīng)無法滿足海量數(shù)據(jù)存儲(chǔ)和訪問的要求,必須將數(shù)據(jù)分散在多個(gè)數(shù)據(jù)庫中,以達(dá)到存儲(chǔ)海量數(shù)據(jù)、平衡負(fù)載、提高系統(tǒng)可用性的目的。如何將單個(gè)數(shù)據(jù)庫中的數(shù)據(jù)劃分到不同的數(shù)據(jù)庫中成為數(shù)據(jù)庫管理員面臨的首要問題。本文提出一種綜合考慮SQL語句、SQL語句執(zhí)行頻率,服務(wù)器性能,數(shù)據(jù)量等多因素的數(shù)據(jù)庫劃分方法,滿足數(shù)據(jù)存儲(chǔ)和訪問要求,從而為數(shù)據(jù)庫設(shè)計(jì)人員劃分?jǐn)?shù)據(jù)庫提供幫助。
關(guān)鍵字:海量數(shù)據(jù);關(guān)系數(shù)據(jù)庫;劃分
中圖分類號(hào):TP311.138
隨著互聯(lián)網(wǎng)、物聯(lián)網(wǎng)的發(fā)展,產(chǎn)生了越來越多的TB級(jí)別的數(shù)據(jù)。雖然研發(fā)出能夠滿足海量數(shù)據(jù)的存儲(chǔ)和訪問要求NOSQL數(shù)據(jù)庫,但是NOSQL數(shù)據(jù)庫不能夠滿足原子性、一致性、隔離性、持久性的要求[1],所以系統(tǒng)中關(guān)鍵、核心的數(shù)據(jù)依然必須存放在關(guān)系型數(shù)據(jù)庫中。在通常情況下,關(guān)系型數(shù)據(jù)庫中存放的數(shù)據(jù)量受到數(shù)據(jù)庫自身、存儲(chǔ)設(shè)備、擴(kuò)展性和系統(tǒng)性能的限制,單個(gè)關(guān)系型數(shù)據(jù)庫中存放的數(shù)據(jù)量是有限的,無法滿足海量數(shù)據(jù)存儲(chǔ)和訪問的要求。必須將數(shù)據(jù)分散在多個(gè)數(shù)據(jù)庫中,將這些數(shù)據(jù)庫作為一個(gè)整體為應(yīng)用提供服務(wù),以達(dá)到存儲(chǔ)海量數(shù)據(jù)、平衡負(fù)載、提高系統(tǒng)可用性的目的。
將數(shù)據(jù)庫中的數(shù)據(jù)分配到不同服務(wù)器的主要方法是垂直劃分和水平劃分[2]。水平數(shù)據(jù)劃分是基于數(shù)據(jù)庫表的數(shù)據(jù)量,若表的數(shù)據(jù)量超出了單個(gè)數(shù)據(jù)庫的容量,則需要將該表中的數(shù)據(jù)拆分到不同的數(shù)據(jù)庫中。垂直數(shù)據(jù)劃分是基于數(shù)據(jù)庫中表與表之間的關(guān)系,若某幾張表之間的聯(lián)系非常緊密,則需要將這些表存放在相同的數(shù)據(jù)庫中[3]。
數(shù)據(jù)庫管理員劃分?jǐn)?shù)據(jù)庫時(shí),雖然會(huì)同時(shí)使用水平數(shù)據(jù)劃分和垂直數(shù)據(jù)劃分的理念,但是沒有特別有效地方法給予適當(dāng)?shù)闹笇?dǎo),使得數(shù)據(jù)的劃分在很大程度上依賴數(shù)據(jù)庫管理員的經(jīng)驗(yàn)以及大量的測試。在劃分的過程中,通常為了獲得良好的系統(tǒng)性能,數(shù)據(jù)庫管理員必須頻繁更改數(shù)據(jù)庫設(shè)計(jì)和測試,這樣即浪費(fèi)大量的時(shí)間和精力,又不一定能夠獲得良好的效果。在現(xiàn)有的數(shù)據(jù)庫劃分方法研究中,都是基于某次操作代價(jià)或者數(shù)據(jù)庫本身的主外鍵關(guān)系,考慮的方面較為單一,不能綜合考慮到程序運(yùn)行時(shí)狀態(tài)、充分發(fā)揮服務(wù)器和數(shù)據(jù)庫的性能。正是由于這樣的問題,使得這些方法缺乏普適性,不具有推廣和應(yīng)用的價(jià)值。
1 數(shù)據(jù)庫自動(dòng)化分方法概述
針對(duì)上述問題,本文提出一種綜合考慮各種影響數(shù)據(jù)庫切分的因素,如SQL語句、SQL語句的執(zhí)行頻率、表數(shù)據(jù)量信息、服務(wù)器的配置信息、數(shù)據(jù)庫信息,通過一定的估算,自動(dòng)生成數(shù)據(jù)庫各表之間的依賴關(guān)系、數(shù)據(jù)庫劃分建議,幫助數(shù)據(jù)庫管理人員做數(shù)據(jù)庫的劃分。同時(shí)考慮到在數(shù)據(jù)庫劃分之后,數(shù)據(jù)庫管理員還需要修改大量已有的SQL語句、分配機(jī)器,為了緩解數(shù)據(jù)庫管理員的負(fù)擔(dān),該算法還提供自動(dòng)生成每個(gè)數(shù)據(jù)庫的建表語句的功能。該算法的大致流程如圖1所示:
2 算法主要考慮的因素
影響數(shù)據(jù)庫切分的因素主要分為五類大類,分別是SQL語句、SQL語句的執(zhí)行頻率、表數(shù)據(jù)量信息、服務(wù)器的配置信息、數(shù)據(jù)庫信息。下邊介紹這些因素與該算法的關(guān)系。
2.1 SQL語句
SQL是一種數(shù)據(jù)庫查詢和程序設(shè)計(jì)語言,用于存取數(shù)據(jù)以及查詢、更新和管理關(guān)系數(shù)據(jù)庫系統(tǒng)[4]。SQL語句,它反映數(shù)據(jù)庫表與表之間,表中字段的值之間的靜態(tài)關(guān)系。在該算法中,主要使用SQL語句分為兩大類:
2.1.1 SQL建表語句
SQL語句的建表語句主要用于創(chuàng)建數(shù)據(jù)庫中的表。建表語句即包含反應(yīng)表與表之參照完整的主外鍵關(guān)系,也包含了反應(yīng)表中字段中的取值的關(guān)系。主外鍵關(guān)系在數(shù)據(jù)庫執(zhí)行insert、update、delete語句時(shí),會(huì)被使用到;段中的取值的關(guān)系unique,在數(shù)據(jù)庫執(zhí)行insert語句時(shí)會(huì)被使用到。
2.1.2 SQL函數(shù)、存儲(chǔ)過程、觸發(fā)器、程序中的SQL語句
SQL函數(shù)、存儲(chǔ)過程、觸發(fā)器、程序中的SQL語句主要用于操作數(shù)據(jù)庫中的數(shù)據(jù)。它們包含的join語句反映了表與表之間關(guān)系[5]。
2.2 SQL語句的執(zhí)行頻率
SQL語句在程序的運(yùn)行過程當(dāng)中,會(huì)被不斷地調(diào)用,SQL語句執(zhí)行的頻率,在一定程度上反映數(shù)據(jù)庫運(yùn)行時(shí)表與表之間,表中字段的值之間的動(dòng)態(tài)關(guān)系。一般情況下,某個(gè)SQL語句的執(zhí)行次數(shù)越多,則包含在該SQL語句中的表之間的聯(lián)系越緊密。
2.3 表數(shù)據(jù)量信息
預(yù)估的數(shù)據(jù)量,即數(shù)據(jù)庫所需要承載的數(shù)據(jù)量的大小,也反映了涉及該表的SQL語句的執(zhí)行時(shí)間。當(dāng)一個(gè)表的數(shù)據(jù)量超過了單個(gè)數(shù)據(jù)庫所能容納的最大限度時(shí),則需要對(duì)其進(jìn)行水平切分,將同一個(gè)表中的數(shù)據(jù)放到其他的數(shù)據(jù)庫中。如果一個(gè)表的數(shù)據(jù)量越大,則涉及該表的SQL語句的執(zhí)行時(shí)間的操作時(shí)間越長。
2.4 數(shù)據(jù)庫信息
數(shù)據(jù)庫種類信息,反映了數(shù)據(jù)庫的性能。它要包括數(shù)據(jù)庫種類和數(shù)據(jù)庫配置信息兩類。不同的數(shù)據(jù)庫有著不同的句法規(guī)則、不同的數(shù)據(jù)讀寫方式,所以在分析SQL語句語法規(guī)則和SQL語句執(zhí)行代價(jià)時(shí),必須明確數(shù)據(jù)庫的種類。相同的數(shù)據(jù)庫,在不同配置的情況下,能夠發(fā)揮出的性能也是不同的,所以數(shù)據(jù)庫的配置在一定程度上決定了數(shù)據(jù)庫的性能,合理的配置數(shù)據(jù)庫,可以提高數(shù)據(jù)庫的性能。
2.5 服務(wù)器的配置信息
服務(wù)器配置信息,反映了服務(wù)器性能的強(qiáng)弱。在配置信息中,起到?jīng)Q定性左右的是CPU,內(nèi)存和硬盤。CPU決定了服務(wù)器處理指令的能力,內(nèi)存決定了數(shù)據(jù)庫可以使用的緩存的大小,硬盤決定了數(shù)據(jù)庫中可以存儲(chǔ)的數(shù)據(jù)量的多少。
3 算法的主要流程詳解
3.1 配置相應(yīng)的參數(shù)
將影響數(shù)據(jù)庫切分的主要因素,寫成相應(yīng)的配置文件輸入到系統(tǒng)中。
3.2 生成主外鍵關(guān)系矩陣和特殊數(shù)據(jù)項(xiàng)表
基于對(duì)SQL建表語句的分析,可以得到主外鍵依賴矩陣和特殊數(shù)據(jù)項(xiàng)表。算法流程如下所示:
(1)設(shè)一共有n張表格,建立主外鍵依賴矩陣ReferencesDataRelation[n][n],ReferencesDataRelation[i][j]表中的第i行第j列代表第i張表的外鍵在第j張表中,其值代表i與表j做連接操作的代價(jià),為數(shù)據(jù)量的乘積,所有的初始值為0;
(2)設(shè)在所有的建表語句中包含m個(gè)設(shè)置為unique的字段,建立特殊數(shù)據(jù)項(xiàng)數(shù)組specificItem[m],每個(gè)項(xiàng)中標(biāo)示第i張表與表中第k個(gè)字段被設(shè)置為unique。如第四張表的第三個(gè)字段被設(shè)置為unique,則specificItem[m]中某項(xiàng)的值為4_3;
(3)依次讀取數(shù)據(jù)庫的建表語句,按照數(shù)據(jù)表讀入的次序,從0開始對(duì)表進(jìn)行編號(hào);
(4)查找建表語句中是否包含設(shè)置為unique的字段,如果沒有,則轉(zhuǎn)到6;
(5)獲取表的編號(hào)i,字段的編號(hào)k,將specificItem表中的某個(gè)可使用的位置設(shè)置為i_k;
(6)讀取數(shù)據(jù)庫建表語句,如果沒有,則轉(zhuǎn)到10;
(7)查看該語句中是否包含反應(yīng)主外鍵的關(guān)鍵字references,如果沒有,轉(zhuǎn)到8;
(8)獲取表的編號(hào),設(shè)兩個(gè)表的編號(hào)分別為i,j;
(9)讀取預(yù)估主表的數(shù)據(jù)量為l和h,將二維矩陣的對(duì)應(yīng)于表編號(hào)的位置ReferencesDataRelation[i,j]和ReferencesDataRelation[j,i]的位置設(shè)置為l*h;
(10)轉(zhuǎn)到3;
(11)結(jié)束。
3.3 計(jì)算表與表之間的依賴關(guān)系
表與表之間的動(dòng)態(tài)的關(guān)系主要通過數(shù)據(jù)庫運(yùn)行過程中執(zhí)行SQL語句、SQL語句執(zhí)行的頻率和表的數(shù)據(jù)量反映出。根據(jù)一定的計(jì)算,得出表與表之間的依賴關(guān)系。具體的算法流程如下所示:
(1)根據(jù)歷史的統(tǒng)計(jì)情況,估算每個(gè)SQL語句在系統(tǒng)運(yùn)行過程中所占的比例;
(2)建立表與表之間的依賴關(guān)系矩陣SQLReleation[n][n],SQLReleation[i][j]表中的第i行第j列代表表i與表j的關(guān)系的緊密程度,其值為表i與表j之間所有的SQL語句執(zhí)行的代價(jià)與SQL語句戰(zhàn)系統(tǒng)中運(yùn)行比例的乘積,矩陣中所有項(xiàng)所有的初始值為0;
(3)讀取一個(gè)SQL語句,如果沒有,則轉(zhuǎn)到9;
(4)并建立語法樹;
(5)自下到上,根據(jù)各表的數(shù)據(jù)量和語句類型,預(yù)估計(jì)算每一層的運(yùn)算代價(jià),設(shè)為n。標(biāo)注層是由那些表的操作生成的。如果在某一層遇到j(luò)oin語句,則查找兩個(gè)參與join運(yùn)算的表i,j的數(shù)據(jù)量,分別為k,l,并得出運(yùn)算的代價(jià)k*l;
(6)讀取該SQL語句的執(zhí)行頻率r;
(7)將SQLReleation[i][j]和SQLReleation[i][j]中的值設(shè)置為SQLReleation[i][j]=SQLReleation[j][i]=SQLReleation[j][i]+k*i*r;
(8)轉(zhuǎn)到3;
(9)結(jié)束。
3.4 垂直劃分?jǐn)?shù)據(jù)庫
依據(jù)數(shù)據(jù)庫垂直劃分的概念,需要基于數(shù)據(jù)庫中表與表的關(guān)系,將不同的數(shù)據(jù)庫表保存在分布于不同服務(wù)器上的數(shù)據(jù)庫實(shí)例中[2]。在第三步驟中,已經(jīng)得到表示表與表之間的關(guān)系強(qiáng)弱的矩陣,該矩陣為對(duì)稱矩陣。將該矩陣抽象為一個(gè)帶權(quán)無向圖,圖的定點(diǎn)代表,圖的邊上的權(quán)重代表與表之間關(guān)系的強(qiáng)弱。根據(jù)圖的可達(dá)性算法[5],求出每個(gè)可達(dá)的閉包。如果閉包過大,則可以設(shè)置一定的閾值,對(duì)閉包進(jìn)行拆分,最終完成對(duì)數(shù)據(jù)庫的垂直切分。算法如下所示:
(1)求出該矩陣中所有數(shù)據(jù)之和,并求平均值,作為管理員劃分的閾值的參考;
(2)管理員輸入表示忽略表與表之間關(guān)系的下限的數(shù)值和閉包拆分的數(shù)值;
(3)將矩陣中所有小于表與表之間關(guān)系的下限的數(shù)據(jù)設(shè)置為0;
(4)根據(jù)矩陣可達(dá)性算法,求出每一個(gè)可達(dá)閉包;
(5)輸入一個(gè)閉包,如果沒有則轉(zhuǎn)到9;
(6)輸出所有的可達(dá)閉包以及閉包中表與表之間的權(quán)重;
(7)如果該閉包中的所有的權(quán)重之和大于閉包拆分的閾值,則將改閉包拆分,生成新的閉包。將新生成的閉包加入需要檢驗(yàn)的閉包中;
(8)轉(zhuǎn)到5;
(9)結(jié)束。
3.5 水平劃分?jǐn)?shù)據(jù)庫
水平數(shù)據(jù)劃分主要是表基于數(shù)據(jù)量的大小,將同一張表中的數(shù)據(jù)分布在不同的數(shù)據(jù)庫當(dāng)中[6]。在算法五中,求得垂直劃分后哪些表應(yīng)該放在同一個(gè)數(shù)據(jù)庫中。但是,當(dāng)數(shù)據(jù)量過大時(shí),也需要對(duì)這些表進(jìn)行水平劃分。在該算法中以閉包中所有表的數(shù)據(jù)量、服務(wù)器的配置,數(shù)據(jù)庫的配置為基數(shù),將閉包中的所有的表作為一個(gè)整體進(jìn)行劃分。算法如下:
(1)依據(jù)服務(wù)器的配置和數(shù)據(jù)庫的參數(shù),計(jì)算每臺(tái)服務(wù)器可以承載的最大數(shù)據(jù)量,以及所有機(jī)器能夠承載數(shù)據(jù)總量。并將所有的機(jī)器按照承載數(shù)據(jù)量的能力,由大到小排序,排序后的結(jié)果為機(jī)器名稱與該機(jī)器承載能力的對(duì),設(shè)為
(2)對(duì)由算法五生成的每個(gè)閉包,求出每個(gè)閉包的總數(shù)據(jù)量以及所有數(shù)據(jù)量的和;
(3)計(jì)算剩余服務(wù)器所能承載的數(shù)據(jù)量以及所有閉包的總數(shù)據(jù)量,如果所有機(jī)器能夠承載的數(shù)據(jù)總量小于表的數(shù)據(jù)量,則轉(zhuǎn)到8;
(4)按照數(shù)據(jù)量,對(duì)閉包從大到小進(jìn)行排序。排序后,對(duì)閉包進(jìn)行編號(hào)。得到編號(hào)與閉包的數(shù)據(jù)量的對(duì),<1,B1>,<2,B2>,.......(數(shù)字為閉包的編號(hào),B+數(shù)字為數(shù)據(jù)量的大小,其中B1>B2>.....);
(5)取出一個(gè)閉包,如果沒有則轉(zhuǎn)到8;
(6)按照從大到小的順序,取出一個(gè)閉包設(shè)為m,依次檢索每臺(tái)機(jī)器,找到與大于并且最為接近該閉包數(shù)據(jù)量服務(wù)器序列。如果可以找到,則將所有的數(shù)據(jù)都放在該機(jī)器上,并將還有剩余空間的機(jī)器所能承載的數(shù)據(jù)量設(shè)置為當(dāng)前能承載的數(shù)據(jù)量減去放置在該服務(wù)器中的數(shù)據(jù)量。并將該服務(wù)器編號(hào)插入到服務(wù)器隊(duì)列中。轉(zhuǎn)到3;
(7)輸出每臺(tái)機(jī)器上的表的閉包;
(8)結(jié)束。
3.6 生成每臺(tái)機(jī)器的建表語句
根據(jù)垂直和水平劃分的結(jié)果,生成每臺(tái)服務(wù)器的建表語句。從而幫助數(shù)據(jù)庫管理員處理數(shù)據(jù)劃分后的建立數(shù)據(jù)庫的問題。主要是依據(jù)SQL建表語句以及步驟六所得的每臺(tái)機(jī)器上的表分配信息。算法如下:
(1)讀取原有數(shù)據(jù)庫建表語句,并對(duì)表進(jìn)行編號(hào);
(2)讀取所有服務(wù)器的信息,并對(duì)服務(wù)器進(jìn)行編號(hào);
(3)讀取某一個(gè)閉包,如果沒有則轉(zhuǎn)到9;
(4)設(shè)閉包中的表為(A,B,C,D,E),獲取閉包中所有表的建表語句和放置該閉包數(shù)據(jù)的服務(wù)器信息;
(5)讀取閉包中的一個(gè)建表表語句,如果沒有則轉(zhuǎn)到7;
(6)設(shè)讀取到A的建表語句,檢索到建表語句中與表A存在主外鍵關(guān)系的表K,如果K在閉包中且該閉包分配到一臺(tái)服務(wù)器中,則保留reference語句,如果k不在閉包中或改閉包分配到多個(gè)服務(wù)器中,則刪除reference語句;
(7)將修改后的建表語句存放到對(duì)應(yīng)的服務(wù)器建表語句中,轉(zhuǎn)到5;
(8)轉(zhuǎn)到3;
(9)輸出所有機(jī)器的建表語句。
4 結(jié)束語
以上是本文提出的綜合考慮各種影響數(shù)據(jù)庫切分的因素,如SQL語句、SQL語句的執(zhí)行頻率、表數(shù)據(jù)量信息、服務(wù)器的配置信息、數(shù)據(jù)庫信息,通過一定的算法得到數(shù)據(jù)庫劃分建議、分配服務(wù)器、創(chuàng)建新的建表語句。該算法可以有效地為數(shù)據(jù)庫管理員劃分?jǐn)?shù)據(jù)庫提供參考,減輕數(shù)據(jù)庫管理員的工作量,提高了劃分?jǐn)?shù)據(jù)庫的效率。
參考文獻(xiàn):
[1]申德榮,于戈,王習(xí)特,等.支持大數(shù)據(jù)管理的NoSQL系統(tǒng)研究綜述[J].軟件學(xué)報(bào),2013(08):1786-1803.
[2]黃河.數(shù)據(jù)庫加速引擎加速方案研究[D].華中科技大學(xué),2006.
[3]Lirig數(shù)據(jù)庫的垂直劃分和水平劃分[EB/OL].http://liriguang.iteye.com/blog/625309.2010.
[4]王珊,薩師煊.數(shù)據(jù)庫系統(tǒng)概論[M].北京:高等教育出版社,2007.
[5]嚴(yán)蔚敏,吳偉民.數(shù)據(jù)結(jié)構(gòu)(C語言版)[M].北京:清華大學(xué)出版社,2012.
[6]侯佳佳,喬運(yùn)華,卜建國,等.基于分布式數(shù)據(jù)庫數(shù)據(jù)處理的研究[J].制造業(yè)自動(dòng)化,2013(01).
作者簡介:李書攀(1986-),男,河南南陽人,碩士,主要從事計(jì)算機(jī)教學(xué)。
作者單位:南陽師范學(xué)院 計(jì)算機(jī)與信息技術(shù)學(xué)院,河南南陽 473061