1

HBase数据表如何查询操作和获取多版本数据?

 11 months ago
source link: https://www.51cto.com/article/755878.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

HBase数据表如何查询操作和获取多版本数据?

作者:黑马程序员 2023-05-26 16:34:31
HBase数据模型是一个多维稀疏映射。 HBase中的表包含列族,其列限定符包含值和时间戳。在大多数 HappyBase API 中,列族和限定符名称被指定为单个字符串,例如cf1:col1,而不是作为两个单独的参数。

HBase数据模型是一个多维稀疏映射。 HBase中的表包含列族,其

d7f53e57213d97c876c51161d32f5653936d8a.jpg

列限定符包含值和时间戳。在大多数 HappyBase API 中,列族和限定符名称被指定为单个字符串,例如cf1:col1,而不是作为两个单独的参数。虽然列族和限定符在 HBase 数据模型中是不同的概念,但它们在与数据交互时几乎总是一起使用,因此将它们视为单个字符串会使 API 变得更简单。

Table 类提供了多种方法来从 HBase 中的表中检索数据。最基本的是 Table.row(),它从表中检索单行,并将其作为映射列到值的字典返回:

row = table.row(b'rk0001')
print(row[b'info:name'])   # prints the value of info:name
# 返回值:b'zhangsan',注意是二进制<class 'bytes'>类型
# 转换字符串:
print(str(row[b'info:name'], encoding="utf-8"))
# 即
str(bytes对象, encoding="编码格式,通常使用utf-8")

> 注意,库中的字符串都有前缀:b,表示二进制

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

> 返回值:

Table.rows() 方法的工作方式与 Table.row() 类似,但需要多个行键并将它们作为 (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对象
data是字典对象,字典中key和value都是bytes

如果您希望 Table.rows() 作为字典或有序字典返回的结果,您必须自己执行此操作。不过这真的很简单,因为返回值可以直接传递给字典构造函数。对于普通字典,顺序丢失:

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'}}
"""

而对于 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'})])
"""

进行更细粒度的查询

HBase 的数据模型允许对要检索的数据进行更细粒度的选择。如果您事先知道需要哪些列,则可以通过将这些列明确指定给 Table.row() 和 Table.rows() 来提高性能。 columns 参数采用列名的列表(或元组):

row = table.row(b'rk0001', columns=[b'info:name', b'data:pic'])
# row对象类型字典,内容:{b'data:pic': b'picture', b'info:name': b'zhangsan'}
print(row[b'info:name'])
print(row[b'data:pic'])

"""
返回值:bytes类型,需要的话自行转字符串
b'zhangsan'
b'picture'

如果检索一整个列族中的所有列(二级列)。例如,要获取列族 info中的所有列和值,请使用以下命令:

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'}
"""

基于时间戳查询

在 HBase 中,每个单元都有一个附加的时间戳。如果您不想使用存储在 HBase 中的最新版本数据,则可以使用从数据库中检索数据的方法,例如Table.row() 都接受一个时间戳参数,该参数指定结果应限制为时间戳不超过指定时间戳的值:

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

默认情况下,HappyBase 在返回的结果中不包含时间戳。在您的应用程序需要访问时间戳时,只需将 include_timestamp 参数设置为 True。现在,结果中的每个单元格都将作为(值,时间戳)元组返回,而不仅仅是一个值:

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)}
"""

获取多版本数据

HBase 支持存储同一单元的多个版本。这可以为每个列族配置。要检索给定行的列的所有版本,可以使用 Table.cells()。此方法返回一个有序的单元格列表,最新版本排在最前面。版本参数指定要返回的最大版本数。就像检索行的方法一样,include_timestamp 参数确定时间戳是否包含在结果中。例子:

# 首先,准备一个保存多版本的表
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个版本(默认最新咯)
values = table.cells(b'rk0001', b'info:name', versions=1)
print(type(values))
print(values)

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

"""
返回值:
<class 'list'>
[b'heiheihei', b'hahaha']
可见,2个版本都获取了,按照顺序,第一个最新
"""

# 获取多版本并附带时间戳信息
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)]
"""

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK