HBase 3、HBase练习题
1、建立学生和课程表
要求:学生可以选择多个课程,每个课程可以被多个学生选择。
查询某个学生所选的所有课程列表
查询某个课程,的学生列表
学生可以修改所选的课程
方案:学生与课程之间是多对多关系,那可以建三张表 学生表、课程表、学生课程关系表
查询某个学生所选的所有课程列表:通过学生ID到学生课程表中去匹配RowKey为studentxxx的记录,然后再根据获取到的记录可以得到课程ID(即RowKey_后的部分);
然后再根据课程ID获取到课程的名称等内容;
查询某个课程,的学生列表:通过课程ID到学生课程表中去匹配RowKey为coursexxx的记录,然后再根据获取到的记录可以得到学生ID(即RowKey_前的部分);
然后再根据学生ID获取到课程的名称等内容;
学生可以修改所选的课程:学生修改课程,无非有两种情况1.学生新添加了课程;2.学生去掉了课程;因此只要对学生课程表中的数据进行删除或者添加即可;另外两个表数据
不需要做任何更改;
下面是代码:
// 学生表的创建与维护 public class Zuoye2_0 { public static Connection conn = null; public static TableName tName = TableName.valueOf("t_student"); public static Random ra = new Random(); @Before public void init() throws IOException{ Configuration conf = HBaseConfiguration.create(); conf.set("hbase.zookeeper.quorum", "node5,node6,node7"); conn = ConnectionFactory.createConnection(conf); } @Test public void create() throws IOException{ Admin admin = conn.getAdmin(); if(admin.tableExists(tName)){ admin.disableTable(tName); admin.deleteTable(tName); } HTableDescriptor ht = new HTableDescriptor(tName); HColumnDescriptor hc = new HColumnDescriptor("cf1".getBytes()); hc.setMaxVersions(5); hc.setBlockCacheEnabled(true); hc.setBlocksize(180000); ht.addFamily(hc); admin.createTable(ht); System.out.println("表创建完成"); } @Test public void insert() throws IOException{ Table table = conn.getTable(tName); List<Put> putList = new ArrayList<Put>(); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); for(int i=1;i<20;i++){ String id=format.format(new Date()); id=id.replace("-", "").replace(" ", "").replace(":", ""); id = "student"+getRowKey(id); Put put = new Put(id.getBytes()); String name="Tom"+i; put.addColumn("cf1".getBytes(), "name".getBytes(), name.getBytes()); putList.add(put); } table.put(putList); System.out.println("数据插入完成"); } @After public void after() throws IOException { if(conn!=null){ conn.close(); } } private String getRowKey(String id){ return id+""+ra.nextInt(99999); } }
// 课程表的创建与维护 public class Zuoye2_1 { public static Connection conn = null; public static TableName tName = TableName.valueOf("t_course"); public static Random ra = new Random(); @Before public void init() throws IOException{ Configuration conf = HBaseConfiguration.create(); conf.set("hbase.zookeeper.quorum", "node5,node6,node7"); conn = ConnectionFactory.createConnection(conf); } @Test public void create() throws IOException{ Admin admin = conn.getAdmin(); if(admin.tableExists(tName)){ admin.disableTable(tName); admin.deleteTable(tName); } HTableDescriptor ht = new HTableDescriptor(tName); HColumnDescriptor hc = new HColumnDescriptor("cf1".getBytes()); hc.setMaxVersions(5); hc.setBlockCacheEnabled(true); hc.setBlocksize(180000); ht.addFamily(hc); admin.createTable(ht); System.out.println("表创建完成"); } @Test public void insert() throws IOException{ Table table = conn.getTable(tName); List<Put> putList = new ArrayList<Put>(); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); for(int i=1;i<10;i++){ String id=format.format(new Date()); id=id.replace("-", "").replace(" ", "").replace(":", ""); id = "course"+getRowKey(id); Put put = new Put(id.getBytes()); String name="Course"+i; put.addColumn("cf1".getBytes(), "name".getBytes(), name.getBytes()); putList.add(put); } table.put(putList); System.out.println("数据插入完成"); } @After public void after() throws IOException { if(conn!=null){ conn.close(); } } private String getRowKey(String id){ return id+""+ra.nextInt(99999); } }
// http://blog.csdn.net/hugengyong/article/details/38148373 // 学生课程表的维护与查询 public class Zuoye2_2 { public static Connection conn = null; public static TableName tName = TableName.valueOf("t_student_course"); public static TableName tStudent = TableName.valueOf("t_student"); public static TableName tCourse = TableName.valueOf("t_course"); public static Random ra = new Random(); @Before public void init() throws IOException{ Configuration conf = HBaseConfiguration.create(); conf.set("hbase.zookeeper.quorum", "node5,node6,node7"); conn = ConnectionFactory.createConnection(conf); } @Test public void create() throws IOException{ Admin admin = conn.getAdmin(); if(admin.tableExists(tName)){ admin.disableTable(tName); admin.deleteTable(tName); } HTableDescriptor ht = new HTableDescriptor(tName); HColumnDescriptor hc = new HColumnDescriptor("cf1".getBytes()); hc.setMaxVersions(5); hc.setBlockCacheEnabled(true); hc.setBlocksize(180000); ht.addFamily(hc); admin.createTable(ht); System.out.println("表创建完成"); } @Test public void insert() throws IOException{ Table table = conn.getTable(tName); List<Put> putList = new ArrayList<Put>(); //学生1 student2016030421164483174 String stu1 = "student2016030421164483174"; //学生2 student2016030421164417190 String stu2 = "student2016030421164417190"; //学生3 student2016030421164462988 String stu3 = "student2016030421164462988"; //课程1 2 3 course2016030421165195800 course201603042116517244 course2016030421165117240 Put put1 = new Put("student2016030421164483174_course2016030421165195800".getBytes()); put1.addColumn("cf1".getBytes(), "student".getBytes(), stu1.getBytes()); Put put2 = new Put("student2016030421164483174_course201603042116517244".getBytes()); put2.addColumn("cf1".getBytes(), "student".getBytes(), stu1.getBytes()); Put put3 = new Put("student2016030421164483174_course2016030421165117240".getBytes()); put3.addColumn("cf1".getBytes(), "student".getBytes(), stu1.getBytes()); Put put4 = new Put("student2016030421164417190_course2016030421165195800".getBytes()); put4.addColumn("cf1".getBytes(), "student".getBytes(), stu2.getBytes()); Put put5 = new Put("student2016030421164417190_course201603042116517244".getBytes()); put5.addColumn("cf1".getBytes(), "student".getBytes(), stu2.getBytes()); Put put6 = new Put("student2016030421164462988_course2016030421165195800".getBytes()); put6.addColumn("cf1".getBytes(), "student".getBytes(), stu3.getBytes()); putList.add(put1); putList.add(put2); putList.add(put3); putList.add(put4); putList.add(put5); putList.add(put6); table.put(putList); System.out.println("数据插入完成"); } //查询某个学生所选的所有课程列表 学生1 @Test public void findCourseByStudent() throws IOException{ Table table = conn.getTable(tName); String stuId="student2016030421164483174"; List<String> courseIds =new ArrayList<String>(); Scan scan = new Scan(); RowFilter rf1 = new RowFilter(CompareOp.EQUAL, new RegexStringComparator(stuId+"_")); scan.setFilter(rf1); ResultScanner rs1 = table.getScanner(scan); Iterator<Result> it = rs1.iterator(); while(it.hasNext()){ Result result = it.next(); byte[] rowKey = result.getRow(); courseIds.add(new String(rowKey,"utf8")); } for(String id : courseIds){ String courseId = id.split("_")[1]; Table courseTable = conn.getTable(tCourse); Get get = new Get(courseId.getBytes()); Result result= courseTable.get(get); byte[] name = result.getValue("cf1".getBytes(), "name".getBytes()); System.out.println("课程ID:"+courseId+" 名称:"+new String(name,"utf8")); } } //查询某个课程,的学生列表 课程1 @Test public void findStudentByCourse() throws IOException{ Table table = conn.getTable(tName); String courseId="course2016030421165195800"; List<String> studentIds =new ArrayList<String>(); Scan scan = new Scan(); RowFilter rf1 = new RowFilter(CompareOp.EQUAL, new RegexStringComparator("_"+courseId)); scan.setFilter(rf1); ResultScanner rs1 = table.getScanner(scan); Iterator<Result> it = rs1.iterator(); while(it.hasNext()){ Result result = it.next(); byte[] rowKey = result.getRow(); studentIds.add(new String(rowKey,"utf8")); } for(String id : studentIds){ String stuId = id.split("_")[0]; Table stuTable = conn.getTable(tStudent); Get get = new Get(stuId.getBytes()); Result result= stuTable.get(get); byte[] name = result.getValue("cf1".getBytes(), "name".getBytes()); System.out.println("学生ID:"+courseId+" 名字:"+new String(name,"utf8")); } } //学生可以修改所选的课程 将学生1的课程1去掉 @Test public void changeCourseOfStudent() throws IOException{ String stuId="student2016030421164483174"; String courseId="course2016030421165195800"; String scId=stuId+"_"+courseId; Delete delete = new Delete(scId.getBytes()); Table table = conn.getTable(tName); table.delete(delete); } @After public void after() throws IOException { if(conn!=null){ conn.close(); } } }
2、建立部门表
要求:部门下有多个子部门。查询所有的顶级部门列表,查询某个部门下所有子部门列表,可以修改一个部门的所属父部门。
方案:
1.在RowKey的设计上把是否是顶级部门带入,例:0_001,1_002 0/1代表是还是是子级部门 0不是 1是 这样可以根据RowKey就能查询出所有的顶级部门
2.在部门表中设计了两个列族 cf1 cf2 在cf2中存储当前部门下的所有子部门;在cf2中存储方式是列名是子部门ID 例值也是子部门ID 例:1_002:1_002
这样可以在不进行又迭代的情况下就可以获取一个部门下的子级部门;只要取出该RowKey的cf2列族下的所有列即可;
3.当修改一个部门的父部门的时候,首先先找到该部门的父部门,先把当前的父部门中的cf2列族下的列删除掉,再到新的部门下的cf2列族下添加一个子部门;最后
再修改当前部门的父ID为新的部门ID
设计如下:
3、根据新浪微博系统:请建立微博系统的表
1.用户表不需要创建,假设用户已经存在,在DBMS中。
2.所有用户可以发微博
3.所有用户可以添加关注用户和取消关注用户
4.所有用户可以查看粉丝列表
5.用户首页,用户所关注的其他用户最新发布的微博列表。
方案:
微博表
rowkey cf1
uid_time_wid content
zs_2015_001
sunliu_2016_002
zs_2016_03050102 content
关注表
cf1 关注的人的id cf2 我的粉丝的id
uid 002=002,
zs 002=002, 004,005
sunlie 004
收件箱表(收取我关注的人发布的最新的微博)
rowkey cf1
uid w_rowkey= set max_version=1000
004 w_rowkey=zs_2015_001 w_rowkey=sunliu_2016_002 w_rowkey=sunliu_2016_003
005 w_rowkey=zs_2015_001
只要xx发布了一条新微博,则系统就会向xx的所有粉丝的收件箱中插一条列w_rowkey的内容作为当前最新版本的值;
在收件箱表中可以设置列 w_rowkey 的保存最多副本数MaxVersions 例:w_rowkey最多可保存1000个副本,那么可以通过时间戳倒序排列,就能获取到最近的我关注的人发布的1000条微博内容的内容ID;