hbase数据模型
在hbase中,数据是以表格的方式存储,这个看起来是跟关系型数据库一致,但其实并不是。它其实看起来更像是多维度的map。(传统关系型数据库是行式的数据库,而hbase是列式,这里不详谈)。
hbase其实应该是一种key-value的数据库,与mongo和redis等key-value相比,它的key有很多组成部分,表行列(列族、列标识符)版本(时间戳方式)等等
hbase的数据模型有以下概念:
- namespace(名字空间);类似于关系型数据库的database
- Table(表):就像传统的表一样,包含着多个行的
- Row(行):hbase的行包含着行的key和一个或多个带着值的列的。行是以key排好序进行存储的。一般是以domain反转方式命名(以便同一公司的数据可以放在同一块区域)。这里需要讲一下,hbase本身的索引(即一级索引)有且只有行键这一个,所以行健的命名及其关键,后面开发同事与运维同事应该要注意这一点。二级索引现在行内有一些解决方案,开发运维同事也可以跟进一下,选择合适的。
- Column(列):hbase的列实际上是由两部分组成的,列族与列标识符
- 列族,列族是列的组成部分之一,一个表的所有列应该有同样的列族们(这个在建表的时候指定)。列族可以设置一些限制之类的。
- 列标识符,列族与列标识符由:连接形成一个列的key
- cell(单元格),单元格结合以上的key还有一个值以及一个时间戳组成,时间戳用来表示版本号
- timestamp(时间戳),时间戳是伴随着值得写入而形成,它可以用来定位一个给定版本的值。默认的时间戳在写入的时候hbase提供,也可以手动传入一个。
ps. rowkey官方文档上写domain反转,但我查阅了其他资料,一般并不是,rowkey最好不要连续,以免连续对同一个redion进行读写操作,影响性能。可以在前缀加上hash,然后就能分布到不同的节点了,我们也能根据这个hash值知道在哪个节点查询。既能保证读写分散,也能够有效读取。
hbase的数据模型概念视图
给出一张表和对应的map视图来理解吧。
Row Key | Time Stamp | ColumnFamily contents | ColumnFamily anchor | ColumnFamily people |
---|---|---|---|---|
"com.cnn.www" | t9 | anchor:cnnsi.com="CNN" | ||
"com.cnn.www" | t8 | anchor:cnnsi.com="CNN.com" | ||
"com.cnn.www" | t6 | contents:html="..." | ||
"com.cnn.www" | t5 | contents:html="..." | ||
"com.cnn.www" | t3 | contents:html="..." | ||
"com.example.www" | t5 | contents:html="..." | people:author="John Doe" |
对应的map可以表示如下:
{
"com.cnn.www": {
contents: {
t6: contents:html: "<html>..."
t5: contents:html: "<html>..."
t3: contents:html: "<html>..."
}
anchor: {
t9: anchor:cnnsi.com: "CNN"
t8: anchor:cnnsi.com: "CNN.com"
}
people: {}
}
"com.example.www": {
contents: {
t5: contents:html: "<html>..."
}
anchor: {}
people: {
t5: people:author: "John Doe"
}
}
}
hbase的数据模型物理视图
hbase是列式的数据库模型。它是以列族来存储的,尽管从概念视图中以行来分割。
hbase中空的单元格是不会被存储了,相比于rdbms型数据库,这就节省了很多空间。
hbase中用timestamp来记录版本号,如果不提供版本号,就选择最新的数据,如果对应的版本号不存在则不会返回值。
hbase的一些常用命令
- 建表 create , create后的语法很多,一般的用法就是 create '表名',’列族1‘,’列族2‘...。如果需要多些设置,可以把这些列族用{}包含,括号里面可以设置如name,versions等,还可以在最后加上splits => []
- 查看有哪些表 list, 不跟就列出所有表,跟表名就列出该表(或者空,即不存在)
- 禁用表,如果要修改表结构或者删除表的话,那么就需要对其禁用,命令是disable '表名'
- 查看表是否被禁用,is_disabled '表名'
- 正则方式禁用表 disable_all '正则表达式'
- 启用表,如果要重新使用一个被禁用的表,那么就要对其解禁,语法是enable '表名'
- 查看表是否可用 is_enable '表名'
- 产看表描述 describe '表名'
- 添加一个数据,put '表名','行健','列族:列标识符','值'
- 查看一个表,获取所有数据,scan ’表名' (可以添加些条件来限制返回数据,条件是{name=>value}形式,name有COLUMNS、LIMIT等)
- 获取数据,get '表','行key'(,'列族:列标识符')
- 删除表,drop '表', 只有表在disabled状态才能被删除
- 删除行、列、列族,delete后面接行、列。。。