HBase数据模型是一个多维稀疏映射。 HBase中的表包含列族,其
列限定符包含值和时间戳。在大多数 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",注意是二进制类型# 转换字符串: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 OrderedDictrows_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)"""返回值:{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)"""返回值:{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}# 插入版本1put "tv", "rk0001", "info:name", "hahaha"# 插入版本2put "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)"""返回值:[b"heiheihei"]"""# 获取2个版本values = table.cells(b"rk0001", b"info:name", versions=2)print(type(values))print(values)"""返回值:[b"heiheihei", b"hahaha"]可见,2个版本都获取了,按照顺序,第一个最新"""# 获取多版本并附带时间戳信息values = table.cells(b"rk0001", b"info:name", versions=2, include_timestamp=True)print(type(values))print(values)"""返回值:[(b"heiheihei", 1641836267655), (b"hahaha", 1641836263534)]"""