supiaopiao

HBase 是一个NoSQL数据库,用于处理海量数据,可以支持10亿行百万列的大表,下面我就和大家分享一下数据是如何存放在HBase表中的

为了更好的理解HBase表的思路,先回顾一下关系数据库中表的处理方式

 

①关系型数据库的表结构

例如有一个用户表user_info,有字段:id、name、tel,表名和字段需要在建表时指定

create table user_info (

    id 类型,

    name 类型,

    tel 类型

   )

然后插入两条数据

insert into user_info values(...)

表结构如下:

id name tel
1 苏静 13910111111
2 王荣荣

13245555555

 

后来字段不够用了,用户需要添加地址,就要新增一个字段,如下:

id name tel address
1 苏静 13910111111 ...
2 王荣荣 13245555555 ...

 

以后再增加需求时,就需要继续新增字段。

上面的内容主要说明的是:

  • 建表的方式,需提前指定表名和字段
  • 插入记录的方式,指定表名和各字段的值
  • 数据表是二维结构,行和列
  • 添加字段不灵活

 

下面看一下HBase的处理方式

②HBase的表结构

建表时要指定的是:表名、列族

建表语句:create \'user_info\', \'base_info\', \'ext_info\'

意思是新建一个表,名称是user_info,包含两个列族base_info和ext_info

列族 是列的集合,一个列族中包含多个列

这时的表结构:

row key(行键) base_info(列族) ext_info(列族)
... ... ...

 

row key 是行键,每一行的ID,这个字段是自动创建的,建表时不需要指定,也不需要创建

插入一条用户数据:name为‘a’,tel为‘123’

插入语句

put \'user_info\', \'row1\', \'base_info:name\', \'a\'

put \'user_info\', \'row1\', \'base_info:tel\', \'123\'

意思是向user_info表中行健为row1的base_info列族中添加一项数据 name:a,接着又添加一项数据tel:123

name和tel就是具体字段,属于base_info这个列族

 

这时的表结构:

row key(行键) base_info(列族) ext_info(列族)
row1 name:a, tel:123  

再插入一条数据:name为‘b’,addr为‘beijing’

put \'user_info\', \'row2\', \'base_info:name\', \'b\'

put \'user_info\', \'row2\', \'ext_info:addr\', \'bj\'

 

这时的表结构:

row key(行键) base_info(列族) ext_info(列族)
row1 name:a, tel:123  
row2 name:b addr:bj

 

 

HBase表中还有一个重要概念:版本,每个字段的值都有版本信息(通过时间戳指定)

例如 base_info:name,每次修改时都会保留之前的值,就是说可以取到他的旧值

row key base_info ext_info
row1 name:a, tel:123  
row2 name:c(v2)[name:b(v1)] addr:bj

 

小结

从上面建表、插入数据的过程可以看出 HBase 存储数据的特点了

  • 和关系数据库一样,也是使用行和列的结构
  • 建表时,定义的是表名和列族(字段的集合),而不是具体字段
  • 列族中可以包含任意个字段,字段名不需要预定义,每一行中同一列族中的字段也可以不一致
  • 多维结构,关系数据库的表是二维的,通过指行、列定位一个数据,HBase中需要通过 行健、列族名、字段名、版本号才能定位到具体数据
  • 插入数据时,一次插入一个字段的数据,不是像关系数据库那样一次插入多个字段

 

 

下面给出一些语句仅供参考:

创建user表,包含infodata两个列族

create \'user\', \'info1\', \'data1\'

create \'user\', {NAME => \'info\', VERSIONS => \'3\'}

 

user表中插入信息,row keyrk0001,列族info中添加name列标示符,值为zhangsan

put \'user\', \'rk0001\', \'info:name\', \'zhangsan\'

 

user表中插入信息,row keyrk0001,列族info中添加gender列标示符,值为female

put \'user\', \'rk0001\', \'info:gender\', \'female\'

 

user表中插入信息,row keyrk0001,列族info中添加age列标示符,值为20

put \'user\', \'rk0001\', \'info:age\', 20

 

user表中插入信息,row keyrk0001,列族data中添加pic列标示符,值为picture

put \'user\', \'rk0001\', \'data:pic\', \'picture\'

 

获取user表中row keyrk0001的所有信息

get \'user\', \'rk0001\'

 

获取user表中row keyrk0001info列族的所有信息

get \'user\', \'rk0001\', \'info\'

 

获取user表中row keyrk0001info列族的nameage列标示符的信息

get \'user\', \'rk0001\', \'info:name\', \'info:age\'

 

获取user表中row keyrk0001infodata列族的信息

get \'user\', \'rk0001\', \'info\', \'data\'

get \'user\', \'rk0001\', {COLUMN => [\'info\', \'data\']}

 

get \'user\', \'rk0001\', {COLUMN => [\'info:name\', \'data:pic\']}

 

获取user表中row keyrk0001,列族为info,版本号最新5个的信息

get \'people\', \'rk0002\', {COLUMN => \'info\', VERSIONS => 2}

get \'user\', \'rk0001\', {COLUMN => \'info:name\', VERSIONS => 5}

get \'user\', \'rk0001\', {COLUMN => \'info:name\', VERSIONS => 5, TIMERANGE => [1392368783980, 1392380169184]}

 

获取user表中row keyrk0001cell的值为zhangsan的信息

get \'people\', \'rk0001\', {FILTER => "ValueFilter(=, \'binary:图片\')"}

 

获取user表中row keyrk0001,列标示符中含有a的信息

get \'people\', \'rk0001\', {FILTER => "(QualifierFilter(=,\'substring:a\'))"}

 

put \'user\', \'rk0002\', \'info:name\', \'fanbingbing\'

put \'user\', \'rk0002\', \'info:gender\', \'female\'

put \'user\', \'rk0002\', \'info:nationality\', \'中国\'

get \'user\', \'rk0002\', {FILTER => "ValueFilter(=, \'binary:中国\')"}

 

查询user表中的所有信息

scan \'user\'

 

查询user表中列族为info的信息

scan \'people\', {COLUMNS => \'info\'}

scan \'user\', {COLUMNS => \'info\', RAW => true, VERSIONS => 5}

scan \'persion\', {COLUMNS => \'info\', RAW => true, VERSIONS => 3}

查询user表中列族为infodata的信息

scan \'user\', {COLUMNS => [\'info\', \'data\']}

scan \'user\', {COLUMNS => [\'info:name\', \'data:pic\']}

 

查询user表中列族为info、列标示符为name的信息

scan \'user\', {COLUMNS => \'info:name\'}

 

查询user表中列族为info、列标示符为name的信息,并且版本最新的5

scan \'user\', {COLUMNS => \'info:name\', VERSIONS => 5}

 

查询user表中列族为infodata且列标示符中含有a字符的信息

scan \'people\', {COLUMNS => [\'info\', \'data\'], FILTER => "(QualifierFilter(=,\'substring:a\'))"}

 

查询user表中列族为infork范围是[rk0001, rk0003)的数据

scan \'people\', {COLUMNS => \'info\', STARTROW => \'rk0001\', ENDROW => \'rk0003\'}

 

查询user表中row keyrk字符开头的

scan \'user\',{FILTER=>"PrefixFilter(\'rk\')"}

 

查询user表中指定范围的数据

scan \'user\', {TIMERANGE => [1392368783980, 1392380169184]}

 

禁用表

disable \'user\' 将数据表设置为失效

 

删除表

drop \'t_user\' 删除数据表 删除前必须使其失效

 

启用表

enable \'t_user\' 将数据表设置为有效

 

查看表结构

desc \'t_user\' 查看数据表结构

 

删除userrow keyrk0001,列标示符为info:name的数据

delete \'people\', \'rk0001\', \'info:name\'

删除userrow keyrk0001,列标示符为info:nametimestamp1392383705316的数据

delete \'user\', \'rk0001\', \'info:name\', 1392383705316

 

清空user表中的数据

truncate \'people\'

 

如果您认为这篇文章还不错或者有所收获,您可以通过右边的“打赏”功能 打赏我一杯咖啡【物质支持】,也可以点击下方的【好文要顶】按钮【精神支持】,因为这两种支持都是使我继续写作、分享的最大动力!

分类:

技术点:

相关文章: