HBase数据库设计

HBase数据库设计

题目:

1、人员-角色
人员有多个角色 角色优先级
角色有多个人员
人员 删除添加角色
角色 可以添加删除人员
人员 角色 删除添加

2、组织架构 部门-子部门
查询 顶级部门
查询 每个部门的所有子部门
部门 添加、删除子部门
部门 添加、删除

3、通话记录:
手机号 对方手机号 通话时长 时间 通话类型(主叫/被叫)

通话记录设计

package com.bjsxt.hbase;

......

public class PhoneCase {

	// 表的管理类
	HBaseAdmin admin = null;
	// 数据的管理类
	HTable table = null;
	// 表名
	String tm = "phone";

	/**
	 * 完成初始化功能
	 * 
	 * @throws Exception
	 */
	@Before
	public void init() throws Exception {
		Configuration conf = new Configuration();
		conf.set("hbase.zookeeper.quorum", "node1,node2,node3");
		admin = new HBaseAdmin(conf);
		table = new HTable(conf, tm.getBytes());
	}

	/**
	 * 创建表
	 * 
	 * @throws Exception
	 */
	@Test
	public void createTable() throws Exception {
		// 表的描述类
		HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(tm));
		// 列族的描述类
		HColumnDescriptor family = new HColumnDescriptor("cf".getBytes());
		desc.addFamily(family);
		if (admin.tableExists(tm)) {
			admin.disableTable(tm);
			admin.deleteTable(tm);
		}
		admin.createTable(desc);
	}

	/**
	 * 10个用户,每个用户每年产生1000条通话记录
	 * 
	 * dnum:对方手机号 type:类型:0主叫,1被叫 length:长度 date:时间
	 * 
	 * @throws Exception
	 * 
	 */
	@Test
	public void insert() throws Exception {
		List<Put> puts = new ArrayList<Put>();
		for (int i = 0; i < 10; i++) {
			String phoneNumber = getPhone("158");
			for (int j = 0; j < 1000; j++) {
				// 属性
				String dnum = getPhone("177");
				String length = String.valueOf(r.nextInt(99));
				String type = String.valueOf(r.nextInt(2));
				String date = getDate("2018");
				// rowkey设计
				String rowkey = phoneNumber + "_" + (Long.MAX_VALUE - sdf.parse(date).getTime());
				Put put = new Put(rowkey.getBytes());
				put.add("cf".getBytes(), "dnum".getBytes(), dnum.getBytes());
				put.add("cf".getBytes(), "length".getBytes(), length.getBytes());
				put.add("cf".getBytes(), "type".getBytes(), type.getBytes());
				put.add("cf".getBytes(), "date".getBytes(), date.getBytes());
				puts.add(put);
			}
		}
		table.put(puts);
	}

	/**
	 * 查询某一个用户3月份的所有通话记录 条件: 1、某一个用户 2、时间
	 * 
	 * @throws Exception
	 */
	@Test
	public void scan() throws Exception {
		String phoneNumber = "15895223166";
		String startRow = phoneNumber + "_" + (Long.MAX_VALUE - sdf.parse("20180401000000").getTime());
		String stopRow = phoneNumber + "_" + (Long.MAX_VALUE - sdf.parse("20180301000000").getTime());

		Scan scan = new Scan();
		scan.setStartRow(startRow.getBytes());
		scan.setStopRow(stopRow.getBytes());
		ResultScanner scanner = table.getScanner(scan);
		for (Result result : scanner) {
			System.out.print(Bytes
					.toString(CellUtil.cloneValue(result.getColumnLatestCell("cf".getBytes(), "dnum".getBytes()))));
			System.out.print("--" + Bytes
					.toString(CellUtil.cloneValue(result.getColumnLatestCell("cf".getBytes(), "type".getBytes()))));
			System.out.print("--" + Bytes
					.toString(CellUtil.cloneValue(result.getColumnLatestCell("cf".getBytes(), "date".getBytes()))));
			System.out.println("--" + Bytes
					.toString(CellUtil.cloneValue(result.getColumnLatestCell("cf".getBytes(), "length".getBytes()))));
		}
	}

	/**
	 * 查询某一个用户。所有的主叫电话 条件: 1、电话号码 2、type=0
	 * 
	 * @throws Exception
	 */
	@Test
	public void scan2() throws Exception {
		FilterList filters = new FilterList(FilterList.Operator.MUST_PASS_ALL);
		SingleColumnValueFilter filter1 = new SingleColumnValueFilter("cf".getBytes(), "type".getBytes(),
				CompareOp.EQUAL, "0".getBytes());
		PrefixFilter filter2 = new PrefixFilter("15895223166".getBytes());
		filters.addFilter(filter1);
		filters.addFilter(filter2);

		Scan scan = new Scan();
		scan.setFilter(filters);
		ResultScanner scanner = table.getScanner(scan);
		for (Result result : scanner) {
			System.out.print(Bytes
					.toString(CellUtil.cloneValue(result.getColumnLatestCell("cf".getBytes(), "dnum".getBytes()))));
			System.out.print("--" + Bytes
					.toString(CellUtil.cloneValue(result.getColumnLatestCell("cf".getBytes(), "type".getBytes()))));
			System.out.print("--" + Bytes
					.toString(CellUtil.cloneValue(result.getColumnLatestCell("cf".getBytes(), "date".getBytes()))));
			System.out.println("--" + Bytes
					.toString(CellUtil.cloneValue(result.getColumnLatestCell("cf".getBytes(), "length".getBytes()))));
		}
		scanner.close();
	}

	/**
	 * 
	 * @param string
	 * @return
	 */

	private String getDate(String string) {
		return string + String.format("%02d%02d%02d%02d%02d", r.nextInt(12) + 1, r.nextInt(31), r.nextInt(24),
				r.nextInt(60), r.nextInt(60));
	}

	Random r = new Random();
	SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmss");

	private String getPhone(String phonePrefix) {
		return phonePrefix + String.format("%08d", r.nextInt(99999999));
	}

	/**
	 * 10个用户,每个用户1000条,每一条记录当作一个对象进行存储
	 * @throws Exception 
	 */
	@Test
	public void insert2() throws Exception{
		List<Put> puts = new ArrayList<Put>();
		for(int i = 0;i<10;i++){
			String phoneNumber = getPhone("158");
			for(int j = 0;j<1000;j++){
				String dnum = getPhone("177");
				String length =String.valueOf(r.nextInt(99));
				String type = String.valueOf(r.nextInt(2));
				String date = getDate("2018");
				//保存属性到对象中
				Phone.PhoneDetail.Builder phoneDetail = Phone.PhoneDetail.newBuilder();
				phoneDetail.setDate(date);
				phoneDetail.setLength(length);
				phoneDetail.setType(type);
				phoneDetail.setDnum(dnum);
				
				//rowkey
				String rowkey = phoneNumber+"_"+(Long.MAX_VALUE-sdf.parse(date).getTime());
			
				Put put = new Put(rowkey.getBytes());
				put.add("cf".getBytes(), "phoneDetail".getBytes(), phoneDetail.build().toByteArray());
				puts.add(put);
			}
		}
		table.put(puts);
	}
	
	@Test
	public void get() throws Exception{
		Get get = new Get("15866626435_9223370522183722807".getBytes());
		Result result = table.get(get);
		PhoneDetail phoneDetail = Phone.PhoneDetail.parseFrom(CellUtil.cloneValue(result.getColumnLatestCell("cf".getBytes(), "phoneDetail".getBytes())));
		System.out.println(phoneDetail);
	}
	
	/**
	 * 10个用户,每天产生1000条记录,每一天的所有数据放到一个rowkey中
	 * @throws Exception 
	 */
	@Test
	public void insert3() throws Exception{
		List<Put> puts = new ArrayList<Put>();

		for(int i = 0;i<10;i++){
			String phoneNumber = getPhone("133");
			String rowkey = phoneNumber+"_"+(Long.MAX_VALUE-sdf.parse("20181225000000").getTime());
			Phone.DayOfPhone.Builder dayOfPhone = Phone.DayOfPhone.newBuilder();
			for(int j=0;j<1000;j++){
				String dnum = getPhone("177");
				String length =String.valueOf(r.nextInt(99));
				String type = String.valueOf(r.nextInt(2));
				String date = getDate2("20181225");
				
				Phone.PhoneDetail.Builder phoneDetail = Phone.PhoneDetail.newBuilder();
				phoneDetail.setDate(date);
				phoneDetail.setLength(length);
				phoneDetail.setType(type);
				phoneDetail.setDnum(dnum);
				dayOfPhone.addDayPhone(phoneDetail);
			}
			Put put = new Put(rowkey.getBytes());
			put.add("cf".getBytes(), "day".getBytes(), dayOfPhone.build().toByteArray());
			puts.add(put);
		}
		table.put(puts);
		
	}
	
	@Test
	public void get2() throws Exception{
		Get get = new Get("13398049199_9223370491187575807".getBytes());
		Result result = table.get(get);
		DayOfPhone parseFrom = Phone.DayOfPhone.parseFrom(CellUtil.cloneValue(result.getColumnLatestCell("cf".getBytes(), "day".getBytes())));
		int count = 0;
		for (PhoneDetail pd : parseFrom.getDayPhoneList()) {
			System.out.println(pd);
			count++;
		}
		System.out.println(count);
	}
	
	private String getDate2(String string) {
		return string+String.format("%02d%02d%02d", r.nextInt(24),r.nextInt(60),r.nextInt(60));
	}

	@After
	public void destory() throws Exception {
		
		if (admin != null) {
			admin.close();
		}
	}
}

人员-角色

两张表
psn
rowkey:					cf1:(人员信息)						cf2:(角色列表)
pid
001						cf1:name=小红						cf2:100=10,cf2:200=9
002						cf1:name=小白						cf2:200=10,cf2:300=9
003						cf1:name=小黑						cf2:300=10,cf2:400=9
004						cf1:name=小绿				

role
rowkey:						cf1:(角色信息)						cf2:(人员列表)
rid	
100						cf1:name=班长						cf2:001=小红
200						cf1:name=学委						cf2:001=小红,cf2:002=小白
300						cf1:name=劳委						cf2:001=小黑,cf2:002=小白
400						cf1:name=体委						cf2:001=小黑,

协处理器

到目前为止,用户已经掌握了如何使用过滤器来减少服务器端通过网络返回到客户端的数据量。HBase 中还有一些特性让用户 甚至可以把一部分计算也移动到数据的存放端:协处理器( coprocessor)。

组织架构

CEO300	
	develop	100
		develop1	200
		develop2	400
	web800
		web1 700
		web2 1100
	test	600
		test1	500
		test2	900
		test3	1000

dept
rowkey:						cf:(部门信息)					cf2:(子部门列表)
did
300							cf:name=ceo,					cf2:100=,cf2:800=?,cf2:600=?
100							cf:name=develop,cf:fid=300		cf2:200=,
200							cf:name=develop1,cf:fid=100
400							cf:name=develop2,cf:fid=100
800							cf:name=web,cf:fid=300			cf2:700=?,cf:1100=?
700							cf:name=web1,cf:fid=800					
1100 						cf:name=web2,cf:fid=800
posted @ 2020-12-02 15:36  shaoyayu  阅读(519)  评论(0编辑  收藏  举报