11.13
实验3
熟悉常用的HBase操作
1.实验目的
(1)理解HBase在Hadoop体系结构中的角色;
(2)熟练使用HBase操作常用的Shell命令;
(3)熟悉HBase操作常用的Java API。
2.实验平台
(1)操作系统:Linux(建议Ubuntu16.04或Ubuntu18.04);
(2)Hadoop版本:3.1.3;
(3)HBase版本:2.2.2;
(4)JDK版本:1.8;
(5)Java IDE:Eclipse。
3. 实验步骤
(一)编程实现以下指定功能,并用Hadoop提供的HBase Shell命令完成相同任务:
(1) 列出HBase所有的表的相关信息,例如表名;
(2) 在终端打印出指定的表的所有记录数据;
(3) 向已经创建好的表添加和删除指定的列族或列;
(4) 清空指定的表的所有记录数据;
(5) 统计表的行数。
(二)HBase数据库操作
1. 现有以下关系型数据库中的表和数据(见表14-3到表14-5),要求将其转换为适合于HBase存储的表并插入数据:
表14-3 学生表(Student)
学号(S_No) |
姓名(S_Name) |
性别(S_Sex) |
年龄(S_Age) |
2015001 |
Zhangsan |
male |
23 |
2015002 |
Mary |
female |
22 |
2015003 |
Lisi |
male |
24 |
表14-4 课程表(Course)
课程号(C_No) |
课程名(C_Name) |
学分(C_Credit) |
123001 |
Math |
2.0 |
123002 |
Computer Science |
5.0 |
123003 |
English |
3.0 |
表14-5 选课表(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 |
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表示)和字符串数组fields指定的单元格中添加对应的数据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指定的行的记录。
4.实验报告
题目: |
熟悉常用的HBase操作 |
姓名 |
刘雪超 |
日期:11.18 |
实验环境:(1)操作系统:Linux(建议Ubuntu16.04或Ubuntu18.04);2(2)Hadoop版本:3.1.3(3)HBase版本:2.2.2;(4)JDK版本:1.8;1(5)Java IDE:Eclipse。 |
||||
实验内容与完成情况: 一、 (1)列出HBase所有的表的相关信息 import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.client.HBaseAdmin; import org.apache.hadoop.hbase.TableName;
public class HBaseListTables { public static void main(String[] args) throws Exception { // 创建配置对象 HBaseConfiguration config = HBaseConfiguration.create(); try (HBaseAdmin admin = new HBaseAdmin(config)) { TableName[] tableNames = admin.listTableNames(); for (TableName tableName : tableNames) { System.out.println(tableName.getNameAsString()); } } } } (2)打印出指定表的所有记录数据 import org.apache.hadoop.hbase.CompareOperator; import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.client.ResultScanner; import org.apache.hadoop.hbase.client.Scan; import org.apache.hadoop.hbase.client.Table; import org.apache.hadoop.hbase.filter.SingleColumnValueFilter; import org.apache.hadoop.hbase.util.Bytes;
public class HBaseScanTable { public static void main(String[] args) throws Exception { String tableName = "your_table_name"; HBaseConfiguration config = HBaseConfiguration.create(); try (Table table = new HTable(config, tableName); ResultScanner scanner = table.getScanner(new Scan())) { for (Result result : scanner) { // 打印每行的数据 System.out.println(result); } } } } (3)向表添加和删除列族或列 import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.HTableDescriptor; import org.apache.hadoop.hbase.HColumnDescriptor; import org.apache.hadoop.hbase.client.HBaseAdmin; import org.apache.hadoop.hbase.TableName;
public class HBaseModifyColumns { public static void main(String[] args) throws Exception { String tableName = "your_table_name"; String columnFamilyToAdd = "cf_to_add"; String columnFamilyToDelete = "cf_to_delete";
HBaseConfiguration config = HBaseConfiguration.create(); try (HBaseAdmin admin = new HBaseAdmin(config)) { if (!admin.tableExists(TableName.valueOf(tableName))) { System.out.println("Table does not exist"); return; }
// 添加列族 HTableDescriptor tableDescriptor = admin.getTableDescriptor(TableName.valueOf(tableName)); tableDescriptor.addFamily(new HColumnDescriptor(columnFamilyToAdd)); admin.modifyTable(TableName.valueOf(tableName), tableDescriptor);
// 删除列族 admin.deleteColumnFamily(TableName.valueOf(tableName), Bytes.toBytes(columnFamilyToDelete)); } } } (4)清空指定表的所有记录数据 import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.client.HBaseAdmin; import org.apache.hadoop.hbase.TableName;
public class HBaseTruncateTable { public static void main(String[] args) throws Exception { String tableName = "your_table_name"; HBaseConfiguration config = HBaseConfiguration.create(); try (HBaseAdmin admin = new HBaseAdmin(config)) { admin.disableTable(TableName.valueOf(tableName)); admin.truncateTable(TableName.valueOf(tableName), true); } } } (5)统计表的行数 import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.client.ResultScanner; import org.apache.hadoop.hbase.client.Scan; import org.apache.hadoop.hbase.client.Table;
public class HBaseCountRows { public static void main(String[] args) throws Exception { String tableName = "your_table_name"; long count = 0; HBaseConfiguration config = HBaseConfiguration.create(); try (Table table = new HTable(config, tableName); ResultScanner scanner = table.getScanner(new Scan())) { for (Result result : scanner) { count++; } } System.out.println("Row count: " + count); } } 使用HBase Shell命令完成相同任务 启动HBase Shell后,你可以执行如下命令:
(1)列出所有表 list (2)扫描并打印指定表的所有记录 scan 'your_table_name' (3)添加和删除列族 添加列族(需要先禁用表): disable 'your_table_name' alter 'your_table_name', 'ADD' => {NAME => 'new_column_family'} enable 'your_table_name' 删除列族: disable 'your_table_name' alter 'your_table_name', 'DELETE' => 'column_family_to_delete' enable 'your_table_name' (4)清空表 disable 'your_table_name' truncate 'your_table_name' (5)统计表的行数 count 'your_table_name' 二、 HBase 表设计方案 1. 学生表(Student) 列族设计:info:存储学生基本信息。grades:存储学生选课成绩信息。 行键设计:使用学号(S_No)作为行键,因为它是唯一标识每个学生的字段。 2. 课程表(Course) 如果课程信息不会频繁变动,可以考虑将其直接嵌入到学生表中作为冗余数据,从而避免了多次表连接操作。但如果需要保持数据的一致性和减少冗余,也可以为课程创建独立的表: 列族设计:info:存储课程基本信息。 行键设计:使用课程号(C_No)作为行键,因为它是唯一标识每门课程的字段。 实际操作步骤 创建学生表(Student) create 'Student', {NAME => 'info'}, {NAME => 'grades'} 插入学生数据 put 'Student', '2015001', 'info:S_Name', 'Zhangsan' put 'Student', '2015001', 'info:S_Sex', 'male' put 'Student', '2015001', 'info:S_Age', '23' put 'Student', '2015001', 'grades:123001', '86' put 'Student', '2015001', 'grades:123003', '69'
# 对其他学生重复上述put命令... 创建课程表(Course) create 'Course', {NAME => 'info'} 插入课程数据 put 'Course', '123001', 'info:C_Name', 'Math' put 'Course', '123001', 'info:C_Credit', '2.0'
# 对其他课程重复上述put命令... 三、
|
||||
出现的问题:无 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通