教育行業(yè)A股IPO第一股(股票代碼 003032)

全國(guó)咨詢/投訴熱線:400-618-4000

HBase怎樣查詢數(shù)據(jù)表和獲取多版本數(shù)據(jù)?

更新時(shí)間:2023年11月06日10時(shí)46分 來(lái)源:傳智教育 瀏覽次數(shù):

HBase數(shù)據(jù)模型是一個(gè)多維稀疏映射。 HBase中的表包含列族,其列限定符包含值和時(shí)間戳。在大多數(shù) HappyBase API 中,列族和限定符名稱被指定為單個(gè)字符串,例如cf1:col1,而不是作為兩個(gè)單獨(dú)的參數(shù)。雖然列族和限定符在 HBase 數(shù)據(jù)模型中是不同的概念,但它們?cè)谂c數(shù)據(jù)交互時(shí)幾乎總是一起使用,因此將它們視為單個(gè)字符串會(huì)使 API 變得更簡(jiǎn)單。

查詢行

Table 類(lèi)提供了多種方法來(lái)從 HBase 中的表中檢索數(shù)據(jù)。最基本的是 Table.row(),它從表中檢索單行,并將其作為映射列到值的字典返回:

row = table.row(b'rk0001')
print(row[b'info:name'])   # prints the value of info:name
# 返回值:b'zhangsan',注意是二進(jìn)制<class 'bytes'>類(lèi)型
# 轉(zhuǎn)換字符串:
print(str(row[b'info:name'], encoding="utf-8"))
# 即
str(bytes對(duì)象, encoding="編碼格式,通常使用utf-8")

> 注意,庫(kù)中的字符串都有前綴:b,表示二進(jìn)制

> 如:print(type(row[b'info:name']))

> 返回值:

查詢多行

Table.rows() 方法的工作方式與 Table.row() 類(lèi)似,但需要多個(gè)行鍵并將它們作為 (key, data) 元組返回:

rows = table.rows([b'rk0001', b'rk0002'])
for key, data in rows:
    print(key, data)

"""
返回值:
b'rk0001' {b'data:pic': b'picture', b'info:age': b'20', b'info:gender': b'female', b'info:name': b'zhangsan'}
b'rk0002' {b'data:pic': b'picture', b'info:age': b'11', b'info:gender': b'male', b'info:name': b'wangwu'}

注意哦,key是bytes對(duì)象
data是字典對(duì)象,字典中key和value都是bytes

如果您希望 Table.rows() 作為字典或有序字典返回的結(jié)果,您必須自己執(zhí)行此操作。不過(guò)這真的很簡(jiǎn)單,因?yàn)榉祷刂悼梢灾苯觽鬟f給字典構(gòu)造函數(shù)。對(duì)于普通字典,順序丟失:

rows_dict = dict(table.rows([b'rk0001', b'rk0002']))
# 返回值:
"""
字典:
{b'rk0001': {b'data:pic': b'picture', b'info:age': b'20',
 b'info:gender': b'female', b'info:name': b'zhangsan'}, 
 b'rk0002': {b'data:pic': b'picture', b'info:age': b'11',
  b'info:gender': b'male', b'info:name': b'wangwu'}}
"""

而對(duì)于 OrderedDict,順序被保留:

from collections import OrderedDict
rows_as_ordered_dict = OrderedDict(table.rows([b'rk0002', b'rk0001']))

"""
返回值:
OrderedDict([(b'rk0002', {b'data:pic': b'picture', 
b'info:age': b'11', b'info:gender': b'male', b'info:name': 
b'wangwu'}), (b'rk0001', {b'data:pic': b'picture', 
b'info:age': b'20', b'info:gender': b'female', 
b'info:name': b'zhangsan'})])
"""

進(jìn)行更細(xì)粒度的查詢

HBase 的數(shù)據(jù)模型允許對(duì)要檢索的數(shù)據(jù)進(jìn)行更細(xì)粒度的選擇。如果您事先知道需要哪些列,則可以通過(guò)將這些列明確指定給 Table.row() 和 Table.rows() 來(lái)提高性能。 columns 參數(shù)采用列名的列表(或元組):

row = table.row(b'rk0001', columns=[b'info:name', b'data:pic'])
# row對(duì)象類(lèi)型字典,內(nèi)容:{b'data:pic': b'picture', b'info:name': b'zhangsan'}
print(row[b'info:name'])
print(row[b'data:pic'])

"""
返回值:bytes類(lèi)型,需要的話自行轉(zhuǎn)字符串
b'zhangsan'
b'picture'

如果檢索一整個(gè)列族中的所有列(二級(jí)列)。例如,要獲取列族 info中的所有列和值,請(qǐng)使用以下命令:

row = table.row(b'rk0001', columns=[b'info'])
print(type(row))
print(row)

"""
返回值:
<class 'dict'>
{b'info:age': b'20', b'info:gender': b'female', b'info:name': b'zhangsan'}
"""

基于時(shí)間戳查詢

在 HBase 中,每個(gè)單元都有一個(gè)附加的時(shí)間戳。如果您不想使用存儲(chǔ)在 HBase 中的最新版本數(shù)據(jù),則可以使用從數(shù)據(jù)庫(kù)中檢索數(shù)據(jù)的方法,例如Table.row() 都接受一個(gè)時(shí)間戳參數(shù),該參數(shù)指定結(jié)果應(yīng)限制為時(shí)間戳不超過(guò)指定時(shí)間戳的值:

row = table.row(b'rk0001', timestamp=123456789)

默認(rèn)情況下,HappyBase 在返回的結(jié)果中不包含時(shí)間戳。在您的應(yīng)用程序需要訪問(wèn)時(shí)間戳?xí)r,只需將 include_timestamp 參數(shù)設(shè)置為 True。現(xiàn)在,結(jié)果中的每個(gè)單元格都將作為(值,時(shí)間戳)元組返回,而不僅僅是一個(gè)值:

row = table.row(b'rk0001', columns=[b'info'], include_timestamp=True)
print(type(row))
print(row)

"""
返回值:
<class 'dict'>
{b'info:age': (b'20', 1641832837038), b'info:gender':
 (b'female', 1641832832414), b'info:name': (b'zhangsan', 
 1641832826093)}
"""

獲取多版本數(shù)據(jù)

HBase 支持存儲(chǔ)同一單元的多個(gè)版本。這可以為每個(gè)列族配置。要檢索給定行的列的所有版本,可以使用 Table.cells()。此方法返回一個(gè)有序的單元格列表,最新版本排在最前面。版本參數(shù)指定要返回的最大版本數(shù)。就像檢索行的方法一樣,include_timestamp 參數(shù)確定時(shí)間戳是否包含在結(jié)果中。例子:

# 首先,準(zhǔn)備一個(gè)保存多版本的表
create 'tv', {NAME => 'info', VERSIONS => 5}
# 插入版本1
put 'tv', 'rk0001', 'info:name', 'hahaha'
# 插入版本2
put 'tv', 'rk0001', 'info:name', 'heiheihei'

# 檢查
hbase(main):024:0> scan 'tv'
ROW                          COLUMN+CELL                                                                       
 rk0001                      column=info:name, timestamp=1641836267655, value=heiheihei                        
1 row(s)
Took 0.0103 seconds
table = connection.table('tv')
# 獲取1個(gè)版本(默認(rèn)最新咯)
values = table.cells(b'rk0001', b'info:name', versions=1)
print(type(values))
print(values)

"""
返回值:
<class 'list'>
[b'heiheihei']
"""
# 獲取2個(gè)版本
values = table.cells(b'rk0001', b'info:name', versions=2)
print(type(values))
print(values)

"""
返回值:
<class 'list'>
[b'heiheihei', b'hahaha']
可見(jiàn),2個(gè)版本都獲取了,按照順序,第一個(gè)最新
"""

# 獲取多版本并附帶時(shí)間戳信息
values = table.cells(b'rk0001', b'info:name', versions=2, include_timestamp=True)
print(type(values))
print(values)

"""
返回值:
<class 'list'>
[(b'heiheihei', 1641836267655), (b'hahaha', 1641836263534)]
"""

0 分享到:
和我們?cè)诰€交談!