NoSQL和关系数据库的操作比较实验及相关知识总结

NoSQL 和关系数据库的操作比较

因为这次实验涉及到的数据库比较多,而有些刚接触不了解,所以打算乘在实验的时候把一些操作和命令总结一下。

实验平台

操作系统:Linux
Hadoop 版本:2.10.0
MySQL (MariaDB)版本:MariaDB 10.3.22
HBase 版本:1.5
Redis 版本: 6.0.3
MongoDB 版本: 4.2.6
JDK 版本:1.8
Java IDE:Eclipse

Mysql

基本操作命令总结

  1. mysql的登录及连接
mysql [-h ip] -u username -p 
参数后面的值
-hmysql服务所在的主机地址(默认是本机:localhost)
-u用户名
-p用户密码(可以不急着写,等回车后输入)
  1. 数据库及表的创建
CREATE DATABASE 数据库名;  //创建数据库
DROP DATABASE 数据库名;    //删除数据库
SHOW DATABASES//显示所有数据库
USE 数据库名;              //选择数据库
//在选择的数据库中
CREATE TABLE  表名(列名 列数据类型);   //创建表
  • AUTO_INCREMENT定义列为自增的属性,一般用于主键,数值会自动加1。
  • PRIMARY KEY关键字用于定义列为主键。
  • 您可以定义多列,列间以逗号分隔。
  • ENGINE 设置存储引擎,CHARSET 设置编码。
//在选择的数据库中
DROP TABLE  表名;   //删除表
//在选择的数据库中
ALTER TABLE <表名> [修改选项] ;   //修改表结构

修改选项:

  • ADD COLUMN <列名> <类型> :增加一列
  • CHANGE COLUMN <旧列名> <新列名> <新列类型> :修改某列的列名或类型
  • ALTER COLUMN <列名> { SET DEFAULT <默认值> | DROP DEFAULT
  • MODIFY COLUMN <列名> <类型>
  • DROP COLUMN <列名>
  • RENAME TO <新表名>
  • CHARACTER SET <字符集名>
  • COLLATE <校对规则名>
DESCRIBE <表名>; //查看表结构
  1. 对数据的增删查改
// 插入数据
INSERT INTO table_name ( column1, column2,...columnN )
                       VALUES
                       ( value1, value2,...valueN );

//删除数据
DELETE FROM table_name [WHERE Clause]

//修改数据
UPDATE table_name SET column =new_value1, column =new_value2
[WHERE Clause]

//查找数据
SELECT column_name,column_name
FROM table_name
[WHERE Clause]
[LIMIT N][ OFFSET M]
  • SELECT * FROM table_name;:表示查看所有数据。
  • LIMIT N:显示前N行的数据
  • 查询语句是SQL的核心,这里就只介绍了简单的用法。
  1. 用户的权限授予
//授予权限用GRANT,回收权限用REVOKE
GRANT [SELECT,INSERT...] ON 数据库名.表名  TO  "用户名"@"主机ip或主机名" [ IDENTIFIED BY "用户密码"] [WITH GRANT OPTION]
  • @后面接主机的ip地址或主机名,比如"localhost",其中"%"表示任意主机。
  • WITH GRANT OPTION:可以被授权的用户,也可以将这些权限 grant 给其他用户。

实验部分

准备工作

安装好mysql,因为现在mysql可能要面临收费,所以可以下载mariaDB来代替一下。下载方式一种是下载安装包,然后解压进行操作。还有一种可以用命令代替,例如apt系列:

apt-get upgrade
apt-get install mysql-server //或者mariadb-server(可以根据提示来选择下哪个版本的)

下载好mysql-connector-java的jar包。并导入Eclipse的项目中
mysql的java驱动
进去网页里下载好后,解压下载的文件,在里面找到mysql-connector-java的jar包,然后将其导入到eclipse里。(PS:最好选zip或tar压缩文件,便于解压)

实验过程

设计出 student 学生表格:
先创建Student数据库:

CREATE DATABASE Student;

在这里插入图片描述
用 select 语句输出所有的相关信息:
在这里插入图片描述
查询 zhangsan 的 Computer 成绩:
在这里插入图片描述
修改 lisi 的 Math 成绩,改为 95:
在这里插入图片描述
.根据上面已经设计出的 student 表,用 MySQL 的 JAVA 客户端编程;
a) 添加数据:English:45 Math:89 Computer:100
b)获取 scofield 的 English 成绩信息
代码部分[^8]

import java.sql.*; 
public class MySQLExample 
{

    static final String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver";  
    static final String DB_URL = "jdbc:mysql://localhost:3306/Student?useSSL=false&serverTimezone=UTC";  //Student是数据库名
    static final String USER = "root";
    static final String PASS = "******";
 
 //添加一行记录
    public static void addRecord(Connection conn,String sql,String name,int english,int math,int computer)
    {
    	PreparedStatement ps;
		try 
		{
			ps = conn.prepareStatement(sql);
			ps.setString(1, name);
	    	ps.setInt(2, english);
	    	ps.setInt(3, math);
	    	ps.setInt(4, computer);
	    	ps.executeUpdate();
	    	System.out.println("添加成功!");
	    	ps.close();
		} catch (SQLException e) 
		{
			e.printStackTrace();
		}
    }
    //sql :select * from student where name = name
    public static void Search(Connection conn,String sql,String name,String score)
    {
    	PreparedStatement ps;
		try 
		{
			ps = conn.prepareStatement(sql);
			ps.setString(1, name);
			ResultSet rs = ps.executeQuery();
	    	while(rs.next())
	    	{
	    		System.out.print(name+":"+score+":");
	    		System.out.println(rs.getInt((score)));
	    	}
	    	rs.close();
	    	ps.close();
		} catch (SQLException e) 
		{
			e.printStackTrace();
		}
    }
    public static void main(String[] args) 
    { 
    //main方法可以根据后面截图修改(应该只需要取消或增加相应注释)
        Connection conn = null;
        try{
            Class.forName(JDBC_DRIVER);
            System.out.println("连接数据库...");
            conn = DriverManager.getConnection(DB_URL,USER,PASS);
            System.out.println(" 实例化Statement对象...");
//          String sql = "INSERT INTO Student VALUES(?,?,?,?);";
//          addRecord(conn,sql, "scofield", 45, 89, 100);
//            String sql = "SELECT * FROM  ";
//            Search(conn, sql, "scofield", "English");
            conn.close();
        }catch(SQLException se)
        {
            se.printStackTrace();
        }catch(Exception e)
        {
            e.printStackTrace();
        }finally
        {
            try
            {
                if(conn!=null) conn.close();
            }catch(SQLException se)
            {
                se.printStackTrace();
            }
        }
        System.out.println("Goodbye!");
    }
}

在这里插入图片描述
查看结果:
在这里插入图片描述
在这里插入图片描述

Hbase

基本操作命令总结 1

  • hbase的登录及连接
hbase shell //启动hbase shell
  • 表的创建和操作
list                                      //列出hbase中存在的所有表
create "表名","列族:列名"[, "列族:列名"...]  //创建表 
describe "表名"                           //显示表相关的详细信息

alter "表名", "列族名[:列名]"   //添加一个列族或列名
alter "表名", {NAME=> "列族名[:列名]", METHOD=> "delete"}  //删除一个列族或列名
truncate "表名"                                   //重新创建指定表
enable "表名"                                   //使表有效
disable "表名"                                  //使表无效
drop "表名"                                     //删除指定表 

ps:删除指定表时,该表必须处于无效状态

  • 对数据的增删查改
put "表名", "行键", "列族名", "列值"       //插入一行的某一列数据
//或者
put "表名", "行键", "列族名:列名", "列值"  //插入一行的某一列数据

delete "表名","行键", "列族名:列名"       // 删除指定行的列族的某个列的值
deleteall "表名","行键"                 // 删除指定行的所有元素值

因为实验中设置了只保留时间戳最新的数据,所以可以用put来对数据进行修改。

put "表名", "行键", "列族名:列名", "新的列值"  //修改一行的某一列数据

查找数据:

//scan 命令
scan "表名"      //扫描整个表
scan "表名",{COLUMN=>"列族名[:列名]"}    //扫描某个列族或某个列族的某个列

//get命令
get "表名","行键"        //获取某一行所有列的的值
get "表名","行键","列族名"  //获取某一行的单元(cell)的值
  • 其他一些常用命令
help "命令名"              //查看命令的使用描述
status                    //返回hbase集群的状态信息

实验部分

准备工作

首先需要成功启动hadoop,即执行

start-dfs.sh  //确保ssh服务开启了

命令。然后启动hbase:

start-hbase.sh   //(如果使用外部zookeeper的话,在该命令执行前先执行zkServer.sh start)

,接着为了能确保java能成功连上hbase。需要向eclipse里导入相关jar包。实验里只需要导入hbase安装目录中的lib文件中的所有jar包就可以了。

实验过程

根据上面给出的表格,用 Hbase Shell 模式设计 student 学生表格。
a) 设计完后,用 scan 指令浏览表的相关信息,给出截图。
在这里插入图片描述
b) 查询 zhangsan 的 Computer 成绩,给出截图。
在这里插入图片描述
c) 修改 lisi 的 Math 成绩,改为 95,给出截图。
在这里插入图片描述

  1. 根据上面给出的表格,用 Hbase Shell 模式设计 student 学生表格。
    a) 设计完后,用 scan 指令浏览表的相关信息,给出截图。
    b) 查询 zhangsan 的 Computer 成绩,给出截图。
    c) 修改 lisi 的 Math 成绩,改为 95,给出截图。
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;
public class HbaseExample{
    public static Configuration configuration;
    public static Connection connection;
    public static Admin admin;
public static void init()
    {
        configuration = HBaseConfiguration.create();
        configuration.set("hbase.rootdir","hdfs://localhost: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();
        }
    }
    public static void addRecord(String tableName,String row,String[] fields,String[] values) throws IOException 
    {
        init();
        Table table = connection.getTable(TableName.valueOf(tableName));
        Put put = new Put(row.getBytes());
        int count = 0;
        for (String str:fields)
        {
        	String[] temp = str.split(":");
        	String colFamily = temp[0];
        	String col = temp.length == 2 ? temp[1] : "";
            put.addColumn(colFamily.getBytes(), col.getBytes(), values[count].getBytes());
            count++;
        }
        table.put(put);
        table.close();
        close();
        System.out.println("addRecord success");
    }
    public static void main(String[] args)throws IOException
    {
      //main方法可以根据后面截图修改(应该只需要取消或增加相应注释)
      String tablename = "Student";
      String fields = {"name","score:English","score:Math","score:Computer"};
      String[] values = {"scofield","45","89","100"};    		   
      addRecord(tableName, "3", fields, values);

//      init();  //第二题的,做第二题的时候这个不能注掉
//    	try 
//    	{
//    		Table table = connection.getTable(TableName.valueOf(tableName));
//    		Get g = new Get("3".getBytes());
//    		g.addColumn("score".getBytes(),"English".getBytes());
//    		Result re = table.get(g);
//    		Cell[] cells = re.rawCells();
//    		for(Cell cell:cells)
//            {
//                System.out.print("column Family:"+new String(CellUtil.cloneFamily(cell))+" "); 
//                System.out.print("row Name:"+new String(CellUtil.cloneQualifier(cell))+" ");
//                System.out.println("value:"+new String(CellUtil.cloneValue(cell))+" ");
//            }
//		} catch (Exception e) 
//    	{
//			e.printStackTrace();
//		}
    }
   

实验部分:
在这里插入图片描述
查看结果:
在这里插入图片描述
在这里插入图片描述

Redis

基本操作命令总结

  • redis的登录及连接
redis-server   //在redis安装目录中的src里执行,开启redis服务

redis-cli //进入redis
  • 字符串命令2
SET key value  //设置指定 key 的值
GET key        //获取指定 key 的值。
GETSET key value   //将给定 key 的值设为 value,并返回 key 的旧值(old value)。
  • 哈希(Hash)命令3
HMSET key field1 value1 [field2 value2 ]  //同时将多个field-value(域-值)对设置到哈希表key中。
HSET key field value      //将哈希表key中的字段field的值设为value 。
HGET key field            //获取存储在哈希表中指定字段的值。
HGETALL key               //获取在哈希表中指定key的所有字段和值
HDEL key field1 [field2]  //删除一个或多个哈希表字段
HKEYS key                 //获取所有哈希表中的字段
HVALS key                 //获取哈希表中所有值。

实验中主要是针对Hash的操作,因此关于其他数据类型的介绍比较少,如有需要可以查看以下资料:
官方文档
中文官方文档
Redis 列表(List)介绍
Redis 集合(Set)介绍

实验部分

准备工作

安装好Redis。仍然有两种方式:一种用直接下,例如:

sudo apt-get install redis-server

还有一种把安装包下下来,然后解压,进入目录执行

make

执行成功后,再执行

make install 

就成功安装好了。
同样,在写java代码的时候需要导入jar包。
jedis下载地址
此外,下面网站也提供2.9.0 jar版本下载4
jedis-2.9.0.jar

实验过程

根据上面给出的键值对,用 Redis 的哈希结构设计出上述表格;(键值可以用student.zhangsan,student.lisi 来表示两个键值属于同一个表格)
a) 设计完之后,用 hgetall 命令分别输出 zhangsan 和 lisi 的成绩信息,并截图;
b) 用 hget 命令查询 zhangsan 的 Computer 成绩,给出截图。
c) 修改 lisi 的 Math 成绩,改为 95,给出截图。
在这里插入图片描述
根据上面已经设计出的 student 表格,用 Redis 的 JAVA 客户端编程(jedis)
a ) 添加数据:English:45 Math:89 Computer:100
b) 获取 scofield 的 English 成绩信息
代码部分:


import redis.clients.jedis.Jedis;
public class RedisExample 
{
	 	    public static void main(String[] args) 
	 	    {
	 	    //https://blog.csdn.net/lixiaoxiong55/article/details/81592800
	        //连接本地的 Redis 服务
	        Jedis jedis = new Jedis("localhost");
	        System.out.println("连接成功");
//	        jedis.hset("Student.scofield", "English", "45");
//	        jedis.hset("Student.scofield", "Math", "89");
//	        jedis.hset("Student.scofield", "Computer","100");
//	        System.out.println("success!");
	        String re = jedis.hget("Student.scofield", "English");  
	        System.out.println(re); 
	    }
}

实验结果:
在这里插入图片描述
在Redis shell里查看结果:
在这里插入图片描述

在这里插入图片描述
对于redis,重启后保存的数据丢失的问题:因为redis数据是存在内存里的,所以重启后会丢失,如果想保存,需要编辑/etc/sysctl.conf ,改vm.overcommit_memory=1,然后sysctl -p 使配置文件生效。

MongoDB

基本操作命令总结

  • mongodb的登录及连接
mongod [-f mongodb.conf]  //开启mongodb服务
mongo //进入mongodb shell里
  • 数据库及集合的创建
show dbs;   //显示当前所有的数据库
use 数据库名   //选择指定数据库,如果没有该数据库,则自动创建该数据库。如果use之后没有创建任何集合。系统就会删除这个数据库。
db.dropDatabase()  //删除当前选择的数据库 ,如果没有选择任何数据库,会删除默认的test数据库


show collections;   //查看所有集合
db.createCollection('集合名')      // 创建集合
db.集合名.drop()                   //删除指定集合
  • 对数据的增删查改
db.集合名.insertOne(Bson)   // 插入一条数据,返回值返回插入的insertedId ,也可用insert({}) 
db.集合名.insertMany(Bson)  //插入多条数据 也可用insert({},{})
db.集合名.remove(<query>,
{justOne: <boolean>,
writeConcern:<document>}

query :(可选)删除的文档的条件。5
justOne : (可选)如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值 false,则删除所有匹配条件的文档。
writeConcern :(可选)抛出异常的级别。

db.集合名.find(query, projection)

query :可选,使用查询操作符指定查询条件6
projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。

db.集合名.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   }
)

query : update的查询条件,类似sql update查询内where后面的。7
update : update的对象和一些更新的操作符(如 , , ,inc…)等,也可以理解为sql update查询内set后面的
upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
writeConcern :可选,抛出异常的级别。

上面是一些基本命令,其中详细介绍和其他命令可以查看以下资料:
官方文档
MongoDB基础篇:MongoDB Shell命令大全
mongodb命令行操作

实验部分

准备工作

安装好mongodb:有两种方法,第一种是采用直接下的方式,例如

sudo apt-get install mongodb

还有一种是下载安装包,然后进行解压的方式,个人比较推荐第一种,第二种容易出错。
然后开启mongodb服务。
为了使java能连上mongodb,需要下载驱动,一种使用maven项目的方式mongodb-java-driver。非maven项目的可以直接下jar包。直接下jar包网址
先选择一个版本,然后点击jar下载。
在这里插入图片描述
下载好后记得导入eclipse项目中。

实验过程
  1. 根据上面给出的文档,用 Mongo shell 设计出 student 集合.
    a) 设计完后,用 find()方法输出两个学生的信息,给出截图;
    在这里插入图片描述
    在这里插入图片描述
    b) 用 find 函数查询 zhangsan 的所有成绩(只显示 score 列),给出截图。
    在这里插入图片描述
    c) 修改 lisi 的 Math 成绩,改为 95,给出截图。
    在这里插入图片描述

  2. 根据上面已经设计出的 student 集合,用 MongoDB 的 JAVA 客户端编程
    a) 添加数据:English:45 Math:89 Computer:100
    b) 获取 scofield 的所有成绩成绩信息(只显示 score 列)
    代码部分:


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.bson.Document;
import org.bson.conversions.Bson;
import com.mongodb.*;
import com.mongodb.client.*;
import com.mongodb.client.model.Filters;


public class MongodbExample 
{
	MongoClient mongoClient;
	MongoDatabase mongoDatabase;
	public MongodbExample(String databasename)
	{
		this.getConnect(databasename);
	}
	public MongodbExample(String username,String password,String databasename)
	{
		this.getConnectByPassword(username, password, databasename);
	}
    public  void getConnect(String databasename)
    {
        mongoClient = new MongoClient("localhost", 27017);
        this.mongoDatabase = mongoClient.getDatabase(databasename);
        System.out.println("Connect Success!");
    }
    public  void getConnectByPassword(String username,String password,String databasename)
    {
        List<ServerAddress> adds = new ArrayList<>();
        ServerAddress serverAddress = new ServerAddress("localhost", 27017);
        adds.add(serverAddress);
        List<MongoCredential> credentials = new ArrayList<>();
        MongoCredential mongoCredential = MongoCredential.createScramSha1Credential(username, databasename, password.toCharArray());
        credentials.add(mongoCredential);
        mongoClient = new MongoClient(adds, credentials);
        this.mongoDatabase = mongoClient.getDatabase(databasename);
        System.out.println("Connect Success!");
    }
    public static void insertOne(MongoDatabase mongoDatabase,String collectionname,Document document)
    {
        MongoCollection<Document> collection = mongoDatabase.getCollection(collectionname);
        collection.insertOne(document);
        System.out.println("Insert document Success!");
    }
    public static void insertMany(MongoDatabase mongoDatabase,String collectionname,List<Document> documents)
    {
    	MongoCollection<Document> collection = mongoDatabase.getCollection(collectionname);
    	collection.insertMany(documents);
    	System.out.println("Insert documents Success!");

    }
    public static void findAll(MongoDatabase mongoDatabase,String collectionname)
    {
    	MongoCollection<Document> collection = mongoDatabase.getCollection(collectionname);
    	FindIterable<Document> findIterable = collection.find();
    	MongoCursor<Document> cursor = findIterable.iterator();
    	while (cursor.hasNext()) 
    	{
    		System.out.println(cursor.next());
    	}
    }
    public static void find(MongoDatabase mongoDatabase,String collectionname,String key,String value)
    {
    	MongoCollection<Document> collection = mongoDatabase.getCollection(collectionname);
    	Bson filter = Filters.eq(key, value);
    	FindIterable<Document> findIterable = collection.find(filter);
    	MongoCursor<Document> cursor = findIterable.iterator();
    	while (cursor.hasNext()) 
    	{
    		System.out.println(cursor.next());
    	}
    }
    public static FindIterable<Document> findReturn(MongoDatabase mongoDatabase,String collectionname,String key,String value)
    {
    	MongoCollection<Document> collection = mongoDatabase.getCollection(collectionname);
    	Bson filter = Filters.eq(key, value);
    	FindIterable<Document> findIterable = collection.find(filter);
    	return findIterable;
    }
	public static void main(String[] args) 
	{
		MongodbExample m = new MongodbExample("Student");
//		Document document = new Document("name","scofield");
//		Document value = new Document("English", "45");
//		value.append("Math", 89);
//		value.append("Computer", "100");
//		document.append("score", value);
//		insertOne(m.mongoDatabase, "Student", document);
//		findAll(m.mongoDatabase, "Student");
		FindIterable<Document> re = findReturn(m.mongoDatabase, "Student", "name", "scofield");
		Document results = re.first();
		System.out.println(results.get("score"));
	}
}

实验结果:
在这里插入图片描述
在mongodb shell 里查看结果:
在这里插入图片描述

在这里插入图片描述

java连接mysql
大数据原理与应用 第四章 分布式数据库HBase 学习指南


  1. https://blog.csdn.net/vbirdbest/article/details/88236575 ↩︎

  2. https://www.runoob.com/redis/redis-strings.html ↩︎

  3. https://www.runoob.com/redis/redis-hashes.html ↩︎

  4. https://www.runoob.com/redis/redis-java.html ↩︎

  5. https://www.runoob.com/mongodb/mongodb-remove.html ↩︎

  6. https://www.runoob.com/mongodb/mongodb-query.html ↩︎

  7. https://www.runoob.com/mongodb/mongodb-update.html ↩︎

  • 8
    点赞
  • 76
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实验比较NoSQL关系数据库操作。 首先,NoSQL数据库相对于关系数据库来说更加灵活和扩展性强。NoSQL数据库可以支持非结构化和半结构化数据,而关系数据库只支持结构化数据。这意味着在NoSQL数据库中可以存储更加复杂和多样化的数据类型,比如文档、图形和键值对等。 其次,NoSQL数据库的存储模型和数据结构灵活性更大。NoSQL数据库采用了不同的存储模型,比如键值对、列族、文档型和图形数据库等。每种存储模型都有自己的优势和适用场景,可以根据具体需求选择最合适的模型。而关系数据库只支持表格结构,需要预先定义表的模式和字段。 另外,NoSQL数据库在读写性能方面通常表现更好。NoSQL数据库可以水平扩展,即通过增加服务器节点来提高读写吞吐量,而关系数据库通常只能通过垂直扩展,即增加服务器的硬件性能来提高吞吐量。因此,在处理大规模数据和高并发的场景下,NoSQL数据库的性能更好。 然而,相对于关系数据库NoSQL数据库的一致性和事务支持通常较弱。由于NoSQL数据库通常采用分布式架构,数据的一致性和并发控制可能存在较大挑战,需要应用程序自己处理。而关系数据库通常具有强一致性和严格的事务支持。 综上所述,NoSQL关系数据库操作有一些重要的区别。NoSQL数据库更加灵活和可扩展,适用于非结构化和半结构化数据的存储;关系数据库则更加适合结构化数据,并具有更强的一致性和事务支持。根据具体需求,可以选择合适的数据库类型来处理不同类型的数据和场景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值