HBase表设计
人员-角色
人员和角色,支持CRUD;人员有多个角色,角色也有多个人员(即多对多的关系);人员支持删除添加角色,角色支持添加删除人员
人员编号pid,例如 001, 002, 003
角色编号rid,例如 100, 200, 300
一张表存储
rowkey是pid_rid或rid_pid,例如 001_100, 001_200, 100_001, 100_00
这样设计,需要在每行中都保存用户和角色信息,数据冗余度很大(更新和删除操作时会很麻烦可能会涉及很多行,影响性能),且没法区分rowkey的前缀是pid还是rid(这可以通过添加前缀解决)
一张表存储相当于将两张表的数据用一张表存储,一般不会这么使用
两张表存储
人员表
| rowkey(pid) | cf1(属性信息) | cf2(角色列表) |
|---|---|---|
| 001 | cf1:name=小黑,cf1:age=18 | cf2:100=班长,cf2:200=小兵 |
| 002 | cf1:name=小黄,cf1:age=19 | cf2:200=小兵 |
角色表
| rowkey(rid) | cf1(角色信息) | cf2(人员列表) |
|---|---|---|
| 100 | cf1:name=班长 | cf2:001=小黑 |
| 200 | cf1:name=小兵 | cf2:001=小黑,cf2:002=小黄 |
两张表的rowkey都是其id,查询起来比较方便,每张表的cf1列族存储的都是基本信息,cf2列族存储的是关联数据的列表。可以使用一列存储关联列表,也可以使用多列存储关联列表,关联列表可以只存储id,也可以存储一些冗余信息。两张表的cf2列族(关联列表),需要同步更新。当查询关联列表的详细信息时,可以通过rowkey查询,速度是很快的。实际使用时一般会采用两张表存储
三张表存储
人员表 rowkey(pid) cf:(人员信息) 角色表 rowkey(rid) cf:(角色信息) 人员角色表 rowkey(random_id) cf1:(角色id) cf2:(人员id)
三张表存储就比较符合传统的关系型数据库的设计了,但是hbase中查询数据都是根据rowkey进行查询的(比较快),并不能关联查询,实际使用时不会采用这种方式
组织架构 部门-子部门
部门CRUD;部门,查询、添加、删除子部门;查询顶级部门;查询每个部门的所有子部门
001--CEO 002--开发部 003--开发1 004--开发2 005--市场部 006--市场1 007--市场2
一张表
| rowkey | cf1:(部门信息) | cf2:(子部门列表) |
|---|---|---|
| 0_001 | cf1:name=CEO | cf2:002=开发部,cf2:005=市场部 |
| 1_002 | cf1:name=开发部,cf1:pid=0_001 | cf2:003=开发1,cf2:004=开发2 |
rowkey设计成"前缀_id",前缀0表示顶级部门,前缀1表示非顶级部门,这样通过前缀0就可以查询出所有的顶级部门;cf2列族为子部门列表,可以用来查询一个部门的所有直接子部门;cf1列族为部门信息,除了存储部门基本信息外,还保存了父部门id(pid),当修改或删除部门时,可以通过pid修改父部门的子部门列表信息
微博表设计
添加删除关注、粉丝列表、写微博、查看某个用户发布的所有微博(降序排序)、查看首页所有关注过的好友发布的最新微博
001:小红 小黑 002:小黑 小红,小白 003:小白 小红,小黑
用户表
| rowkey(pid) | cf1:(基本信息) | cf2:(关注列表) | cf3:(粉丝列表) |
|---|---|---|---|
| 001 | cf1:name=小红 | cf2:002=小黑 | cf3:002=小黑,cf3:003=小白 |
| 002 | cf1:name=小黑 | cf2:001=小红,cf2:003=小白 | cf3:001=小红,cf3:003=小白 |
| 003 | cf1:name=小白 | cf2:001=小红,cf2:002=小黑 | cf3:002=小黑 |
用户表这样设计可以用于实现,用户的CRUD、查看粉丝列表、添加删除关注(需要同步更新粉丝列表)
微博表
| rowkey(wid) | cf:(微博信息) |
|---|---|
| pid_(long.max_value-timestamp) | cf:content=发微博,cf:title=标题 |
微博表的设计主要体现在rowkey上,rowkey以pid(用户id)为前缀,这样可以非常快速地过滤出指定用户的微博;后缀是long.max_value-timestamp,这样保证了每个用户的微博数据都是按照倒序排序的,查询用户的第一条微博数据即为最新的
微博收取表
| rowkey(pid) | cf:(所有关注人发布微博的排序)version=10000 |
|---|---|
| pid | cf:sq=wid3 cf:sq=wid2 cf:sq=wid1 |
这个表的rowkey是用户id(pid),列cf:sq表示收取的微博(关注的人发的微博)。当用户发微博时,会遍历粉丝列表,往微博收取表中插入数据,pid为粉丝的pid,cf:sq为自己的id。hbase支持多版本,这里cf:sq的version=10000,该列支持存储最多一万条重复rowkey的数据。即用户可以获取所有关注的人最近发布的10000条微博,这些微博数据是按照版本号排序的,也就是按照发布时间排序的。这样用户可以通过设置版本号获取指定数量的按照发布时间排序的关注人发布的微博。hbase中只支持rowkey排序,不支持列排序,这里利用版本号变相实现了列中数据的排序,实际是同一条数据中的历史数据排序,对于不是同一条数据的列,不符合version的语义,依然没法实现排序
注意:这里只是为了演示,对于数据量不是很大,且有关联关系的数据(例如上面的用户、角色、部门等),是不适合存储在hbase中的,更适合存储在传统的关系型数据库中