Hbase学习

HBase 是一种非关系型数据库,它不要求数据之间有严格的关系,同时它允许在同一列不同行中存储不同类型的数据。

HBase 采用列式存储或者说是面向列的数据库,在表中它由行排序。HBase 是根据列族来存储数据的。列族下面可以有非常多的列,列族在创建表的时候就必须指定。一个表有多个列族,每一个列族可以有任意数量的列。后续列的值连续存储在磁盘上。表中的每个单元格值都具有时间戳。

总之,在一个 HBase 中:

  • 表是行的集合;
  • 行是列族的集合;
  • 列族是列的集合;
  • 列是键值对的集合。

传统数据库像是一个有着严格格式的 Excel 表格,而 HBase 更像是一个巨大、稀疏、多维的"键值对(Key-Value)"字典

概念理解

HBase 的表(Table)由许多行组成,每一行都有一个全局唯一的行键(RowKey) 。HBase 最大的特点之一是数据按 RowKey 的字典顺序自动排序

比如我们有三个用户,就是三行,行键分别是 user_001, user_002, user_003。这三行数据构成了这张表,然后按照字典顺序排序 user_001, user_002, user_003在底层存储时,user_001 紧挨着 user_002

行键 (RowKey) 列族:BaseInfo (基础信息)
user_001
user_002
user_003

具体到某一行 (比如 user_001),它里面包含的并不是直接的列,而是列族。比如user_001 这一行里,包含了 BaseInfoActionLog 这两个列族,分别代表基本信息和日志

然后一个列族包含多个列 ,同一列族数据在硬盘中连续存储,每一列是一个键值对,并通过时间戳保留多个版本,比如表中的T1,T2

行键 (RowKey) 列族:BaseInfo (基础信息) 列族:ActionLog (行为日志)
user_001 name = "张三" (T1) age = "27" (T3) age = "26" (T2) login_time = "2026-03-26" (T1) click_item = "手机" (T2)

综合来看就是这样:

行键 (RowKey) 列族:BaseInfo (基础信息) 列族:ActionLog (行为日志)
user_001 name = "张三" (T1) age = "27" (T2) age = "26" (T1) login_time = "2026-03-26" (T1) click_item = "手机" (T2)
user_002 name = "李四" (T1) email = "lisi@test.com" (T1) (空,不占用额外存储空间)
user_003 nickname = "王五" (T1) search_word = "HBase教程" (T1)

你也许注意到了,对于这三个用户,其列族的列可以是完全不同的,这和我们常见的关系型数据库是最大的不同点,比如mysql,一个用户是一行,那么不同用户属性值的集合应当完全一样,一张表的每个列所有用户都有,但是对于列族数据库来说,一张表的不同用户完全可以有不同的属性值。

我们再来拿常见的商品表并结合操作代码来讲解一下Hbase,不同的商品会有不同的属性,比如食品有保质期,手机有颜色型号等,非常适合用列族数据库存储。

商品库

使用**商品库(Product)**的例子,建表时有两个列族:BaseInfo(基础信息)和 Attr(动态属性),商品的行键(RowKey)是 SKU_1001

在操作数据前,我们需要先建表和列族。在 HBase 控制台里,建表只需要指定表名和列族名即可,不需要定义具体的列。

Ruby 复制代码
hbase(main):001:0> create 'Product', 'BaseInfo', 'Attr'
0 row(s) in 1.2340 seconds

即创建一个Product表,有BaseInfo和Attr两个列族

增:上架新商品 (Put)

场景: 录入 SKU_1001 的名称、品牌和首发价格。

操作时刻: T1

在 Shell 中,put 命令的语法是:put '表名', 'RowKey', '列族:列名', '值'

Shell 命令:

Ruby 复制代码
hbase(main):002:0> put 'Product', 'SKU_1001', 'BaseInfo:name', 'iPhone 15 Pro'
hbase(main):003:0> put 'Product', 'SKU_1001', 'BaseInfo:brand', 'Apple'
hbase(main):004:0> put 'Product', 'SKU_1001', 'Attr:price', '7999'

执行后,HBase 底层的逻辑视图:

行键 (RowKey) 列族:BaseInfo (基础信息) 列族:Attr (动态属性)
SKU_1001 name = "iPhone 15 Pro" (T1) brand = "Apple" (T1) price = "7999" (T1)

改:降价与动态增加属性 (Put)

场景: 双十一降价,并且新增"颜色"和"赠品"属性。

操作时刻: T2

HBase 没有 update 命令,修改和新增字段都是继续使用 put 进行追加。

Shell 命令:

Ruby 复制代码
# 覆盖旧价格(追加新版本)
hbase(main):005:0> put 'Product', 'SKU_1001', 'Attr:price', '7499'
# 动态新增原本不存在的列
hbase(main):006:0> put 'Product', 'SKU_1001', 'Attr:color', 'Titanium Blue'
hbase(main):007:0> put 'Product', 'SKU_1001', 'Attr:gift', 'AirPods'

执行后,HBase 底层的逻辑视图变为了:

行键 (RowKey) 列族:BaseInfo (基础信息) 列族:Attr (动态属性)
SKU_1001 name = "iPhone 15 Pro" (T1) brand = "Apple" (T1) price = "7499" (T2) color = "Titanium Blue" (T2) gift = "AirPods" (T2) price = "7999" (T1)

查:读取商品信息 (Get)

场景: 查看 SKU_1001 这个商品的最新全部信息。

操作时刻: 随时

使用 get 命令可以获取指定 RowKey 的数据。默认情况下,Shell 会打印出该行所有列的最新版本数据。

Shell 命令:

Ruby 复制代码
hbase(main):008:0> get 'Product', 'SKU_1001'

COLUMN                     CELL
 Attr:color                timestamp=1711540000000, value=Titanium Blue
 Attr:gift                 timestamp=1711540000000, value=AirPods
 Attr:price                timestamp=1711540000000, value=7499
 BaseInfo:brand            timestamp=1711530000000, value=Apple
 BaseInfo:name             timestamp=1711530000000, value=iPhone 15 Pro

(注意看控制台的输出,HBase 自动按列名的字典顺序排好了,并且展示了每条数据的实际数字时间戳。这里返回的价格是 7499,旧的 7999 被隐藏了。)


删:活动结束,移除赠品属性 (Delete)

场景: 撤掉"赠品"这个属性。

操作时刻: T3

语法是:delete '表名', 'RowKey', '列族:列名'。(如果想删除整行数据,可以使用 deleteall '表名', 'RowKey')。

Shell 命令:

Ruby 复制代码
hbase(main):009:0> delete 'Product', 'SKU_1001', 'Attr:gift'

执行 Delete 操作后,HBase 底层的逻辑视图:

行键 (RowKey) 列族:BaseInfo (基础信息) 列族:Attr (动态属性)
SKU_1001 name = "iPhone 15 Pro" (T1) brand = "Apple" (T1) gift = [Tombstone 墓碑标记] (T3) price = "7499" (T2) color = "Titanium Blue" (T2) gift = "AirPods" (T2) price = "7999" (T1)

此时如果你再次执行 get 'Product', 'SKU_1001',你会发现输出的结果中,Attr:gift 这一行彻底消失了。

相关推荐
Engineer邓祥浩13 小时前
JVM学习笔记(9) 第三部分 虚拟机执行子系统 第8章 虚拟机字节码执行引擎
jvm·笔记·学习
xuhaoyu_cpp_java13 小时前
MySql学习(三)
经验分享·笔记·学习·mysql
鱼鳞_13 小时前
Java学习笔记_Day31(IO流)
java·笔记·学习
red_redemption13 小时前
自由学习记录(162)
学习
马士兵教育13 小时前
AI工作岗位的就业分层?
开发语言·人工智能·学习·面试·职场和发展
weixin_4434785113 小时前
Flutter学习之第三方组件:视频播放器控件
学习·flutter·音视频
徒 花13 小时前
HCIP学习16 RIP 与 OSPF 路由重分布综合实验
网络·学习·智能路由器·hcip·ensp
landuochong20013 小时前
智能体闭环进展:从学习、记忆、决策到执行
人工智能·学习·claudecode
map1e_zjc14 小时前
Java SpringBoot学习记录(4)
java·开发语言·学习
xian_wwq14 小时前
【学习笔记】3 种零防御 UAC 绕过技术
笔记·学习