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;

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM