SQL 中,我们对命令的划分如下:
(1)DDL 建库建表
(2)DML 增删改
(3)DQL 查询
(4)QCL 权限管理
简写规律:
(1)ns: Namespace
(2)t1 : Table
(3)f1 : ColumnFamily
(4)r1 : Rowkey
(5)c1 : 列
(5)ts : timestamp
一. DDL 操作
命令空间管理
-
list_namespace
功能:列举hbase所有的命名空间;类比 mysql 中的 show databases;
hbase(main):061:0> list_namespace NAMESPACE default hbase qx 3 row(s) Took 0.0274 seconds
-
list_namespace_tables 'hbase'
功能:查看某个数据库中有哪些表;类比 mysql 中的 show tables in dbname;
语法:
list_namespace_tables '命名空间的名称'
栗子:
list_namespace_tables 'qx'
-
create_namespace ’Namespace的名称’ ,类比 mysql 中的 create database ‘数据库的名称’
语法:
create_namespace '命名空间的名称'
栗子:
create_namespace 'qx'
-
drop_namespace ‘Namespace的名称’
功能:删除 namespace;类比 mysql 中的 drop database 。
注意:
(1)hbase在有表的情况下则不能直接删除,必须先删除表。
(2)mysql 可以加上 cascade 直接删除有表的数据库
语法:
drop_namespace '命名空间的名称'
栗子:
drop_namespace 'qx'
表的管理
-
list 列举所有的表
功能:
(1)单独使用,不分命名空间,列举所有命名空间下的表(不包含系统表)
(2)如果需要列举某个命令空间下所有的表,用 list_namespace_tables
语法:
list_namespace_tables '命名空间的名称'
栗子:
list_namespace_tables 'hbase'
-
create 创建表
功能:创建表,类比 mysql 中 create table dbname.tbname(字段信息)
注意:必须指定表名,和至少一个列族
语法:
create '表名','列族'
栗子:
create 'qx:t2','cf1',{NAME=>'cf3',VERSIONS=>2}
-
drop 删除表
功能:删除表
注意:删除表之前,需要保证该表为 disable 状态,如果不是,需要先将表的状态改成 disable 方可执行 drop 命令,否则会报错
语法:
#(1)禁用表 disable ‘表名’ #(2)启用表 enable ‘表名’ #(3)删除表 drop ‘表名’
-
exists
功能:判断表是否存在
语法:
exists '表名'
栗子:
exists 'quxuan:t1'
-
alter 可以对表进行修改
如增加列族等。一般用不到。
二. DML 操作
首先准备数据,我们指定表名为 ‘qx:t2’,并且该表有两个列族 cf1 和 cf3 ,cf1 只能存1个版本的值,cf3可以存2个版本的值。
注意:Hbase 最小操作单元为:列。
#建表
create 'qx:t2','cf1',{NAME=>'cf3',VERSIONS=>2}
#查看表结构
hbase(main):068:0> desc 'qx:t2'
Table qx:t2 is ENABLED
qx:t2
COLUMN FAMILIES DESCRIPTION
{NAME => 'cf1', VERSIONS => '1', EVICT_BLOCKS_ON_CLOSE => 'false', NEW_VERSION_BEHAVIOR =>
'false', KEEP_DELETED_CELLS => 'FALSE', CACHE_DATA_ON_WRITE => 'false', DATA_BLOCK_ENCODI
NG => 'NONE', TTL => 'FOREVER', MIN_VERSIONS => '0', REPLICATION_SCOPE => '0', BLOOMFILTER
=> 'ROW', CACHE_INDEX_ON_WRITE => 'false', IN_MEMORY => 'false', CACHE_BLOOMS_ON_WRITE =>
'false', PREFETCH_BLOCKS_ON_OPEN => 'false', COMPRESSION => 'NONE', BLOCKCACHE => 'true',
BLOCKSIZE => '65536'}
{NAME => 'cf3', VERSIONS => '2', EVICT_BLOCKS_ON_CLOSE => 'false', NEW_VERSION_BEHAVIOR =>
'false', KEEP_DELETED_CELLS => 'FALSE', CACHE_DATA_ON_WRITE => 'false', DATA_BLOCK_ENCODI
NG => 'NONE', TTL => 'FOREVER', MIN_VERSIONS => '0', REPLICATION_SCOPE => '0', BLOOMFILTER
=> 'ROW', CACHE_INDEX_ON_WRITE => 'false', IN_MEMORY => 'false', CACHE_BLOOMS_ON_WRITE =>
'false', PREFETCH_BLOCKS_ON_OPEN => 'false', COMPRESSION => 'NONE', BLOCKCACHE => 'true',
BLOCKSIZE => '65536'}
2 row(s)
-
put 命令
功能:插入/更新数据【某一行的某一列】
语法:
put '表名','rowkey','列族:列','值'
栗子:
#插入/更新数据 hbase(main):037:0> put 'qx:t2','20220101_000','cf3:address','guangzhou' Took 0.0238 seconds
其中, 20220101_000 是我们的 rowkey. rowkey 由我们来指定。
-
scan 命令
功能:查看 hbase 中某个表的内容
注意:
(1)每个列族默认只存一个版本的值,
(2)若建表时指定了列族的最多可存版本数 VERSIONS 并且大于1,则可以存多个版本的值。查看时,可用 scan 命令并指定版本数来显示。语法:
(1)scan '表名' (2)scan '表名',{Filter}
栗子:
#查看 hbase 中某个表的内容,等同于 select * (1)scan 'qx:t2' //一般不用 #根据条件查询,工作中主要使用的场景,LIMIT/COLUMN/FILTER (2)scan 'qx:t2',{Filter} //用得最多 eg:scan 't1',{FORMATTER => 'toString'} # 需求一:查询表的内容,并指定显示的版本数 # 语法:scan ‘ns:t1’,{VERSIONS=>版本数} # 栗子: hbase(main):039:0> scan 'qx:t2',{VERSIONS=>10} ROW COLUMN+CELL 20220101_000 column=cf1:age, timestamp=1661356585777, value=18 20220101_000 column=cf1:name, timestamp=1661355516410, value=laoshi 20220101_000 column=cf3:address, timestamp=1661357607820, value=guangzhou 20220101_000 column=cf3:address, timestamp=1661356783147, value=yilake # 小结:通过指定VERSIONS, 能查看到cf3:address 有两个版本的Value,时间戳不同并按降序排序 # 如果该列只能存1个版本,当该列的值被修改了,用上面的命令,如是无法显示多个版本的值。对用户而言,age 旧值会直接被新值覆盖掉。如下: hbase(main):081:0> scan 'qx:t2',{VERSIONS=>10} ROW COLUMN+CELL 20220101_000 column=cf1:age, timestamp=1661417042528, value=19 20220101_000 column=cf1:name, timestamp=1661416363446, value=laoshi 20220101_000 column=cf3:address, timestamp=1661416398782, value=yilake 20220101_000 column=cf3:address, timestamp=1661416384608, value=guangzhou # 需求二: # 问题:只能存1个版本的列对应的值如果发生修改,如何查询修改前的数据(过期的数据)呢? # 语法:scan 'ns:t1',{VERSIONS=>10,RAW=>TRUE} , # 功能:查看过期的数据 (2)hbase(main):082:0> scan 'qx:t2',{VERSIONS=>10,RAW=>TRUE} ROW COLUMN+CELL 20220101_000 column=cf1:age, timestamp=1661417042528, value=19 20220101_000 column=cf1:age, timestamp=1661416332056, value=18 20220101_000 column=cf1:name, timestamp=1661416363446, value=laoshi 20220101_000 column=cf3:address, timestamp=1661416398782, value=yilake 20220101_000 column=cf3:address, timestamp=1661416384608, value=guangzhou #问题: #(1)我们明明设置了cf1列族的多版本的值为1,为什么它被修改前的值依然能查到? #答:hbase 没有物理更新和删除:通过插入来代替的。实现了逻辑更新和删除,根据版本的限制做了标记不再显示。严格来讲,hbase 只支持追加,不支持修改和删除。换言之,put 命令严格来讲,只是插入操作。 #(2)hbase 为什么要这么做呢? #答:为了加快性能。【如果不对数据打标记,而是到物理层把数据删掉或者更改(会有内存寻址等一系列操作),性能反而大打折扣。】而对数据打了标记,后面根据版本的限制,如果这条数据是标记已删除的,则不会返回该数据。 # 我们新增两条 2021 开头的数据,如下: hbase(main):083:0> put 'qx:t2','20210101_000','cf1:name','laoer' Took 0.0154 seconds hbase(main):084:0> put 'qx:t2','20210101_001','cf1:age',15 Took 0.0250 seconds hbase(main):085:0> scan 'qx:t2' ROW COLUMN+CELL 20210101_000 column=cf1:name, timestamp=1661417418140, value=laoer 20210101_001 column=cf1:age, timestamp=1661417435489, value=15 20220101_000 column=cf1:age, timestamp=1661417042528, value=19 20220101_000 column=cf1:name, timestamp=1661416363446, value=laoshi 20220101_000 column=cf3:address, timestamp=1661416398782, value=yilake # 需求三:我们怎么查询 rowkey 以 2021 开头数据呢? # 语法:ROWPREFIXFILTER hbase(main):087:0> scan 'qx:t2',{ROWPREFIXFILTER=>'2021'} ROW COLUMN+CELL 20210101_000 column=cf1:name, timestamp=1661417418140, value=laoer 20210101_001 column=cf1:age, timestamp=1661417435489, value=15 2 row(s) Took 0.0181 seconds # 需求三:怎么查询某个范围的数据?(以 rowkey为索引) # 语法:STARTROW,STOPROW # 栗子一:(查以某个时间开始,往后的数据) hbase(main):092:0> scan 'qx:t2',{STARTROW=>'20220101'} ROW COLUMN+CELL 20220101_000 column=cf1:age, timestamp=1661417042528, value=19 20220101_000 column=cf1:name, timestamp=1661416363446, value=laoshi 20220101_000 column=cf3:address, timestamp=1661416398782, value=yilake 1 row(s) Took 0.0103 seconds # 栗子二:(查以某个时间开始,以某个时间结束,中间的数据,前闭后开区间) hbase(main):090:0> put 'qx:t2','20210901_001','cf1:name','laosan' Took 0.0432 seconds hbase(main):093:0> scan 'qx:t2',{STARTROW=>'20210101',STOPROW=>'20211231'} ROW COLUMN+CELL 20210101_000 column=cf1:name, timestamp=1661417418140, value=laoer 20210101_001 column=cf1:age, timestamp=1661417435489, value=15 20210901_001 column=cf1:name, timestamp=1661420407755, value=laosan 3 row(s) Took 0.0429 seconds # 栗子三:查询前几条数据,LIMIT hbase(main):096:0> scan 'qx:t2',{LIMIT=>2} ROW COLUMN+CELL 20210101_000 column=cf1:name, timestamp=1661417418140, value=laoer 20210101_001 column=cf1:age, timestamp=1661417435489, value=15 2 row(s) Took 0.0571 seconds
小结:在 Hbase 数据检索,尽量走索引查询:按照 Rowkey 前缀条件查询
· 尽量避免走全表扫描
· Hbase 所有 Rowkey 的查询都是前缀匹配,只有按照前缀匹配才走索引
· 表的设计:日期_ID
· 按照日期查询:走
· 按照 ID 查询:不走
-
get 命令
功能:读取某个 Rowkey 的数据
(1)缺点:get 命令最多只能返回一个 rowkey 的数据,根据 rowkey 进行检索数据;当查询条件不是rowkey的时候,就不是根据索引检索数据了。只能全盘扫描。
(2)优点:get 是 Hbase 中查询数据最快的方式,并不是最常用的方式
(3)应用:前提是知道要查询的 rowkey 的值语法:
(1)get '表名','rowkey’ (2)get '表名','rowkey','列族' (3)get '表名','rowkey','列族:列'
栗子:
#查看表所有内容 hbase(main):003:0> scan 'qx:t2' ROW COLUMN+CELL 20210102_000 column=cf3:age, timestamp=1661360151820, value=99 20220101_000 column=cf1:age, timestamp=1661358881140, value=19 20220101_000 column=cf1:name, timestamp=1661355516410, value=laoshi 20220101_000 column=cf3:address, timestamp=1661357607820, value=guangzhou 20220201_001 column=cf1:addr, timestamp=1661357090889, value=shanghai 20220201_001 column=cf1:age, timestamp=1661357064495, value=18 20220201_001 column=cf1:name, timestamp=1661356986190, value=laoda 20220201_001 column=cf1:phone, timestamp=1661357076362, value=110 20220201_001 column=cf3:addr, timestamp=1661357143741, value=beijing 20220201_001 column=cf3:name, timestamp=1661357123015, value=laoda 20220201_001 column=cf3:sex, timestamp=1661357174760, value=male 3 row(s) Took 0.4090 seconds #必须指定 'ns:t1','rowkey'【查询某个rowkey所有的keyvalue】 hbase(main):004:0> get 'qx:t2','20210102_000' COLUMN CELL cf3:age timestamp=1661360151820, value=99 1 row(s) Took 0.1248 seconds #(2)可以同时指定 'ns:t1','rowkey','cf1'【查询某个rowkey中某个列族下的keyvalue】 hbase(main):005:0> get 'qx:t2','20220101_000','cf1' COLUMN CELL cf1:age timestamp=1661358881140, value=19 cf1:name timestamp=1661355516410, value=laoshi 1 row(s) Took 2.0784 seconds #(3)可以同时指定 'ns:t1','rowkey','cf1:c1' 【查询某个rowkey中某个列族下的某一列】 hbase(main):006:0> get 'qx:t2','20220101_000','cf1:name' COLUMN CELL cf1:name timestamp=1661355516410, value=laoshi 1 row(s) Took 0.0778 seconds
-
delete
功能:删除Hbase中的数据
语法:
(1)delete '表名',‘rowkey’,'列族:列' (2)deleteall '表名','rowkey' (3)truncate '表名'
示例:
#删除某列的数据 hbase(main):007:0> delete 'qx:t2','20220101_000','cf1:age' Took 0.5117 seconds #删除某个rowkey的数据 hbase(main):009:0> deleteall 'qx:t2','20220201_001' Took 0.1354 seconds #清空所有数据,生产环境不建议使用,有问题,建议删表重建 hbase(main):011:0> truncate 'qx:t2' Truncating 'qx:t2' table (it may take a while): Disabling table... Truncating table... Took 9.6237 seconds
-
count 统计命令
功能:统计某张表的行数【rowkey的个数】
语法:
count '表名'
示例:
count 'qx:t2'
-
incr
功能:一般用于自动计数的,不用记住上一次的值,直接做自增
· 需求:一般用于做数据的计数
· 与 Put 区别:put 需要记住上一次的值是什么,incr 不需要知道上一次的值是什么,自动计数
语法:
(1)incr '表名','rowkey','列族:列' (2)get_counter '表名','rowkey','列族:列'
示例:
hbase(main):008:0> incr 'NEWS_VISIT_CNT','20210101_001','c1:CNT',12 COUNTER VALUE = 12 Took 0.2801 seconds hbase(main):012:0> incr 'NEWS_VISIT_CNT','20210101_001','c1:CNT' COUNTER VALUE = 13 Took 0.0666 seconds
三. 观察下面表中的数据
#查看表所有内容
hbase(main):045:0> scan 'qx:t2'
ROW COLUMN+CELL
20210102_000 column=cf3:age, timestamp=1661360151820, value=99
20220101_000 column=cf1:age, timestamp=1661358881140, value=19
20220101_000 column=cf1:name, timestamp=1661355516410, value=laoshi
20220101_000 column=cf3:address, timestamp=1661357607820, value=guangzhou
20220201_001 column=cf1:addr, timestamp=1661357090889, value=shanghai
20220201_001 column=cf1:age, timestamp=1661357064495, value=18
20220201_001 column=cf1:name, timestamp=1661356986190, value=laoda
20220201_001 column=cf1:phone, timestamp=1661357076362, value=110
20220201_001 column=cf3:addr, timestamp=1661357143741, value=beijing
20220201_001 column=cf3:name, timestamp=1661357123015, value=laoda
20220201_001 column=cf3:sex, timestamp=1661357174760, value=male
规律:
(1)观察Hbase 表会自动按照底层的 key 构建字典有序:逐位比较
先比较 rowkey,如果rowkey相同,再比较列族;如果列族相同,再比较列名;如果列名相同,再比较时间戳。
(2)rowkey、列族、列名 按 升序 排序;时间戳按 降序 排序。
设计目标:**为什么要构建排序:**加快数据的查询。
小结:
-
Hbase集群管理
(1)启动:start-dfs.sh / start-zk.sh / start-hbase.sh
(2)监控:HMaster : 16010
(3)关闭:stop-hbase.sh / stop-zk.sh / stop-dfs.sh -
Hbase Shell 命令行
DDL: list_namespace、create_namespace、drop_namespace、list、create 'ns:tbname'、列族、drop、exists
DML:put
(1)put 的使用;
(2)功能:为表中的某一行添加某一列,如果存在就更新,不存在就插入;
(3)语法:put 'ns:tbname','rowkey','cf:col','value'
网友评论