实验四:NoSQL和关系数据库的操作比较
一、实验目的
理解四种数据库(MySQL、HBase、Redis和MongoDB)的概念以及不同点;
熟练使用四种数据库操作常用的Shell命令;
熟悉四种数据库操作常用的Java API。
二、实验平台
操作系统:Linux(CentOS 7);
Hadoop版本:2.7.3;
Xshell版本:Xshell 8。
JDK版本:1.7或以上版本;
Java IDE:IDEA 2021.3.1。
MySQL版本:5.6.49;
HBase版本:1.1.2;
Redis版本:3.0.6;
MongoDB版本:3.2.6;
Java IDE:Eclipse;
三、实验步骤
(一) MySQL数据库操作
学生表Student
Name | English | Math | Computer |
zhangsan | 69 | 86 | 77 |
lisi | 55 | 100 | 88 |
1. 根据上面给出的Student表,在MySQL数据库中完成如下操作:
(1)在MySQL中创建Student表,并录入数据;
(2)用SQL语句输出Student表中的所有记录;
(3)查询zhangsan的Computer成绩;
(4)修改lisi的Math成绩,改为95。
2. 根据上面已经设计出的Student表,使用MySQL的JAVA客户端编程实现以下操作:
首先在porn.xml中添加MySQL依赖:
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.33</version>
</dependency>
(1)向Student表中添加如下所示的一条记录:
scofield | 45 | 89 | 100 |
package com.example;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
public class Four_Mysql
{
public static void main(String[] args) {
String url = "jdbc:mysql://namenode:3306/School";
String user = "root";
String password = "000000";
try (Connection connection = DriverManager.getConnection(url, user, password)) {
// 插入数据
String insertQuery = "INSERT INTO Student (Name, English, Math, Computer) VALUES (?, ?, ?, ?)";
PreparedStatement preparedStatement = connection.prepareStatement(insertQuery);
preparedStatement.setString(1, "scofield");
preparedStatement.setInt(2, 45);
preparedStatement.setInt(3, 89);
preparedStatement.setInt(4, 100);
int rowsAffected = preparedStatement.executeUpdate();
System.out.println("Rows inserted: " + rowsAffected);
} catch (Exception e) {
e.printStackTrace();
}
}
}
在MySQL中查看数据信息
(2)获取scofield的English成绩信息
package com.example;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class Four_Mysql2 {
public static void main(String[] args) {
String url = "jdbc:mysql://192.168.10.200:3306/school";
String user = "root";
String password = "000000";
try (Connection connection = DriverManager.getConnection(url, user, password)) {
// 查询数据
String selectQuery = "SELECT English FROM Student WHERE Name = ?";
PreparedStatement preparedStatement = connection.prepareStatement(selectQuery);
preparedStatement.setString(1, "scofield");
ResultSet resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
int englishScore = resultSet.getInt("English");
System.out.println("scofield's English score: " + englishScore);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
(二)HBase数据库操作
学生表Student
name | score | |||
English | Math | Computer | ||
zhangsan | 69 | 86 | 77 | |
lisi | 55 | 100 | 88 |
1. 根据上面给出的学生表Student的信息,执行如下操作:
(1)用Hbase Shell命令创建学生表Student;
(2)用scan命令浏览Student表的相关信息;
(3)查询zhangsan的Computer成绩;
(4)修改lisi的Math成绩,改为95。
2. 根据上面已经设计出的Student表,用HBase API编程实现以下操作:
(1)添加数据:English:45 Math:89 Computer:100
scofield | 45 | 89 | 100 |
package com.example;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;
public class Four_Hb {
public static void main(String[] args) throws Exception {
// 配置 HBase 连接
Configuration config = HBaseConfiguration.create();
// 加载 hbase-site.xml 配置文件
config.addResource(new Path("hbase-site.xml"));
config.set("hbase.zookeeper.quorum", "192.168.10.200");
config.set("hbase.zookeeper.property.clientPort", "2181");
// 创建连接
try (Connection connection = ConnectionFactory.createConnection(config)) {
// 获取表句柄
TableName tableName = TableName.valueOf("Student1");
Table table = connection.getTable(tableName);
// 添加数据
addStudentData(table);
// 获取 scofield 的 English 成绩信息
getStudentEnglishScore(table, "scofield");
// 关闭表
table.close();
}
}
// 添加学生数据到 HBase 表
private static void addStudentData(Table table) throws Exception {
// 定义行键
String rowKey = "scofield";
// 创建 Put 对象
Put put = new Put(Bytes.toBytes(rowKey));
put.addColumn(Bytes.toBytes("English"), Bytes.toBytes("score"), Bytes.toBytes("45"));
put.addColumn(Bytes.toBytes("Math"), Bytes.toBytes("score"), Bytes.toBytes("89"));
put.addColumn(Bytes.toBytes("Computer"), Bytes.toBytes("score"), Bytes.toBytes("100"));
// 插入到 HBase
table.put(put);
System.out.println("scofield的数据添加成功。");
}
// 获取 scofield 的 English 成绩信息
private static void getStudentEnglishScore(Table table, String rowKey) throws Exception {
// 创建 Get 对象
Get get = new Get(Bytes.toBytes(rowKey));
get.addColumn(Bytes.toBytes("English"), Bytes.toBytes("score"));
// 获取结果
Result result = table.get(get);
byte[] englishScore = result.getValue(Bytes.toBytes("English"), Bytes.toBytes("score"));
// 输出成绩
if (englishScore != null) {
System.out.println(rowKey + "'s English score: " + Bytes.toString(englishScore));
} else {
System.out.println("No English score found for " + rowKey);
}
}
}
HBase shell中查看表内容。
(2)获取scofield的English成绩信息。
package com.example;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.Bytes;
public class Four_Hb {
public static void main(String[] args) throws Exception {
// 配置 HBase 连接
Configuration config = HBaseConfiguration.create();
// 加载 hbase-site.xml 配置文件
config.addResource(new Path("hbase-site.xml"));
config.set("hbase.zookeeper.quorum", "192.168.10.200");
config.set("hbase.zookeeper.property.clientPort", "2181");
// 创建连接
try (Connection connection = ConnectionFactory.createConnection(config)) {
// 获取表句柄
TableName tableName = TableName.valueOf("Student1");
Table table = connection.getTable(tableName);
// 添加数据
addStudentData(table);
// 获取 scofield 的 English 成绩信息
getStudentEnglishScore(table, "scofield");
// 关闭表
table.close();
}
}
// 添加学生数据到 HBase 表
private static void addStudentData(Table table) throws Exception {
// 定义行键
String rowKey = "scofield";
// 创建 Put 对象
Put put = new Put(Bytes.toBytes(rowKey));
put.addColumn(Bytes.toBytes("English"), Bytes.toBytes("score"), Bytes.toBytes("45"));
put.addColumn(Bytes.toBytes("Math"), Bytes.toBytes("score"), Bytes.toBytes("89"));
put.addColumn(Bytes.toBytes("Computer"), Bytes.toBytes("score"), Bytes.toBytes("100"));
// 插入到 HBase
table.put(put);
System.out.println("scofield的数据添加成功。");
}
// 获取 scofield 的 English 成绩信息
private static void getStudentEnglishScore(Table table, String rowKey) throws Exception {
// 创建 Get 对象
Get get = new Get(Bytes.toBytes(rowKey));
get.addColumn(Bytes.toBytes("English"), Bytes.toBytes("score"));
// 获取结果
Result result = table.get(get);
byte[] englishScore = result.getValue(Bytes.toBytes("English"), Bytes.toBytes("score"));
// 输出成绩
if (englishScore != null) {
System.out.println(rowKey + "'s English score: " + Bytes.toString(englishScore));
} else {
System.out.println("No English score found for " + rowKey);
}
}
}
(三)Redis数据库操作
Student键值对如下:
zhangsan:{ English: 69 Math: 86 Computer: 77 } lisi:{ English: 55 Math: 100 Computer: 88 } |
1. 根据上面给出的键值对,完成如下操作:
(1)用Redis的哈希结构设计出学生表Student(键值可以用student.zhangsan和student.lisi来表示两个键值属于同一个表);
(2)用hgetall命令分别输出zhangsan和lisi的成绩信息;
(3)用hget命令查询zhangsan的Computer成绩;
(4)修改lisi的Math成绩,改为95。
2. 根据上面已经设计出的学生表Student,用Redis的JAVA客户端编程(jedis),实现如下操作:
(1)添加数据:English:45 Math:89 Computer:100
该数据对应的键值对形式如下:
scofield:{ English: 45 Math: 89 Computer: 100 } |
package com.example;
import redis.clients.jedis.Jedis;
public class Four_Redis {
public static void main(String[] args) {
// 创建Jedis连接
Jedis jedis = new Jedis("192.168.10.200", 6379); // 确保Redis服务在localhost的6379端口运行
// 添加数据到Redis
String key = "scofield";
jedis.hset(key, "English", "45");
jedis.hset(key, "Math", "89");
jedis.hset(key, "Computer", "100");
// 获取scofield的English成绩
String englishScore = jedis.hget(key, "English");
System.out.println("Scofield's English score: " + englishScore);
// 关闭连接
jedis.close();
}
}
(2)获取scofield的English成绩信息
(四)MongoDB数据库操作
Student文档如下:
{ “name”: “zhangsan”, “score”: { “English”: 69, “Math”: 86, “Computer”: 77 } } { “name”: “lisi”, “score”: { “English”: 55, “Math”: 100, “Computer”: 88 } } |
1. 根据上面给出的文档,完成如下操作:
(1)用MongoDB Shell设计出student集合;
(2)用find()方法输出两个学生的信息;
(3)用find()方法查询zhangsan的所有成绩(只显示score列);
(4)修改lisi的Math成绩,改为95。
2. 根据上面已经设计出的Student集合,用MongoDB的Java客户端编程,实现如下操作:
(1)添加数据:English:45 Math:89 Computer:100
与上述数据对应的文档形式如下:
{ “name”: “scofield”, “score”: { “English”: 45, “Math”: 89, “Computer”: 100 } } |
package com.example;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;
public class Four_MongoDB {
public static void main(String[] args) {
// MongoDB 连接字符串
String uri = "mongodb://192.168.10.200:27017";
try (MongoClient mongoClient = MongoClients.create(uri)) {
System.out.println("Connection successful!");
// 连接到数据库
MongoDatabase database = mongoClient.getDatabase("school");
// 连接到集合
MongoCollection<Document> collection = database.getCollection("students");
// (1) 添加数据
Document student = new Document("name", "scofield")
.append("score", new Document("English", 45)
.append("Math", 89)
.append("Computer", 100));
collection.insertOne(student);
System.out.println("Document inserted!");
// (2) 获取 scofield 的成绩信息,只显示 score 列
Document query = new Document("name", "scofield");
Document projection = new Document("score", 1).append("_id", 0);
Document result = collection.find(query).projection(projection).first();
if (result != null) {
System.out.println("Scofield's scores: " + result.toJson());
} else {
System.out.println("No document found with name 'scofield'.");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
(2)获取scofield的所有成绩成绩信息(只显示score列)