对以下场景进行hbase模式设计:
1 用于记录会员在活动中购买商品的情况,记录的信息包括会员id,活动id,商品id,商品的购买量,购买单价等
2 需要进行的查询包括
1)求某个特定会员在某次特定活动中购买指定商品的数量
2)求某个特定会员在某次特定活动中的消费总额
3)求某个特定会员参加过的活动清单
4)求某个特定活动参与会员的清单
提示:关键是行键设计,要求简洁,高效
1 hbase模式设计
会员交易记录表(records_tab)
Row key | Column Family | ||
record | value | ||
customerId-activityId -productId |
| the quantity | |
record:price | the price | ||
record:total | The total | ||
Record:timestamp | The timestamp |
注意:在行键中可以添加时间,格式:customerId-activityId –productId-date。例如:
110001-120001-130001-20130120
2 模拟数据
行键 | 数量 | 单价 | 金额 |
110001-120001-130001 | 100 | 20 | 2000 |
110001-120001-130002 | 20 | 10 | 200 |
110001-120001-130003 | 30 | 100 | 3000 |
110001-120002-130001 | 15 | 10 | 150 |
110002-120001-130001 | 10 | 20 | 200 |
3 查询实现思路
总体思路:
HBase的查询实现有两种方式:
1、按指定RowKey获取唯一一条记录,get方法org.apache.hadoop.hbase.client.Get)
2、按指定的条件获取一批记录,scan方法(org.apache.hadoop.hbase.client.Scan)
实现条件查询功能使用的就是scan方式,scan在使用时有以下几点值得注意:
1、scan可以通过setCaching与setBatch方法提高速度(以空间换时间);
2、scan可以通过setStartRow与setStopRow来限定范围。范围越小,性能越高。
通过巧妙的RowKey设计使我们批量获取记录集合中的元素挨在一起(应该在同一个Region下),可以在遍历结果时获得很好的性能。
3、scan可以通过setFilter方法添加过滤器,这也是分页、多条件查询的基础。
3.1 求某个特定会员在某次特定活动中购买指定商品的数量。
主要代码如下:
publicstaticvoid main(String[] args) throws IOException {
Configuration conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.quorum", "master101,slave102,slave103");
conf.set("hbase.zookeeper.property.clientPort", "2222");
HTable table = new HTable(conf, "records_tab");
String str="110001-120001-130001";
Filter filter = new RowFilter(CompareFilter.CompareOp.EQUAL,
new SubstringComparator(str));
Scan s = new Scan();
s.setFilter(filter);
s.setMaxVersions();
System.out.println("客户:110001,活动:120001,商品:130001,数量:"+resultByUidAidPid(table, s));
}
//求某个特定会员在某次特定活动中购买指定商品的数量
privatestaticint resultByUidAidPid(HTable table, Scan s) throws IOException {
ResultScanner ss = table.getScanner(s);
for(Result r:ss){
for(KeyValue kv:r.raw()){
if(kv.getKeyString().contains("quantity")){
returnnew Integer(new String(kv.getValue()));
}
}
}
return 0;
}
执行结果:
3.2 求某个特定会员在某次特定活动中的消费总额。
主要代码:
publicstaticvoid main(String[] args) throws IOException {
Configuration conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.quorum", "master101,slave102,slave103");
conf.set("hbase.zookeeper.property.clientPort", "2222");
HTable table = new HTable(conf, "records_tab");
String str="110001-120001-130001";
String str1="110001-120001";
Filter filter1 = new RowFilter(CompareFilter.CompareOp.EQUAL,
new SubstringComparator(str1));
Scan s = new Scan();
s.setFilter(filter1);
s.setMaxVersions();
int total=resultByUidAid(table,s);
System.out.println("客户:110001,活动:120001,消费总额:"+total);
}
privatestatic String [] transform(byte [] b){
returnnew String(b).split("-");
}
//求某个特定会员在某次特定活动中的消费总额
privatestaticint resultByUidAid(HTable table, Scan s) throws IOException{
ResultScanner ss = table.getScanner(s);
int total=0;
for(Result r:ss){
String st[]=transform(r.getRow());
System.out.print("客户:"+st[0]+",活动:"+st[1]+",商品:"+st[2]);
for(KeyValue kv:r.raw()){
if(kv.getKeyString().contains("total")){
System.out.println(",金额:"+new Integer(new String(kv.getValue())));
total=total+new Integer(new String(kv.getValue()));
}
}
}
return total;
}
执行结果:
3.3 求某个特定会员参加过的活动清单。
主要代码,如下:
publicstaticvoid main(String[] args) throws IOException {
Configuration conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.quorum", "master101,slave102,slave103");
conf.set("hbase.zookeeper.property.clientPort", "2222");
HTable table = new HTable(conf, "records_tab");
String str="110001";
Filter filter = new RowFilter(CompareFilter.CompareOp.EQUAL,
new SubstringComparator(str));
Scan s = new Scan();
s.setFilter(filter);
s.setMaxVersions();
System.out.println("客户:110001");
resultByUid(table, s);
}
privatestatic String [] transform(byte [] b){
returnnew String(b).split("-");
}
//求某个特定会员参加过的活动清单。
privatestaticvoid resultByUid(HTable table, Scan s) throws IOException{
ResultScanner ss = table.getScanner(s);
String str="";
for(Result r:ss){
String st[]=transform(r.getRow());
if(!str.equals(st[1]))
{
str=st[1];
System.out.println("活动:"+st[1]);
}
}
}
执行结果:
3.4 求某个特定活动参与会员的清单。
主要代码,如下:
publicstaticvoid main(String[] args) throws IOException {
Configuration conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.quorum", "master101,slave102,slave103");
conf.set("hbase.zookeeper.property.clientPort", "2222");
HTable table = new HTable(conf, "records_tab");
String str="120001";
Filter filter = new RowFilter(CompareFilter.CompareOp.EQUAL,
new SubstringComparator(str));
Scan s = new Scan();
s.setFilter(filter);
s.setMaxVersions();
System.out.println("活动:120001");
resultByUid(table, s);
}
privatestatic String [] transform(byte [] b){
returnnew String(b).split("-");
}
//求某个特定活动参与会员的清单。
privatestaticvoid resultByUid(HTable table, Scan s) throws IOException{
ResultScanner ss = table.getScanner(s);
String str="";
for(Result r:ss){
String st[]=transform(r.getRow());
if(!str.equals(st[0]))
{
str=st[0];
System.out.println("客户:"+st[0]);
}
}
}
执行结果: