HBase分佈式數據庫操作與編程——HBase 練習、HBase Shell數據庫表創建、HBase Shell數據訪問操作、HBase Java API編程

HBase分佈式數據庫操作與編程目錄

一、實驗目的

1.掌握HBase操作常用Shell命令;
2.掌握HBase數據表的創建、添加數據、查看數據、刪除數據、刪除表、查詢歷史數據等操作;
3.掌握HBase APIs編程實踐方法

二、實驗內容

第1題 HBase 練習
【實驗內容】
1.實現HBase的配置並完成http://dblab.xmu.edu.cn/blog/install-hbase/上的javac程序練習。
1、切換到/usr/local/hbase目錄並編輯/.bashrc文件(在/.bashrc文件中export PATH這行追加/usr/local/hbase/bin)
在這裏插入圖片描述
2、編輯完成後,再執行source命令使上述配置在當前終端立即生效
在這裏插入圖片描述
3、添加HBase權限(將hbase下的所有文件的所有者改爲hadoop,hadoop是當前用戶的用戶名)
在這裏插入圖片描述
4、 查看HBase版本,確定hbase安裝成功(看到以下輸出消息表示HBase已經安裝成功)
在這裏插入圖片描述
5、用vi命令打開並編輯hbase-env.sh
在這裏插入圖片描述
配置JAVA環境變量如圖,配置HBASE_MANAGES_ZK爲true,表示由hbase自己管理zookeeper,不需要單獨的zookeeper
在這裏插入圖片描述
6、打開並編輯hbase-site.xml
在這裏插入圖片描述
在啓動HBase前需要設置屬性hbase.rootdir,用於指定HBase數據的存儲位置(以防每次重啓系統都會丟失數據)
在這裏插入圖片描述
7、測試運行(首先切換目錄至HBase安裝目錄/usr/local/hbase;再啓動HBase)
在這裏插入圖片描述
8、打開shell命令行模式(用戶可以通過輸入shell命令操作HBase數據庫)
在這裏插入圖片描述
9、退出shell命令行模式,停止HBase運行
在這裏插入圖片描述
10、配置/usr/local/hbase/conf/hbase-env.sh
在這裏插入圖片描述
配置JAVA_HOME,HBASE_CLASSPATH,HBASE_MANAGES_ZK.
HBASE_CLASSPATH設置爲本機Hadoop安裝目錄下的conf目錄(即/usr/local/hadoop/conf)
在這裏插入圖片描述
11、用命令vi打開並編輯hbase-site.xml
在這裏插入圖片描述
hbase.rootdir指定HBase的存儲目錄;hbase.cluster.distributed設置集羣處於分佈式模式
在這裏插入圖片描述
12、登陸ssh,切換目錄至/usr/local/hadoop ,啓動hadoop
在這裏插入圖片描述
13、命令jps(能看到NameNode,DataNode和SecondaryNameNode都已經成功啓動,表示hadoop啓動成功)
在這裏插入圖片描述
14、切換目錄至/usr/local/hbase,啓動HBase(輸入命令jps,看到以下界面說明hbase啓動成功)
在這裏插入圖片描述
15、進入shell界面
在這裏插入圖片描述
16、退出shell界面,停止HBase運行
在這裏插入圖片描述
編程實踐
1、HBase中用create命令創建表
在這裏插入圖片描述
2、通過describe命令查看“student”表的基本信息
在這裏插入圖片描述
3、添加數據( 當運行命令:put ‘student’,’95001’,’Sname’,’LiYing’時,即爲student表添加了學號爲95001,名字爲LiYing的一行數據,其行鍵爲95001 )
在這裏插入圖片描述
4、爲95001行下的course列族的math列添加了一個數據
在這裏插入圖片描述
5、爲95001行下的course列族的Sage列添加了一個數據
在這裏插入圖片描述
6、爲95001行下的course列族的Sdept列添加了一個數據
在這裏插入圖片描述
7、刪除數據,刪除了student表中95001行下的Ssex列的所有數據
在這裏插入圖片描述
8、get命令,(用於查看某一行數據,返回的是‘student’表‘95001’行的數據)
在這裏插入圖片描述
9、scan命令(用於查看某個表的全部數據)
在這裏插入圖片描述
10、刪除student表中的95001行的全部數據
在這裏插入圖片描述
11、刪除表有兩步,第一步先讓該表不可用,第二步刪除表
在這裏插入圖片描述
12、在創建表的時候,指定保存的版本數(假設指定爲5)
在這裏插入圖片描述
13、put命令,插入數據然後更新數據,使其產生歷史版本數據
在這裏插入圖片描述
14、詢時,指定查詢的歷史版本數。默認會查詢出最新的數據。(有效取值爲1到5)
在這裏插入圖片描述
15、Eclipse編寫java程序,來對HBase數據庫進行增刪改查等操作
ExampleForHbase類代碼如下

    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.hbase.*;
    import org.apache.hadoop.hbase.client.*;
    import java.io.IOException;
     
    public class ExampleForHbase{
        public static Configuration configuration;
        public static Connection connection;
        public static Admin admin;
     
        //主函數中的語句請逐句執行,只需刪除其前的//即可,如:執行insertRow時請將其他語句註釋
        public static void main(String[] args)throws IOException{
            //創建一個表,表名爲Score,列族爲sname,course
            createTable("Score",new String[]{"sname","course"});
     
            //在Score表中插入一條數據,其行鍵爲95001,sname爲Mary(因爲sname列族下沒有子列所以第四個參數爲空)
            //等價命令:put 'Score','95001','sname','Mary'
            insertRow("Score", "95001", "sname", "", "Mary");
            //在Score表中插入一條數據,其行鍵爲95001,course:Math爲88(course爲列族,Math爲course下的子列)
            //等價命令:put 'Score','95001','score:Math','88'
            //insertRow("Score", "95001", "course", "Math", "88");
            //在Score表中插入一條數據,其行鍵爲95001,course:English爲85(course爲列族,English爲course下的子列)
            //等價命令:put 'Score','95001','score:English','85'
            //insertRow("Score", "95001", "course", "English", "85");
     
            //1、刪除Score表中指定列數據,其行鍵爲95001,列族爲course,列爲Math
            //執行這句代碼前請deleteRow方法的定義中,將刪除指定列數據的代碼取消註釋註釋,將刪除制定列族的代碼註釋
            //等價命令:delete 'Score','95001','score:Math'
            //deleteRow("Score", "95001", "course", "Math");
     
            //2、刪除Score表中指定列族數據,其行鍵爲95001,列族爲course(95001的Math和English的值都會被刪除)
            //執行這句代碼前請deleteRow方法的定義中,將刪除指定列數據的代碼註釋,將刪除制定列族的代碼取消註釋
            //等價命令:delete 'Score','95001','score'
            //deleteRow("Score", "95001", "course", "");
     
            //3、刪除Score表中指定行數據,其行鍵爲95001
            //執行這句代碼前請deleteRow方法的定義中,將刪除指定列數據的代碼註釋,以及將刪除制定列族的代碼註釋
            //等價命令:deleteall 'Score','95001'
            //deleteRow("Score", "95001", "", "");
     
            //查詢Score表中,行鍵爲95001,列族爲course,列爲Math的值
            //getData("Score", "95001", "course", "Math");
            //查詢Score表中,行鍵爲95001,列族爲sname的值(因爲sname列族下沒有子列所以第四個參數爲空)
            //getData("Score", "95001", "sname", "");
     
            //刪除Score表
            //deleteTable("Score");
        }
     
        //建立連接
        public static void init(){
            configuration  = HBaseConfiguration.create();
            configuration.set("hbase.rootdir","hdfs://localhost:9000/hbase");
            try{
                connection = ConnectionFactory.createConnection(configuration);
                admin = connection.getAdmin();
            }catch (IOException e){
                e.printStackTrace();
            }
        }
        //關閉連接
        public static void close(){
            try{
                if(admin != null){
                    admin.close();
                }
                if(null != connection){
                    connection.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
     
        /**
         * 建表。HBase的表中會有一個系統默認的屬性作爲主鍵,主鍵無需自行創建,默認爲put命令操作中表名後第一個數據,因此此處無需創建id列
         * @param myTableName 表名
         * @param colFamily 列族名
         * @throws IOException
         */
        public static void createTable(String myTableName,String[] colFamily) throws IOException {
     
            init();
            TableName tableName = TableName.valueOf(myTableName);
     
            if(admin.tableExists(tableName)){
                System.out.println("talbe is exists!");
            }else {
                HTableDescriptor hTableDescriptor = new HTableDescriptor(tableName);
                for(String str:colFamily){
                    HColumnDescriptor hColumnDescriptor = new HColumnDescriptor(str);
                    hTableDescriptor.addFamily(hColumnDescriptor);
                }
                admin.createTable(hTableDescriptor);
                System.out.println("create table success");
            }
            close();
        }
        /**
         * 刪除指定表
         * @param tableName 表名
         * @throws IOException
         */
        public static void deleteTable(String tableName) throws IOException {
            init();
            TableName tn = TableName.valueOf(tableName);
            if (admin.tableExists(tn)) {
                admin.disableTable(tn);
                admin.deleteTable(tn);
            }
            close();
        }
     
        /**
         * 查看已有表
         * @throws IOException
         */
        public static void listTables() throws IOException {
            init();
            HTableDescriptor hTableDescriptors[] = admin.listTables();
            for(HTableDescriptor hTableDescriptor :hTableDescriptors){
                System.out.println(hTableDescriptor.getNameAsString());
            }
            close();
        }
        /**
         * 向某一行的某一列插入數據
         * @param tableName 表名
         * @param rowKey 行鍵
         * @param colFamily 列族名
         * @param col 列名(如果其列族下沒有子列,此參數可爲空)
         * @param val 值
         * @throws IOException
         */
        public static void insertRow(String tableName,String rowKey,String colFamily,String col,String val) throws IOException {
            init();
            Table table = connection.getTable(TableName.valueOf(tableName));
            Put put = new Put(rowKey.getBytes());
            put.addColumn(colFamily.getBytes(), col.getBytes(), val.getBytes());
            table.put(put);
            table.close();
            close();
        }
     
        /**
         * 刪除數據
         * @param tableName 表名
         * @param rowKey 行鍵
         * @param colFamily 列族名
         * @param col 列名
         * @throws IOException
         */
        public static void deleteRow(String tableName,String rowKey,String colFamily,String col) throws IOException {
            init();
            Table table = connection.getTable(TableName.valueOf(tableName));
            Delete delete = new Delete(rowKey.getBytes());
            //刪除指定列族的所有數據
            //delete.addFamily(colFamily.getBytes());
            //刪除指定列的數據
            //delete.addColumn(colFamily.getBytes(), col.getBytes());
     
            table.delete(delete);
            table.close();
            close();
        }
        /**
         * 根據行鍵rowkey查找數據
         * @param tableName 表名
         * @param rowKey 行鍵
         * @param colFamily 列族名
         * @param col 列名
         * @throws IOException
         */
        public static void getData(String tableName,String rowKey,String colFamily,String col)throws  IOException{
            init();
            Table table = connection.getTable(TableName.valueOf(tableName));
            Get get = new Get(rowKey.getBytes());
            get.addColumn(colFamily.getBytes(),col.getBytes());
            Result result = table.get(get);
            showCell(result);
            table.close();
            close();
        }
        /**
         * 格式化輸出
         * @param result
         */
        public static void showCell(Result result){
            Cell[] cells = result.rawCells();
            for(Cell cell:cells){
                System.out.println("RowName:"+new String(CellUtil.cloneRow(cell))+" ");
                System.out.println("Timetamp:"+cell.getTimestamp()+" ");
                System.out.println("column Family:"+new String(CellUtil.cloneFamily(cell))+" ");
                System.out.println("row Name:"+new String(CellUtil.cloneQualifier(cell))+" ");
                System.out.println("value:"+new String(CellUtil.cloneValue(cell))+" ");
            }
        }
    }

編程實例代碼運行結果
在這裏插入圖片描述
執行完插入數據後,在shell界面中執行scan ‘Score’
在這裏插入圖片描述
第2題. HBase Shell數據庫表創建
【實驗內容】
根據以下關係型數據庫表,使用HBase Shell設計並創建適宜的HBase數據表。
在這裏插入圖片描述
1、啓動hadoop、hbase
在這裏插入圖片描述
2、進入hbase的shell界面
在這裏插入圖片描述
3、創建表格“Student”
在這裏插入圖片描述
4、創建表格“Score”和“SC”
在這裏插入圖片描述
5、查看已有的表格
在這裏插入圖片描述
6、給“Student”表學號爲“2020001”添加姓名、性別、年齡
在這裏插入圖片描述
7、給“Student”表學號爲“2020003”添加姓名、性別、年齡
在這裏插入圖片描述
8、給“Student”表學號爲“2020005”添加姓名、性別、年齡
在這裏插入圖片描述
9、scan命令查看“Student”表格信息
在這裏插入圖片描述
10、給“Course”表學號爲“123001、123002、123003”分別添加對應的課程名稱
在這裏插入圖片描述
11、給“Course”表學號爲“123001、123002、123003”添加學分
在這裏插入圖片描述
12、查看“Course”表格的全部數據
在這裏插入圖片描述
13、向學生表添加課程列族
在這裏插入圖片描述
14、scan命令查看“Student”表格信息
在這裏插入圖片描述
第3題 HBase Shell數據訪問操作
【實驗內容】
(1)使用HBase Shell命令向第1題所構建的HBase數據表中添加適宜數據;
(2)使用HBase Shell命令從第1題所構建的HBase數據表中查詢出數據;
(3)使用HBase Shell命令從第1題所構建的HBase數據表中刪除任一數據;
(4)使用HBase Shell命令統計第1題所構建的HBase數據表的行數。

【實驗過程】(步驟、記錄、數據、程序等)
請提供相應Shell操作命令或相應Shell界面截圖證明。
1、在“Student”添加數據
在這裏插入圖片描述
2、查詢出數據
在這裏插入圖片描述
3、刪除任一數據
在這裏插入圖片描述
4、統計“Student”表的行數
在這裏插入圖片描述
第4題 HBase Java API編程
【實驗內容】
根據第1,2題所建立的表,請編程完成以下指定功能:
(1)createTable(String tableName, String[] fields)
創建表,參數tableName爲表的名稱,字符串數組fields爲存儲記錄各個域名稱的數組。要求當HBase已經存在名爲tableName的表的時候,先刪除原有的表,然後再創建新的表。
(2)addRecord(String tableName, String row, String[] fields, String[] values)
向表tableName、行row(用S_Name表示)和字符串數組files指定的單元格中添加對應的數據values。其中fields中每個元素如果對應的列族下還有相應的列限定符的話,用“columnFamily:column”表示。例如,同時向“Math”、“Computer Science”、“English”三列添加成績時,字符串數組fields爲{“Score:Math”,”Score;Computer Science”,”Score:English”},數組values存儲這三門課的成績。
(3)scanColumn(String tableName, String column)
瀏覽表tableName某一列的數據,如果某一行記錄中該列數據不存在,則返回null。要求當參數column爲某一列族名稱時,如果底下有若干個列限定符,則要列出每個列限定符代表的列的數據;當參數column爲某一列具體名稱(例如“Score:Math”)時,只需要列出該列的數據。
(4)modifyData(String tableName, String row, String column)
修改表tableName,行row(可以用學生姓名S_Name表示),列column指定的單元格的數據。
(5)deleteRow(String tableName, String row)
刪除表tableName中row指定的行的記錄。

1、創建java工程
在這裏插入圖片描述
2、菜單函數,java程序代碼如下
HBaseModifyStudent類代碼如下

import java.io.IOException;
import java.util.Scanner;
public class HBaseModifyStudent {
	public static void main(String[] args) throws IOException{
		HBaseStudentOperation h1=new HBaseStudentOperation();
		@SuppressWarnings("resource")
		Scanner in = new Scanner(System.in);
		while(true){
			System.out.println("**********************基於JAVA的Hbase數據庫表及表的基本操作**********************");
			System.out.println("1、創建學生選課表");
			System.out.println("2、向創建的表中添加學生信息");
			System.out.println("3、瀏覽創建的選課表中指定列的數據");
			System.out.println("4、修改指定單元格的數據");
			System.out.println("5、刪除指定行的數據");
			System.out.println("0、退出!");
			System.out.print("請輸入你的選擇:");
			int a=in.nextInt();
			switch(a){
			case 1: h1.createTable("StudentScore",new String[]{"student","Math","ComputerScience","English"});break;
			case 2: h1.addRecord("StudentScore","Zhangsan",new String[]{"student:S_No","student:S_Name","student:S_Sex","student:S_Age","Math:C_No","Math:C_Name","Math:C_Credit","Math:SC_Score","English:C_No","English:C_Name","English:C_Credit","English:SC_Score"}, new String[]{"2020001","Zhangsan","male","23","123001","Math","2.0","86","123003","English","3.0","69"});break;
			case 3: h1.scanColumn("StudentScore", "Math");break;
			case 4: h1.modifyData("StudentScore","Zhangsan","Math:SC_Score","89");break;
			case 5: h1.deleteRow("StudentScore","Zhangsan");break;
			case 0: return;
			}
		}
	}
}

在這裏插入圖片描述
3、連接和關閉Hbase數據庫的JAVA代碼
HBaseStudentOperation類代碼如下

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;

import java.io.IOException;
import java.util.Scanner;
public class HBaseStudentOperation{
        public static Configuration configuration;
        public static Connection connection;
        public static Admin admin;
        //建立連接
        public static void init(){
            configuration  = HBaseConfiguration.create();
            configuration.set("hbase.rootdir","hdfs://localhost:9000/hbase");
            try{
                connection = ConnectionFactory.createConnection(configuration);
                admin = connection.getAdmin();
            }catch (IOException e){
                e.printStackTrace();
            }
        }
        //關閉連接
        public static void close(){
            try{
                if(admin != null){
                    admin.close();
                }
                if(null != connection){
                    connection.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
     
        /**
         * 建表。HBase的表中會有一個系統默認的屬性作爲主鍵,主鍵無需自行創建,默認爲put命令操作中表名後第一個數據,因此此處無需創建id列
         * @param myTableName 表名
         * @param colFamily 列族名
         * @throws IOException
         */
        public static void createTable(String myTableName,String[] colFamily) throws IOException {
        	@SuppressWarnings("resource")
    		Scanner in = new Scanner(System.in);
            init();
            TableName tableName = TableName.valueOf(myTableName);
            if(admin.tableExists(tableName)){
                System.out.println("該表已經存在!");
                System.out.println("是否刪除該表重新創建?");
                System.out.println("1、是");
                System.out.println("2、否");
                System.out.print("請輸入你的選擇:");
                int a=in.nextInt();
                switch(a){
                case 1:if (admin.tableExists(tableName)) {
                    		admin.disableTable(tableName);
                    		admin.deleteTable(tableName);
                    		System.out.println("表:"+tableName+"已成功刪除");
                		}
                	   HTableDescriptor hTableDescriptor = new HTableDescriptor(tableName);
                	   for(String str:colFamily){
                		  HColumnDescriptor hColumnDescriptor = new HColumnDescriptor(str);
                		  hTableDescriptor.addFamily(hColumnDescriptor);
                	    }
                	   admin.createTable(hTableDescriptor);
                	   System.out.println("表創建成功!");break;
                case 2:break;
                }
            }else {
                HTableDescriptor hTableDescriptor = new HTableDescriptor(tableName);
                for(String str:colFamily){
                    HColumnDescriptor hColumnDescriptor = new HColumnDescriptor(str);
                    hTableDescriptor.addFamily(hColumnDescriptor);
                }
                admin.createTable(hTableDescriptor);
                System.out.println("表創建成功!");
            }
            close();
        }
        public void addRecord(String tableName,String rowKey,String []fields,String [] values) throws IOException {
            init();
            Table table = connection.getTable(TableName.valueOf(tableName));
            for (int i = 0; i < fields.length; i++) {
             Put put = new Put(rowKey.getBytes());
             String [] cols = fields[i].split(":");
             if(cols.length==1){
            	 put.addColumn(cols[0].getBytes(), "".getBytes(), values[i].getBytes());//因爲當輸入的是單列族,split僅讀出一個字符字符串,即cols僅有一個元素
             }
             else {
            	 put.addColumn(cols[0].getBytes(), cols[1].getBytes(), values[i].getBytes());
            }
             table.put(put);
            }
            System.out.println("數據插入成功");
            table.close();
            close();
           }
        public void scanColumn (String tableName,String column) throws IOException{
        	init();
        	Table table = connection.getTable(TableName.valueOf(tableName));
        	Scan scan = new Scan();
        	String [] cols = column.split(":");
        	if(cols.length==1){
        		scan.addFamily(Bytes.toBytes(column));
        		}
        	else {
        		scan.addColumn(Bytes.toBytes(cols[0]),Bytes.toBytes(cols[1]));
        		}
        	ResultScanner scanner = table.getScanner(scan);
        	for (Result result = scanner.next(); result !=null;result = scanner.next()) {
        		showCell(result);
        		}
        	table.close();
        	close();
        	}
        public void modifyData(String tableName,String rowKey,String column,String value) throws IOException{
        	init();
        	Table table = connection.getTable(TableName.valueOf(tableName));
        	Put put = new Put(rowKey.getBytes());
        	String [] cols = column.split(":");
        	if(cols.length==1){
        		put.addColumn(column.getBytes(),"".getBytes() , value.getBytes());//qualifier:列族下的列名
        	}
        	else { 
        		put.addColumn(cols[0].getBytes(),cols[1].getBytes() , value.getBytes());//qualifier:列族下的列名
        	}
        	System.out.println("信息修改成功!");
        	table.put(put);
        	table.close();
        	close();
       }
       public void showCell(Result result){
            Cell[] cells = result.rawCells();
            for(Cell cell:cells){
                System.out.println("RowName:"+new String(CellUtil.cloneRow(cell))+" ");
                System.out.println("Timetamp:"+cell.getTimestamp()+" ");
                System.out.println("column Family:"+new String(CellUtil.cloneFamily(cell))+" ");
                System.out.println("row Name:"+new String(CellUtil.cloneQualifier(cell))+" ");
                System.out.println("value:"+new String(CellUtil.cloneValue(cell))+" ");
            }
        }
       public void deleteRow(String tableName,String rowKey) throws IOException{
       	init();
       	Table table = connection.getTable(TableName.valueOf(tableName));
       	Delete delete = new Delete(rowKey.getBytes());
       	table.delete(delete);
       	System.out.println("刪除成功!");
       	table.close();
       	close();
       }
    }

在這裏插入圖片描述
在這裏插入圖片描述
4、創建學生信息表
在這裏插入圖片描述
在這裏插入圖片描述
5、添加學生選課信息
在這裏插入圖片描述
6、瀏覽學生選課信息表
在這裏插入圖片描述
7、修改學生選課信息
在這裏插入圖片描述
在這裏插入圖片描述
8、刪除學生選課信息
在這裏插入圖片描述
運行結果如下
選擇1,創建學生選課表
在這裏插入圖片描述
再次創建,提示該表已經存在
在這裏插入圖片描述
選擇2,學生Zhangsan選課信息的錄入
在這裏插入圖片描述
Scan命令,查看插入成功的結果
在這裏插入圖片描述
選擇3,進行學生Zhangsan數學課程信息的查詢,結果如下
在這裏插入圖片描述
選擇4,進行學生Zhangsan數學成績的修改
在這裏插入圖片描述
Scan命令查詢結果(之前是86分,現在89分)
在這裏插入圖片描述
選擇5,進行學生Zhangsan一行的信息的刪除
在這裏插入圖片描述
Scan命令查詢結果(可見,zhangshan的信息已經被全部刪除)
在這裏插入圖片描述
做到這裏,本次HBase分佈式數據庫操作與編程基本完成,過程截圖不清楚或有問題的可以給我評論或私信,命令行代碼希望自己敲,可以加深理解,加油!
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章