//石家庄鐵道大學,軟件工程系:滄月88
實驗環境:
1、 操作系統:Linux(建議Ubuntu16.04);
2、 Hadoop版本:2.7.1;
3、 JDK版本:1.7或以上版本; 4、 Java IDE:Eclipse。
實驗目的:
1、 理解HBase在Hadoop體系結構中的角色;
2、 熟練使用HBase操作常用的Shell命令;
3、 熟悉HBase操作常用的Java API。
實驗步驟:
(一)編程實現以下指定功能,並用 Hadoop 提供的 HBase Shell 命令完成相同任務:
(1) 列出 HBase 所有的表的相關信息,例如表名;
list

(2) 在終端打印出指定的表的所有記錄數據;
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();
}
