//石家莊鐵道大學,軟件工程系:滄月88java
實驗環境:
一、 操做系統:Linux(建議Ubuntu16.04);數據庫
二、 Hadoop版本:2.7.1;編程
三、 JDK版本:1.7或以上版本; 四、 Java IDE:Eclipse。數組
實驗目的:
一、 理解HBase在Hadoop體系結構中的角色;bash
二、 熟練使用HBase操做經常使用的Shell命令;oop
三、 熟悉HBase操做經常使用的Java API。spa
實驗步驟:
(一)編程實現如下指定功能,並用 Hadoop 提供的 HBase Shell 命令完成相同任務:操作系統
(1) 列出 HBase 全部的表的相關信息,例如表名;code
list
(2) 在終端打印出指定的表的全部記錄數據;blog
scan '表名'
(3) 向已經建立好的表添加和刪除指定的列族或列;
alter '表名',NAME=>'列名'
alter '表名',NAME=>'列名',METHOD=>'delete'
(4) 清空指定的表的全部記錄數據;
truncate '表名'
(5) 統計表的行數。
count '表名'
(二)HBase 數據庫操做
1. 現有如下關係型數據庫中的表和數據,要求將其轉換爲適合於 HBase 存儲的表並插入數 據:
學生表(Student)
學號(S_No) |
姓名(S_Name) |
性別(S_Sex) |
年齡(S_Age) |
2015001 |
Zhangsan |
male |
23 |
2015003 |
Mary |
female |
22 |
2015003 |
Lisi |
male |
24 |
課程表(Course)
課程號(C_No) |
課程名(C_Name) |
學分(C_Credit) |
123001 |
Math |
2.0 |
123002 |
Computer Science |
5.0 |
123003 |
English |
3.0 |
選課表(SC)
學號(SC_Sno) |
課程號(SC_Cno) |
成績(SC_Score) |
2015001 |
123001 |
86 |
2015001 |
123003 |
69 |
2015002 |
123002 |
77 |
2015002 |
123003 |
99 |
2015003 |
123001 |
98 |
2015003 |
123002 |
95 |
建立表格思路:
(1)關係型數據庫轉成非關係型數據庫:本人的思路是:把關係型數據庫的一個主鍵設置爲行鍵,其餘主鍵設置爲一個列名。和行鍵一個表的其餘數據單獨成列。
(2)具體分割以下:把學號做爲行鍵,課程號做爲列名,student表的其餘數據成列。
代碼以下:(本身封裝了一個jar包)
Hbase_gao.createTable("SC",new String[]{"name","sex","age","123001","123002","123003"}); Hbase_gao.insertRow("SC", "2015001", "name","", "Zhangsan"); Hbase_gao.insertRow("SC", "2015001", "sex","", "male"); Hbase_gao.insertRow("SC", "2015001", "age", "", "23"); Hbase_gao.insertRow("SC", "2015001", "123001", "cname", "Math"); Hbase_gao.insertRow("SC", "2015001", "123001", "credit", "2.0"); Hbase_gao.insertRow("SC", "2015001", "123001", "score", "86"); Hbase_gao.insertRow("SC", "2015001", "123003", "cname", "English"); Hbase_gao.insertRow("SC", "2015001", "123003", "credit", "3.0"); Hbase_gao.insertRow("SC", "2015001", "123003", "score", "69"); Hbase_gao.insertRow("SC", "2015002", "name","", "Mary"); Hbase_gao.insertRow("SC", "2015002", "sex","", "female"); Hbase_gao.insertRow("SC", "2015002", "age", "", "22"); Hbase_gao.insertRow("SC", "2015002", "123002", "cname", "Computer Science"); Hbase_gao.insertRow("SC", "2015002", "123002", "credit", "5.0"); Hbase_gao.insertRow("SC", "2015002", "123002", "score", "77"); Hbase_gao.insertRow("SC", "2015002", "123003", "cname", "English"); Hbase_gao.insertRow("SC", "2015002", "123003", "credit", "3.0"); Hbase_gao.insertRow("SC", "2015002", "123003", "score", "99"); Hbase_gao.insertRow("SC", "2015003", "name","", "Lisi"); Hbase_gao.insertRow("SC", "2015003", "sex","", "male"); Hbase_gao.insertRow("SC", "2015003", "age", "", "24"); Hbase_gao.insertRow("SC", "2015003", "123001", "cname", "Math"); Hbase_gao.insertRow("SC", "2015003", "123001", "credit", "2.0"); Hbase_gao.insertRow("SC", "2015003", "123001", "score", "98"); Hbase_gao.insertRow("SC", "2015003", "123002", "cname", "Computer Science"); Hbase_gao.insertRow("SC", "2015003", "123002", "credit", "5.0"); Hbase_gao.insertRow("SC", "2015003", "123002", "score", "95");
2. 請編程實現如下功能:
連接語句:
//創建鏈接 public static void init(){ configuration = HBaseConfiguration.create(); configuration.set("hbase.rootdir","hdfs://本身ip: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(); } }
(1)createTable(String tableName, String[] fields)
建立表,參數 tableName 爲表的名稱,字符串數組 fields 爲存儲記錄各個字段名稱的數組。 要求當 HBase 已經存在名爲 tableName 的表的時候,先刪除原有的表,而後再建立新的表。
* 建表。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!");
admin.disableTable(tablename);
admin.deleteTable(tablename);
} 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(); }
(2)addRecord(String tableName, String row, String[] fields, String[] values)
向表 tableName、行 row(用 S_Name 表示)和字符串數組 fields 指定的單元格中添加對 應的數據 values。其中,fields 中每一個元素若是對應的列族下還有相應的列限定符的話,用 「columnFamily:column」表示。例如,同時向「Math」、「Computer Science」、「English」三列添加 成績時,字符串數組 fields 爲{「Score:Math」, 」Score:Computer Science」, 」Score:English」},數組 values 存儲這三門課的成績。
* 向某一行的某一列插入數據 * @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(); }
(3)scanColumn(String tableName, String column)
瀏覽表 tableName 某一列的數據,若是某一行記錄中該列數據不存在,則返回 null。要求 當參數 column 爲某一列族名稱時,若是底下有若干個列限定符,則要列出每一個列限定符表明 的列的數據;當參數 column 爲某一列具體名稱(例如「Score:Math」)時,只須要列出該列的 數據。
/** * 根據行鍵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(); }
(4)modifyData(String tableName, String row, String column)
修改表 tableName,行 row(能夠用學生姓名 S_Name 表示),列 column 指定的單元格的 數據。
* 向某一行的某一列插入數據 * @param tableName 表名 * @param rowKey 行鍵 * @param column 列族名 * @param val 值 * @throws IOException */ public static void modiyData(String tableName,String row,String column,String val) throws IOException { init(); Table table = connection.getTable(TableName.valueOf(tableName)); Put put = new Put(row.getBytes()); put.addColumn(column.getBytes(), val.getBytes()); table.put(put); table.close(); close(); }
(5)deleteRow(String tableName, String row)
刪除表 tableName 中 row 指定的行的記錄。
/** * 刪除數據 * @param tableName 表名 * @param row 行鍵 * @throws IOException */ public static void deleteRow(String tableName,String row) throws IOException { init(); Table table = connection.getTable(TableName.valueOf(tableName)); Delete delete = new Delete(row.getBytes()); table.delete(delete); table.close(); close(); }