在初學(xué)HBase時,自己將HBase中的名詞類與MySQL數(shù)據(jù)庫中的相對照著學(xué),總是不理解HBase的數(shù)據(jù)結(jié)構(gòu)及原理,追本溯源去看Google三大論文之BigTable,看到這部分覺得十分簡單的表達了BigTable的結(jié)構(gòu),摘抄下來與大家分享。
BigTable作為一個NoSQL數(shù)據(jù)庫,本文目的是幫助初學(xué)者理解列存數(shù)據(jù)庫,與傳統(tǒng)的關(guān)系型數(shù)據(jù)庫不同,但是卻沿用了很多關(guān)系型數(shù)據(jù)庫的術(shù)語,例如table row column,若是將這些與關(guān)系型數(shù)據(jù)庫中的概念對照著理解的話,很容易走火入魔,百思不得其解。
本質(zhì)上看BigTable其實是一個鍵值對映射,是一個稀疏的,分布式的,持久化的,多維的排序映射。
BigTable有三維,分別是行鍵(row Key),列鍵(column key)和時間戳(timestamp),行鍵和列鍵都是字節(jié)串,時間戳是64位整型;值是一個字節(jié)串。
一條數(shù)據(jù)可以表示為:row:string,column:string,time:int64) -> string
行鍵可以是任意字節(jié)串,通常10-100字節(jié),行的讀寫是原子性的,BigTable按照行鍵的字典序存儲數(shù)據(jù)。
BigTable 的表根據(jù)row Key來劃分 tablet(片劑),tablet是負(fù)載均衡的單元,最初表只有一個tablet,
隨著表數(shù)據(jù)不斷增多,表越來越大,tablet會自動分裂,tablet的大小一般在100-200M之間,row key是表的
第一級索引,我們可以把該行的列、時間和值看成一個整體,簡化成一維鍵值映射,類似于
table{
? ? ?"1":{row1},//行
? ? ?"aaa":{sth},
? ? ?"bbb":{sth},
? ? ?"xxx":{sth},
? ? ?"zzz":{sth}
}
列是第二級索引,每行擁有的列是不受限制的,可以隨時增加減少,列又被分為多個列簇(column family,是訪問
控制的單元),一般,一個列簇里面的列存儲的是相同類型的數(shù)據(jù)。一行的列簇很少變化,但列簇里面的列可以隨意添加和刪除。列鍵按照family:qualifier格式命名,下面是將列拿出來,將時間和值看成一個整體,簡化為二維鍵值映射:
table {
? ? ?"aaa": { //aaa行
? ? ? ? ? "A:foo":{sth}, //一列 列簇名為A
? ? ? ? ? "A:bar":{sth}, //一列 列簇名為A
? ? ? ? ? "B:"{STH} //一列 列簇名為空
? ? ?},
? ? ?"aaab":{
? ? ? ? ? "A:foo": {sth},
? ? ? ? ? "B:":{sth}
},
...
}
或者也可以將列簇當(dāng)作一層新的索引,類似于:
table{
? ? ?"aaa":{
? ? ? ? ? "A":{
? ? ? ? ? ? ? ?"foo":{sth},
? ? ? ? ? ? ? ?"bar":{sth}
},
? ? ? ? ? "B":{
? ? ? ? ? ? ? ?"":"ocean"
}
},
...
}
時間戳為第三極索引,BigTable允許保存數(shù)據(jù)的多個版本,版本區(qū)別依據(jù)就是時間戳。時間戳由BigTable賦值,
代表數(shù)據(jù)存入BigTable的準(zhǔn)確時間,也可以由客戶端賦值,數(shù)據(jù)的不同版本按照時間降序存儲,因此,最先讀到的
是最新版本的數(shù)據(jù),加入時間戳以后,就得到BigTable的完整數(shù)據(jù)模型,類似于:
table{
...
? ? ?"aaa": {
? ? ? ? ? "A":{
? ? ? ? ? ? ? ? "foo":{
? ? ? ? ? ? ? ? ? ? 15:"y", //一個版本
? ? ? ? ? ? ? ? ? ? ?4:"m"
},
? ? ? ? ? ? ? "bar":{
? ? ? ? ? ? ? ? ? ? 15:"d",
? ? ? ? ? },
? ? ?},
? ? ? ? ? "B": {
? ? ? ? ? ? ? ?6:"a"
? ? ? ? ? ? ? ? 3:"b"
}
},
...
}
查詢的時候,若是只給出行列,則返回的是最新版本的數(shù)據(jù),若給出行、列、時間戳,則返回的是時間小于或等于時間戳的數(shù)據(jù)。例:查詢 "aaa"/"A:foo",返回的是值"y",查詢 "aaa"/"A:foo"/4,返回的結(jié)果則是"m",查詢"aaa"/"A:foo"/2,返回的結(jié)果是空
BigTable在Google的應(yīng)用小例子:WebTable表中存儲了大量的網(wǎng)頁相關(guān)信息,在WebTable中每一行存儲一個網(wǎng)頁,
其反轉(zhuǎn)的URL作為 rowKey,例如maps.google.com/index.html的數(shù)據(jù)存儲在鍵為com.google.maps/index.html的行里面,反轉(zhuǎn)設(shè)置的原因是為了讓同一個域名下的子域名網(wǎng)頁能聚集在一起,