張雅文 劉春霞 黨偉超 白尚旺
(太原科技大學(xué)計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院 山西 太原030024)
在SaaS應(yīng)用中,一個(gè)應(yīng)用實(shí)例為多個(gè)租戶服務(wù),即雖然多租戶數(shù)據(jù)同屬于一個(gè)應(yīng)用,但是被不同的租戶進(jìn)行了不同的定制[1-2]。多寬表模式是一種有效存儲(chǔ)多租戶數(shù)據(jù)的解決方法,通過元數(shù)據(jù)驅(qū)動(dòng)實(shí)現(xiàn)租戶定制需求[3]。傳統(tǒng)數(shù)據(jù)庫(kù)索引是在關(guān)系的某個(gè)特定屬性列上建立索引,多寬表存儲(chǔ)模式是將所有租戶不同數(shù)據(jù)模式的數(shù)據(jù)共享存儲(chǔ),所以傳統(tǒng)的數(shù)據(jù)庫(kù)索引技術(shù)無法適用于多寬表模式[4]。因此本文給出元數(shù)據(jù)驅(qū)動(dòng)下改進(jìn)的Indexes Pivot Table IIPT(Improved Indexes Pivot Table)索引模型,該模型充當(dāng)多寬表模式下的租戶邏輯索引,以此提高數(shù)據(jù)訪問速度。
在現(xiàn)階段,面向SaaS應(yīng)用的多租戶數(shù)據(jù)管理是國(guó)內(nèi)外研究的重要內(nèi)容,由于多租戶數(shù)據(jù)庫(kù)在滿足租戶數(shù)據(jù)隔離和按需定制要求的同時(shí),在性能上也需使用戶有較好的體驗(yàn),因此這對(duì)數(shù)據(jù)的存儲(chǔ)機(jī)制和索引機(jī)制提出了挑戰(zhàn)[5]。多租戶數(shù)據(jù)存儲(chǔ)已經(jīng)成為熱點(diǎn),但是在索引方面的研究還比較少[6]。
SaaS應(yīng)用采用單個(gè)數(shù)據(jù)節(jié)點(diǎn)對(duì)多租戶數(shù)據(jù)進(jìn)行共享存儲(chǔ),但是由于單個(gè)數(shù)據(jù)節(jié)點(diǎn)的能力有限,無法滿足租戶數(shù)量日益增長(zhǎng)的要求,因此采用多數(shù)據(jù)節(jié)點(diǎn)進(jìn)行存儲(chǔ)是必然的[7]。為解決多數(shù)據(jù)節(jié)點(diǎn)大規(guī)模數(shù)據(jù)索引的問題,采用租戶節(jié)點(diǎn)索引、租戶邏輯索引和關(guān)系數(shù)據(jù)庫(kù)物理索引三級(jí)索引相結(jié)合的索引模型[8]。租戶節(jié)點(diǎn)索引根據(jù)當(dāng)前訪問的租戶,定位到存儲(chǔ)該租戶數(shù)據(jù)的數(shù)據(jù)節(jié)點(diǎn)。租戶邏輯索引在單節(jié)點(diǎn)上為租戶數(shù)據(jù)提供支持定制、共享的索引技術(shù),保證租戶快速訪問數(shù)據(jù)。關(guān)系數(shù)據(jù)庫(kù)索引是一個(gè)單獨(dú)的、物理的數(shù)據(jù)庫(kù)結(jié)構(gòu),在底層數(shù)據(jù)庫(kù)基礎(chǔ)上提供索引技術(shù)支持[9]。
本文主要針對(duì)單數(shù)據(jù)節(jié)點(diǎn)的索引技術(shù)進(jìn)行研究。單數(shù)據(jù)節(jié)點(diǎn)下的數(shù)據(jù)存儲(chǔ)為共享模式,如果一個(gè)租戶在某個(gè)屬性上建立索引,其他租戶也會(huì)被動(dòng)地在該屬性建立索引,所以在創(chuàng)建索引時(shí)租戶間會(huì)相互干擾[10]。為了解決該問題,M-Store提出了單獨(dú)建立租戶索引,不僅優(yōu)化了索引結(jié)構(gòu),而且提高了查詢效率,但是索引數(shù)據(jù)隨著租戶數(shù)量的增加也會(huì)越來越多,給數(shù)據(jù)庫(kù)造成很大的負(fù)擔(dān)[11]。Salesforce采用建立Indexes Pivot Table來存儲(chǔ)租戶索引數(shù)據(jù),該方法有效地提高了租戶訪問數(shù)據(jù)的速度,但隨著租戶數(shù)量的增加,Indexes Pivot Table會(huì)產(chǎn)生大量的空值,其占用的存儲(chǔ)空間也會(huì)暴漲[12-13]。為了解決傳統(tǒng)數(shù)據(jù)庫(kù)索引不能適用多寬表共享存儲(chǔ)模式的問題,以及現(xiàn)有的索引模型導(dǎo)致數(shù)據(jù)庫(kù)存儲(chǔ)空間增長(zhǎng)的問題,給出了一種元數(shù)據(jù)驅(qū)動(dòng)的IIPT索引模型,不僅存儲(chǔ)空間不會(huì)隨租戶數(shù)量急速增長(zhǎng),而且有效提高了租戶訪問數(shù)據(jù)的速度。
在SaaS模式下,數(shù)據(jù)庫(kù)不但要提供存儲(chǔ)的功能,還要支持租戶按需定制、數(shù)據(jù)隔離以及數(shù)據(jù)擴(kuò)展。結(jié)合國(guó)內(nèi)外研究現(xiàn)狀,同時(shí)比較多種存儲(chǔ)模式優(yōu)缺點(diǎn),本文選擇了多寬表模式來存儲(chǔ)租戶業(yè)務(wù)數(shù)據(jù),以及給出一種適合該模式的多租戶索引模型。
在SaaS應(yīng)用中,多租戶的特性支持單個(gè)應(yīng)用實(shí)例被不同租戶進(jìn)行不同定制。寬表模式作為一種有效解決多租戶數(shù)據(jù)存儲(chǔ)問題的方法,是將所有租戶不同數(shù)據(jù)模式的數(shù)據(jù)存儲(chǔ)到一張寬表中,為了解決寬表存在大量空值的問題,提出了多寬表的存儲(chǔ)模式。
多寬表模式提供較好的可定制性,在該模式下,租戶按需定制數(shù)據(jù)項(xiàng),將其定制信息保存在元數(shù)據(jù)(MetaDataFields)中,租戶定制的數(shù)據(jù)項(xiàng)經(jīng)過模式映射后,根據(jù)數(shù)據(jù)表的元數(shù)據(jù)信息(MetaTable)存儲(chǔ)在與租戶定制列數(shù)相近的寬表Data x中,多寬表的數(shù)據(jù)定義如圖1所示。
圖1 基于多寬表的多租戶數(shù)據(jù)庫(kù)
如表1所示,租戶從視圖層看到的是傳統(tǒng)的關(guān)系數(shù)據(jù)模式,但是在實(shí)際的多寬表存儲(chǔ)模式中,基于定制的元數(shù)據(jù)信息,該關(guān)系通過模式映射機(jī)制被透明的轉(zhuǎn)換到寬表(Data x)中,如表2所示。
表1 租戶1從視圖層看到的關(guān)系
表2 租戶1存儲(chǔ)層的關(guān)系
多寬表共享存儲(chǔ)多租戶不同業(yè)務(wù)下不同的數(shù)據(jù)模式,隨著租戶數(shù)量的不斷增加,數(shù)據(jù)量也會(huì)急劇增加,訪問數(shù)據(jù)時(shí)通過順序掃描查詢勢(shì)必會(huì)影響查詢效率,因此建立多寬表數(shù)據(jù)存儲(chǔ)模式下的多租戶索引模型勢(shì)在必行。傳統(tǒng)索引是在關(guān)系的某個(gè)特定屬性列上建立索引,該屬性列下數(shù)據(jù)的數(shù)據(jù)類型、數(shù)據(jù)模式是相同的,但是多寬表存儲(chǔ)著多種不同的數(shù)據(jù)模式,同一屬性列數(shù)據(jù)可能是不同的數(shù)據(jù)類型或代表不同的數(shù)據(jù)含義。因此給出了一種元數(shù)據(jù)驅(qū)動(dòng)改進(jìn)的Indexes Pivot Table索引模型。
Salesforce建立Indexes Pivot Table存儲(chǔ)索引數(shù)據(jù)。Indexes Pivot Table中包含字段如StringValue、NumValue和DateValue等,Salesforce將索引數(shù)據(jù)按數(shù)據(jù)類型存儲(chǔ)在相應(yīng)的字段中。例如,Salesforce會(huì)將數(shù)據(jù)表中字符串?dāng)?shù)據(jù)類型的數(shù)據(jù)復(fù)制到索引表中的StringValue字段,日期類型的數(shù)據(jù)復(fù)制到DateValue字段等。該Indexes Pivot Table在存儲(chǔ)索引數(shù)據(jù)時(shí),如果其中一個(gè)數(shù)據(jù)類型字段存儲(chǔ)了索引數(shù)據(jù),則其他數(shù)據(jù)類型為空值。隨著數(shù)據(jù)量的增大,空值的數(shù)量也會(huì)逐漸增大,浪費(fèi)了存儲(chǔ)空間。針對(duì)產(chǎn)生大量空值的情況,對(duì)Indexes Pivot Table進(jìn)行改進(jìn),將多種數(shù)據(jù)類型字段合并存儲(chǔ)在一列中,有效解決了空值產(chǎn)生的問題。
本文對(duì)多寬表模式的多租戶數(shù)據(jù)庫(kù)進(jìn)行擴(kuò)展,增加了基于元數(shù)據(jù)驅(qū)動(dòng)改進(jìn)的Indexes Pivot Table。圖2描述了IIPT多租戶數(shù)據(jù)庫(kù)模型,模型中的表分為兩種。一種為元數(shù)據(jù)表,另一種為數(shù)據(jù)表。元數(shù)據(jù)表包括字段元數(shù)據(jù)MetaDataFields、多寬表的元數(shù)據(jù)MetaTable以及索引元數(shù)據(jù)IndexDataTable。數(shù)據(jù)表包括一系列的寬表Data。
圖2 IIPT多租戶數(shù)據(jù)庫(kù)模型
下面給出本模型的表結(jié)構(gòu)定義。
定義1MetaDataFields
表示字段元數(shù)據(jù),用于存儲(chǔ)Data寬表的信息以及其中屬性的各種信息。租戶標(biāo)識(shí)TenantId、租戶邏輯私有表標(biāo)識(shí)TableName,以及寬表所屬列名fieldName聯(lián)合作為主鍵,通過RealTableName可以映射出租戶業(yè)務(wù)數(shù)據(jù)fieldName實(shí)際物理存儲(chǔ)位置,而RealFieldName可以映射Data寬表中fieldName的真正含義。fieldType、fieldLength、isIndexed、DataType分別表示fieldName的屬性:類型、長(zhǎng)度、是否為索引、真正的數(shù)據(jù)類型。
定義2MetaTable
表示多寬表的元數(shù)據(jù),用于存儲(chǔ)所有Data寬表的基本信息,包括寬表的表名和列數(shù)等信息,該信息作為租戶選擇寬表進(jìn)行存儲(chǔ)的依據(jù)。
定義3IndexDataTable
表示索引元數(shù)據(jù),用于共享存儲(chǔ)多寬表的索引。Indexes Pivot Table存儲(chǔ)多種數(shù)據(jù)類型的索引數(shù)據(jù),造成索引表中空值的增多。本文對(duì)Indexes Pivot Table進(jìn)行改進(jìn),將多種數(shù)據(jù)類型共同存儲(chǔ)在一列中。通過訪問字段元數(shù)據(jù)表,對(duì)于需要建立索引的數(shù)據(jù),將其從寬表復(fù)制到索引表中,無需關(guān)注數(shù)據(jù)類型。
定義4Data1, Data2, Data x
表示數(shù)據(jù)表,寬表的列數(shù)呈遞增趨勢(shì)分布。租戶根據(jù)數(shù)據(jù)模式具有的屬性列數(shù)選擇合適的寬表存儲(chǔ)業(yè)務(wù)數(shù)據(jù)。UID是全局唯一標(biāo)識(shí)作為寬表的主鍵,與租戶標(biāo)識(shí)TenantId和租戶邏輯私有表標(biāo)識(shí)TableName一起對(duì)租戶的業(yè)務(wù)數(shù)據(jù)進(jìn)行共享存儲(chǔ),它們的最大列數(shù)分別為valueMax、columnMax、rowMax。
租戶索引具有可定制性,定制過程就是根據(jù)租戶需求及對(duì)關(guān)系模式中某字段適合作為索引的判斷,將字段元數(shù)據(jù)表(MetaDataFields)中的isIndexed字段設(shè)置為yes。在對(duì)實(shí)時(shí)性要求較高的SaaS應(yīng)用中,如果沒有索引更新策略是不可行的。當(dāng)業(yè)務(wù)數(shù)據(jù)插入、刪除、修改時(shí),索引元數(shù)據(jù)需同時(shí)更新;當(dāng)業(yè)務(wù)數(shù)據(jù)查詢時(shí),首先根據(jù)字段元數(shù)據(jù)表判斷是否存在索引,如果存在按照索引查詢,并返回結(jié)果,如果不存在,則順序查詢,返回查詢結(jié)果。本文給出IIPT索引模型的索引插入算法IIPTIA(Improved Indexes Pivot Table Insert Algorithm),索引刪除算法IIPTDA(Improved Indexes Pivot Table Delete Algorithm),索引更新算法IIPTUA(Improved Indexes Pivot Table Update Algorithm)及查詢算法IIPTQA(Improved Indexes Pivot Table Query Algorithm)。
算法1索引插入算法(IIPTIA)
輸入:insert into R (A,B,…) values(value1,value2,value3,…)
輸出:null
1. 獲取當(dāng)前租戶標(biāo)識(shí)Tenantid;
2. 根據(jù)輸入語(yǔ)句更新數(shù)據(jù)庫(kù)中的業(yè)務(wù)數(shù)據(jù)表Data,保存全局唯一標(biāo)識(shí)(UID);
3. 根據(jù)租戶標(biāo)識(shí)Tenantid,for私有表R中的字段A,B,…,在字段元數(shù)據(jù)表MetaDataFields中判斷出R定制的索引列;
4. 取出索引列上更新的值;
5. 根據(jù)索引元數(shù)據(jù)表的結(jié)構(gòu)對(duì)索引值進(jìn)行存儲(chǔ)。
算法2索引刪除算法(IIPTDA)
輸入:delete from R where A=′b′;
輸出:null
1. 獲取當(dāng)前租戶標(biāo)識(shí)Tenantid;
2. 根據(jù)輸入語(yǔ)句獲得私有表名稱R與列名A,查詢字段元數(shù)據(jù)表MetaDataFields取得實(shí)際存儲(chǔ)表名與實(shí)際列名;
3. 根據(jù)步驟2得出實(shí)際刪除業(yè)務(wù)數(shù)據(jù)的SQL語(yǔ)句;
4. 根據(jù)步驟2對(duì)實(shí)際存儲(chǔ)的表進(jìn)行查詢,保存要?jiǎng)h除信息的全局唯一標(biāo)識(shí)UID;
5. 根據(jù)步驟4中所得UID對(duì)索引表進(jìn)行刪除操作,由此當(dāng)對(duì)業(yè)務(wù)數(shù)據(jù)進(jìn)行刪除操作時(shí),業(yè)務(wù)數(shù)據(jù)所對(duì)應(yīng)的索引數(shù)據(jù)也同步進(jìn)行刪除。
算法3索引更新算法(IIPTUA)
輸入:update A set B=′b′ where C=′c′;
輸出:null
1. 獲取當(dāng)前租戶標(biāo)識(shí)Tenantid;
2. 根據(jù)輸入語(yǔ)句獲得私有表名稱R、列名A與列名B,查詢字段元數(shù)據(jù)表MetaDataFields取得實(shí)際存儲(chǔ)表名與實(shí)際列名,以及set的列是否為索引列;
3. 對(duì)sql語(yǔ)句進(jìn)行解析,獲得索引更新值b與條件值c;
4. 根據(jù)步驟2與步驟3得出實(shí)際更新業(yè)務(wù)數(shù)據(jù)的SQL語(yǔ)句;
5. 根據(jù)步驟2與步驟3對(duì)實(shí)際存儲(chǔ)的表進(jìn)行查詢,保存要更新信息的全局唯一標(biāo)識(shí)UID;
6. if步驟2中結(jié)果為yes
根據(jù)步驟5中得到的UID對(duì)索引數(shù)據(jù)表進(jìn)行更新
else步驟2中的結(jié)果為no。
無需對(duì)索引表進(jìn)行更新。
算法4數(shù)據(jù)查詢算法(IIPTQA)
輸入:select A,B,… from R where D=value1
輸出:符合條件的目標(biāo)結(jié)果集
1. 獲取當(dāng)前租戶標(biāo)識(shí)Tenantid;
2. 解析查詢語(yǔ)句中的私有表R和所查字段A,B,…;
3. 查詢字段元數(shù)據(jù)表(MetaDataFields)獲得私有表R實(shí)際存儲(chǔ)表名Data,以及所查字段(A,B,…)在Data表中的實(shí)際字段名value n(n=1,2,…,n);
4. 查詢字段元數(shù)據(jù)表(MetaDataFields)獲得where條件D是否為索引;
5. If 步驟4中結(jié)果為yes
查詢索引元數(shù)據(jù)表(IndexDataTable)獲得數(shù)據(jù)行全局唯一標(biāo)識(shí)UID;
在Data表中,根據(jù)UID字段上的數(shù)據(jù)庫(kù)物理索引B-樹,直接查;
返回符合條件的目標(biāo)數(shù)據(jù)集。
Else 步驟4中的結(jié)果為no
依次將A,B,…,D用查詢到的實(shí)際字段名value n替換,將R用Data表替換;
替換后拼接成可直接作用于Data表的查詢語(yǔ)句,進(jìn)行查詢;
返回符合條件的目標(biāo)數(shù)據(jù)集。
本文實(shí)現(xiàn)了基于關(guān)系型數(shù)據(jù)庫(kù),在多寬表共享數(shù)據(jù)存儲(chǔ)模式下元數(shù)據(jù)驅(qū)動(dòng)的索引機(jī)制。實(shí)驗(yàn)主要針對(duì)空值數(shù)量進(jìn)行分析,并對(duì)本文給出的索引策略進(jìn)行驗(yàn)證。實(shí)驗(yàn)環(huán)境如下:
數(shù)據(jù)庫(kù)版本為MySQL Server 5.5,運(yùn)行環(huán)境為Eclipse 3.7.2。
在存儲(chǔ)單元的基礎(chǔ)上對(duì)空值數(shù)量進(jìn)行分析,假設(shè)存儲(chǔ)N個(gè)索引數(shù)據(jù)。若采用Indexes Pivot Table存儲(chǔ),其中表示數(shù)據(jù)類型的字段有M個(gè),則存在(M-1)×N個(gè)空值。
若采用IIPT存儲(chǔ),所有索引數(shù)據(jù)只存儲(chǔ)在一個(gè)字段中,沒有空值產(chǎn)生。
分析可得,采用改進(jìn)的Indexes Pivot Table,相對(duì)于Indexes Pivot Table,解決了空值問題,節(jié)省了存儲(chǔ)空間。
實(shí)驗(yàn)數(shù)據(jù)采用3個(gè)關(guān)系模式作為實(shí)例,分別為:學(xué)生(Student)關(guān)系模式、課程(Course)關(guān)系模式和地址(NativePlace)關(guān)系模式。定制關(guān)系模式中的一個(gè)屬性為索引屬性,分別為CNo、NNo和SOld。3個(gè)關(guān)系模式的數(shù)據(jù)經(jīng)過模式映射存儲(chǔ)在合適的Data表中,Data表中字段UID上有主碼索引,Data表數(shù)據(jù)量為10 000條。
由租戶發(fā)起insert插入數(shù)據(jù)的更新操作,實(shí)驗(yàn)算法1中的索引插入。例句如下:
insert into Course (CNo,Cname,CGrade) values (8,yuwen,2)
insert into NativePlace(NNo,Nname,NPlace) values (001,wangli,beijing)
insert into Student(SNo,Sname,SSex,SOld,Spart) values (001,wangna,nv,22,jisuanji)
分別更新數(shù)據(jù)到各自的Data表中,如表3和表4所示。
表3 Course和NativePlace所在Data表
表4 Student所在Data表
根據(jù)更新的數(shù)據(jù)對(duì)索引表同步更新,如表5所示。
表5 改進(jìn)的Indexes Pivot Table
以上實(shí)驗(yàn)實(shí)現(xiàn)了算法1的索引插入的更新策略。
由租戶發(fā)起delete刪除數(shù)據(jù)的更新操作,實(shí)驗(yàn)算法2中的索引刪除。例句如下:
delete from Student where SNo=′000′
根據(jù)算法2可成功刪除實(shí)際存儲(chǔ)表中Student 學(xué)號(hào)為′000′的數(shù)據(jù),同時(shí)也刪除了索引表中該學(xué)生的所有索引信息。
由租戶發(fā)起update數(shù)據(jù)的更新操作,實(shí)驗(yàn)算法3中的索引更新。例句如下:
update Student set SOld=′30′ where SNo=′000′
根據(jù)算法3,判斷得出SOld為索引列,因此在更新業(yè)務(wù)數(shù)據(jù)的同時(shí)對(duì)索引表也進(jìn)行更新。
update Student set SName=′zhangli′ where SNo=′000′
根據(jù)算法3,判斷得出SName不是索引列,因此只需更新業(yè)務(wù)數(shù)據(jù),索引表保持不變。
為了模擬多租戶環(huán)境,本實(shí)驗(yàn)開啟40個(gè)線程作為40個(gè)租戶對(duì)數(shù)據(jù)進(jìn)行操作。記錄有索引機(jī)制與沒有索引機(jī)制40個(gè)租戶分別對(duì)數(shù)據(jù)進(jìn)行查詢的時(shí)間,實(shí)驗(yàn)結(jié)果如圖3所示。
圖3 查詢時(shí)間對(duì)比
如圖3所示,圖中上方的曲線是沒有加入索引機(jī)制的查詢時(shí)間,下方是加入索引機(jī)制后的查詢時(shí)間。在無索引機(jī)制下,40個(gè)租戶的平均查詢時(shí)間為123.675 ms;在索引機(jī)制下,平均查詢時(shí)間為30.025 ms,比無索引機(jī)制的平均查詢時(shí)間低75.72%。通過實(shí)驗(yàn)驗(yàn)證可得,在兩級(jí)索引即租戶邏輯索引和關(guān)系數(shù)據(jù)庫(kù)物理索引的基礎(chǔ)上,本文給出的算法是可實(shí)現(xiàn)的,并且提高了多租戶數(shù)據(jù)查詢效率。
綜上所述,給出的多寬表模式下的索引模型,較好地解決了SaaS應(yīng)用索引的定制問題,以及在查詢效率上實(shí)驗(yàn)效果也較為理想。
本文基于MySQL關(guān)系型數(shù)據(jù)庫(kù),在多寬表數(shù)據(jù)存儲(chǔ)模式下引入改進(jìn)的Indexes Pivot Table,減少了Indexes Pivot Table作為索引表產(chǎn)生的空值數(shù)量。同時(shí)給出了在該模型下的索引維護(hù)策略,包含索引更新策略和在索引機(jī)制下的查詢策略,通過實(shí)驗(yàn)實(shí)現(xiàn)了同步更新索引表以及有效提高數(shù)據(jù)查詢效率。在下一步研究中,如何對(duì)索引列更全面地進(jìn)行設(shè)置是需要考慮的問題。