//石家庄铁道大学,软件工程系:沧月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();
}