MySQL数据库

MySQL

一 数据库概念

数据库是“按照数据结构来组织、存储和管理数据的仓库。是一个长期存储在计算机内的、有组织的、有共享的、统一管理的数据集合。

二 SQL语言

经验:通常执行对数据库的“增删改查”,简称C(Create)R(Read)U(Update)D(Delete)。

2.1数据库操作

创建自定义数据库

mysql> CREATE DATABASE mydb1; #创建mydb数据库
mysql> CREATE DATABASE mydb2 CHARACTER SET gbk; #创建数据库并设置编码格式为gbk
mysql> CREATE DATABASE IF NOT EXISTS mydb4; #如果mydb4数据库不存在,则创建;如果存在,则不创建。

修改数据库

mysql> ALTER DATABASE mydb2 CHARACTER SET gbk; #查看创建数据库时的基本信息

删除数据库

mysql> DROP DATABASE mydb1; #删除数据库mydb1

使用数据库

mysql> USE mydb1; #使用mydb1数据库

三 数据查询

3.1 基本查询

语法:SELECT 列名 FROM 表名

关键字描述
SELECT指定要查询的列
FROM指定要查询的表

3.1.1 查询部分列

#查询员工表中所有员工的编号、名字、邮箱
SELECT employee_id,first_name,email 
FROM t_employees;

3.1.2 查询所有列

#查询员工表中所有员工的所有信息(所有列)
SELECT 所有列的列名 FROM t_employees;
SELECT * FROM t_employees;

3.1.3 对列中的数据进行运算

#查询员工表中所有员工的编号、名字、年薪
SELECT employee_id , first_name , salary*12 
FROM t_employees;
算数运算符描述
+两列做加法运算
-两列做减法运算
*两列做乘法运算
/两列做除法运算

注意:%是占位符,而非模运算符。

3.1.4 列的别名

列 as ‘列名’

#查询员工表中所有员工的编号、名字、年薪(列名均为中文)
SELECT employee_id as "编号" , first_name as "名字" , salary*12 as "年薪" 
FROM t_employees;

3.1.4 查询结果去重

DISTINCT 列名

#查询员工表中所有经理的ID。
SELECT DISTINCT manager_id 
FROM t_employees;

3.2 基本查询

语法: SELECT 列名 FROM 表名 ORDER BY 排序列 [排序规则]

排序规则描述
ASC对前面排序列做升序排序
DESC对前面排序列做降序排序

3.2.1 依据单列排序

#查询员工的编号,名字,薪资。按照工资高低进行降序排序。
SELECT employee_id , first_name , salary
FROM t_employees
ORDER BY salary DESC;

3.2.2 依据单列排序

#查询员工的编号,名字,薪资。按照工资高低进行升序排序(薪资相同时,按照编号进行升序排序)。
SELECT employee_id , first_name , salary
FROM t_employees
ORDER BY salary DESC , employee_id ASC;

3.3 条件查询

语法:SELECT 列名 FROM 表名 WHERE 条件

关键字描述
WHERE 条件在查询结果中,筛选符合条件的查询结果,条件为布尔表达式

3.3.1 等值判断(=)

#查询薪资是11000的员工信息(编号、名字、薪资)
SELECT employee_id , first_name , salary
FROM t_employees
WHERE salary = 11000;

3.3.2 逻辑判断(and、or、not)

#查询薪资是11000并且提成是0.30的员工信息(编号、名字、薪资)
SELECT employee_id , first_name , salary
FROM t_employees
WHERE salary = 11000 AND commission_pct = 0.30;

3.3.3 不等值判断(> 、< 、>= 、<= 、!= 、<>)

#查询员工的薪资在6000~10000之间的员工信息(编号,名字,薪资)
SELECT employee_id , first_name , salary
FROM t_employees
WHERE salary >= 6000 AND salary <= 10000;

3.3.4 区间判断(between and)

#查询员工的薪资在6000~10000之间的员工信息(编号,名字,薪资)
SELECT employee_id , first_name , salary
FROM t_employees
WHERE salary BETWEEN 6000 AND 10000; #闭区间,包含区间边界的两个值

3.3.5 NULL 值判断(IS NULL、IS NOT NULL)

  • IS NULL —> 列名 IS NULL
  • IS NOT NULL–>列名 IS NOT NULL
#查询没有提成的员工信息(编号,名字,薪资 , 提成)
SELECT employee_id , first_name , salary , commission_pct
FROM t_employees
WHERE commission_pct IS NULL;

3.3.6 枚举查询( IN (值 1,值 2,值 3 ) )

#查询部门编号为70、80、90的员工信息(编号,名字,薪资 , 部门编号)
SELECT employee_id , first_name , salary , department_id
FROM t_employees
WHERE department_id IN(70,80,90);

3.3.7 模糊查询

  • LIKE _ (单个任意字符)
    列名 LIKE ‘张_’
  • LIKE %(任意长度的任意字符)
    列名 LIKE ‘张%’
#查询名字以"L"开头的员工信息(编号,名字,薪资 , 部门编号)
SELECT employee_id , first_name , salary , department_id
FROM t_employees
WHERE first_name LIKE 'L%';

#查询名字以"L"开头并且长度为4的员工信息(编号,名字,薪资 , 部门编号)
SELECT employee_id , first_name , salary , department_id
FROM t_employees
WHERE first_name LIKE 'L___';

3.3.8 分支结构查询

CASE
	WHEN 条件1 THEN 结果1
	WHEN 条件2 THEN 结果2
	WHEN 条件3 THEN 结果3
	ELSE 结果
END
#查询员工信息(编号,名字,薪资 , 薪资级别<对应条件表达式生成>)
SELECT employee_id , first_name , salary , department_id , 
       CASE
           WHEN salary>=10000 THEN 'A'
           WHEN salary>=8000 AND salary<10000 THEN 'B'
           WHEN salary>=6000 AND salary<8000  THEN 'C'
           WHEN salary>=4000 AND salary<6000  THEN 'D'
   ELSE 'E'
       END as "LEVEL"
FROM t_employees;

3.4 时间查询

语法:SELECT 时间函数([参数列表])

-经验:执行时间函数查询,会自动生成一张虚表(一行一列)

时间函数描述
SYSDATE()当前系统时间(日、月、年、时、分、秒)
CURDATE()获取当前日期
CURTIME()获取当前时间
WEEK(DATE)获取指定日期为一年中的第几周
YEAR(DATE)获取指定日期的年份
HOUR(TIME)获取指定时间的小时值
MINUTE(TIME)获取时间的分钟值
DATEDIFF(DATE1,DATE2)获取DATE1 和 DATE2 之间相隔的天数
ADDDATE(DATE,N)计算DATE 加上 N 天后的日期

3.4.1 获得当前系统时间

#查询当前时间
SELECT SYSDATE();
#查询当前时间
SELECT NOW();
#获取当前日期
SELECT CURDATE();
#获取当前时间
SELECT CURTIME();

3.5 字符串查询

语法: SELECT 字符串函数 ([参数列表])

字符串函数说明
CONCAT(str1,str2,str…)将 多个字符串连接
INSERT(str,pos,len,newStr)将str 中指定 pos 位置开始 len 长度的内容替换为 newStr
LOWER(str)将指定字符串转换为小写
UPPER(str)将指定字符串转换为大写
SUBSTRING(str,num,len)将str 字符串指定num位置开始截取 len 个内容

3.5.1 字符串应用

#拼接内容
SELECT CONCAT('My','S','QL');
#字符串替换
SELECT INSERT('这是一个数据库',3,2,'MySql');#结果为这是 MySql 数据库
#指定内容转换为小写
SELECT LOWER('MYSQL');
#指定内容转换为大写
SELECT UPPER('mysql');
#指定内容截取
SELECT SUBSTRING('JavaMySQLOracle',5,5);

3.6 聚合函数

语法:SELECT 聚合函数(列名) FROM 表名;

聚合函数说明
SUM()求所有行中单列结果的总和
AVG()平均值
MAX()最大值
MIN()最小值
COUNT()求总行数

注意:聚合函数自动忽略null值,不进行统计。

3.7 分组查询

语法:SELECT 列名 FROM 表名 WHERE 条件 GROUP BY 分组依据(列);

关键字说明
GROUP BY分组依据,必须在 WHERE 之后生效

3.7.1 查询各部门的总人数

#思路:
#1.按照部门编号进行分组(分组依据是 department_id)
#2.再针对各部门的人数进行统计(count)
SELECT department_id,COUNT(employee_id)
FROM t_employees
GROUP BY department_id; 

3.7.2 查询各部门的平均工资

#思路:
#1.按照部门编号进行分组(分组依据department_id)。
#2.针对每个部门进行平均工资统计(avg)。
SELECT department_id , AVG(salary)
FROM t_employees
GROUP BY department_id;

3.7.3 查询各个部门、各个岗位的人数

#思路:
#1.按照部门编号进行分组(分组依据 department_id)。
#2.按照岗位名称进行分组(分组依据 job_id)。
#3.针对每个部门中的各个岗位进行人数统计(count)。
SELECT department_id , job_id , COUNT(employee_id)
FROM t_employees
GROUP BY department_id , job_id;

3.8 分组过滤查询

语法:SELECT 列名 FROM 表名 WHERE 条件 GROUP BY 分组列 HAVING 过滤规则

关键字说明
HAVING 过滤规则过滤规则定义对分组后的数据进行过滤

3.9 限定查询

SELECT 列名 FROM 表名 LIMIT 起始行,查询行数

关键字说明
LIMIT offset_start,row_count限定查询结果的起始行和总行数

3.9.1 查询前 5 行记录

#查询表中前五名员工的所有信息
SELECT * FROM t_employees LIMIT 0,5;

3.10 查询总结

3.10.1 SQL 语句编写顺序

SELECT 列名 FROM 表名 WHERE 条件 GROUP BY 分组 HAVING 过滤条件 ORDER BY 排序列(asc|desc)LIMIT 起始行,总条数

3.10.2 SQL 语句执行顺序

1.FROM :指定数据来源表
2.WHERE : 对查询数据做第一次过滤
3.GROUP BY : 分组
4.HAVING : 对分组后的数据第二次过滤
5.SELECT : 查询各字段的值
6.ORDER BY : 排序
7.LIMIT : 限定查询结果

3.11 子查询(作为条件判断)

SELECT 列名 FROM 表名 Where 条件 (子查询结果)

3.11.1 查询工资大于Bruce 的员工信息

#1.先查询到 Bruce 的工资(一行一列)
SELECT SALARY FROM t_employees WHERE FIRST_NAME = 'Bruce';#工资是 6000

#2.查询工资大于 Bruce 的员工信息
SELECT * FROM t_employees WHERE SALARY > 6000;

#3.将 1、2 两条语句整合
SELECT * FROM t_employees WHERE SALARY >SELECT SALARY FROM t_employees WHERE FIRST_NAME = 'Bruce';

3.12子查询(作为枚举查询条件)

SELECT 列名 FROM 表名 Where 列名 in(子查询结果);

3.12.1 查询与名为’King’同一部门的员工信息

#思路:
#1.	先查询 'King' 所在的部门编号(多行单列)
SELECT department_id
FROM t_employees
WHERE last_name = 'King'; //部门编号:80、90

#2.	再查询80、90号部门的员工信息
SELECT employee_id , first_name , salary , department_id
FROM t_employees
WHERE department_id in (80,90); 

#3.SQL:合并
SELECT employee_id , first_name , salary , department_id
FROM t_employees
WHERE department_id in (SELECT department_id cfrom t_employees WHERE last_name = 'King'); #N行一列

3.12.2 查询与名为’King’同一部门的员工信息

#1.查询 60 部门所有人的工资(多行多列)
SELECT SALARY from t_employees WHERE DEPARTMENT_ID=60;

#2.查询高于 60 部门所有人的工资的员工信息(高于所有)
select * from t_employees where SALARY > ALL(select  SALARY from t_employees WHERE DEPARTMENT_ID=60);

#。查询高于 60 部门的工资的员工信息(高于部分)
select * from t_employees where SALARY > ANY(select  SALARY from t_employees WHERE DEPARTMENT_ID=60);

3.13 子查询(作为一张表)

SELECT 列名 FROM(子查询的结果集)WHERE 条件;

查询员工表中工资排名前 5 名的员工信息

#思路:
#1.	先对所有员工的薪资进行排序(排序后的临时表)
select employee_id , first_name , salary
from t_employees
order by salary desc

#2.	再查询临时表中前5行员工信息
select employee_id , first_name , salary
from (临时表) 
limit 0,5;

#SQL:合并
select employee_id , first_name , salary
from (select employee_id , first_name , salary from t_employees order by salary desc) as temp
limit 0,5;

3.14 合并查询(了解,使用较少)

  • SELECT * FROM 表名 1 UNION SELECT * FROM 表名 2
  • SELECT * FROM 表名 1 UNION ALL SELECT * FROM 表名 2

-注意:合并结果的两张表,列数必须相同,列的数据类型可以不同

3.15 表连接查询

SELECT 列名 FROM 表 1 连接方式 表 2 ON 连接条件

3.15.1 内连接查询(INNER JOIN ON)

#1.查询所有有部门的员工信息(不包括没有部门的员工) SQL 标准
SELECT * FROM t_employees INNER JOIN t_jobs ON t_employees.JOB_ID = t_jobs.JOB_ID

#2.查询所有有部门的员工信息(不包括没有部门的员工) MYSQL
SELECT * FROM t_employees,t_jobs WHERE t_employees.JOB_ID = t_jobs.JOB_ID

3.15.2 三表连接查询

#查询所有员工工号、名字、部门名称、部门所在国家ID
SELECT * FROM t_employees e 
INNER JOIN t_departments d 
on e.department_id = d.department_id
INNER JOIN t_locations l
ON d.location_id = l.location_id

3.15.3 左外连接(LEFT JOIN ON)

#查询所有员工信息,以及所对应的部门名称(没有部门的员工,也在查询结果中,部门名称以NULL 填充)
SELECT e.employee_id , e.first_name , e.salary , d.department_name FROM t_employees e
LEFT JOIN t_departments d 
ON e.department_id = d.department_id;

3.15.4 右外连接(RIGHT JOIN ON)

#查询所有部门信息,以及此部门中的所有员工信息(没有员工的部门,也在查询结果中,员工信息以NULL 填充)
SELECT e.employee_id , e.first_name , e.salary , d.department_name FROM t_employees e 
RIGHT JOIN t_departments d 
ON e.department_id = d.department_id;

四. DML 操作【重点

4.1 新增(INSERT)

INSERT INTO 表名(列 1,列 2,列 3…) VALUES(值 1,值 2,值 3…);

4.1.1 添加一条信息

#添加一条工作岗位信息
INSERT INTO t_jobs(JOB_ID,JOB_TITLE,MIN_SALARY,MAX_SALARY) VALUES('JAVA_Le','JAVA_Lecturer',2500,9000);
#添加一条员工信息
INSERT INTO `t_employees`
(EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,COMMISSION_PCT,MANAGER_ID,DEPARTMENT_ID)
VALUES 
('194','Samuel','McCain','SMCCAIN', '650.501.3876', '1998-07-01', 'SH_CLERK', '3200', NULL, '123', '50');

4.2 修改(UPDATE)

UPDATE 表名 SET 列 1=新值 1 ,列 2 = 新值 2,…WHERE 条件;

#修改编号为100 的员工的工资为 25000
UPDATE t_employees SET SALARY = 25000 WHERE EMPLOYEE_ID = '100';
#修改编号为135 的员工信息岗位编号为 ST_MAN,工资为3500
UPDATE t_employees SET JOB_ID=ST_MAN,SALARY = 3500 WHERE EMPLOYEE_ID = '135';

4.3 删除(DELETE)

DELETE FROM 表名 WHERE 条件;

4.4 清空整表数据(TRUNCATE)

TRUNCATE TABLE 表名;

五. 数据表操作

5.1 数据类型

MySQL支持多种类型,大致可以分为三类:数值、日期/时间和字符串(字符)类型。对于我们约束数据的类型有很大的帮助

5.1.1 数值类型

类型大小范围(有符号)范围(无符号)用途
INT4 字节(-2 147 483 648,2 147 483 647)(0,4 294 967 295)大整数值
DOUBLE8 字节(-1.797E+308,-2.22E-308)(0,2.22E-308,1.797E+308)双精度浮点数值
DOUBLE(M,D)8个字节,M表示长度,D表示小数位数同上,受M和D的约束 DOUBLE(5,2) -999.99-999.99同上,受M和D的约束双精度浮点数值
DECIMAL(M,D)DECIMAL(M,D)依赖于M和D的值,M最大值为65依赖于M和D的值,M最大值为65小数值

5.1.2 日期类型

类型大小范围格式用途
DATE31000-01-01/9999-12-31YYYY-MM-DD日期值
TIME3‘-838:59:59’/‘838:59:59’HH:MM:SS时间值或持续时间
YEAR11901/2155YYYY年份值
DATETIME81000-01-01 00:00:00/9999-12-31 23:59:59YYYY-MM-DD HH:MM:SS混合日期和时间值
TIMESTAMP41970-01-01 00:00:00/2038 结束时间是第 2147483647 秒北京时间 2038-1-19 11:14:07,格林尼治时间 2038年1月19日 凌晨 03:14:07YYYYMMDD HHMMSS混合日期和时间值,时间戳

5.1.3 字符串类型

类型大小用途
CHAR0-255字符定长字符串 char(10) 10个字符
VARCHAR0-65535 字节变长字符串 varchar(10) 10个字符
BLOB(binary large object)0-65535字节二进制形式的长文本数据
TEXT0-65535字节长文本数据

5.2 数据表的创建(CREATE)

CREATE TABLE 表名(
列名 数据类型 [约束],
列名 数据类型 [约束],
​ …
列名 数据类型 [约束] //最后一列的末尾不加逗号
)[charset=utf8] //可根据需要指定表的字符编码集

5.3 数据表的修改(ALTER)

ALTER TABLE 表名 操作;

5.3.1 向现有表中添加列

#在课程表基础上添加gradeId 列
ALTER TABLE subject ADD gradeId int;

5.3.2 修改表中的列

#修改课程表中课程名称长度为10个字符
ALTER TABLE subject MODIFY subjectName VARCHAR(10);

5.3.3 删除表中的列

#删除课程表中 gradeId 列
ALTER TABLE subject DROP gradeId;

5.3.4 修改列名

#修改课程表中 subjectHours 列为 classHours
ALTER TABLE subject CHANGE subjectHours classHours int ;

5.3.5 修改表名

#修改课程表的subject 为 sub
ALTER TABLE subject rename sub;

5.4 数据表的删除(DROP)

DROP TABLE 表名

六 约束

6.1 实体完整性约束

表中的一行数据代表一个实体(entity),实体完整性的作用即是标识每一行数据不重复、实体唯一。

6.1.1 主键约束

PRIMARY KEY 唯一,标识表中的一行数据,此列的值不可重复,且不能为 NULL

6.1.2 唯一约束

UNIQUE 唯一,标识表中的一行数据,不可重复,可以为 NULL

6.1.3 自动增长列

AUTO_INCREMENT 自动增长,给主键数值列添加自动增长。从 1 开始,每次加 1。不能单独使用,和主键配合。

6.2 域完整性约束

限制列的单元格的数据正确性。

6.2.1 非空约束

NOT NULL 非空,此列必须有值。

6.2.2 默认值约束

DEFAULT 值 为列赋予默认值,当新增数据不指定值时,书写DEFAULT,以指定的默认值进行填充。

6.2.3 引用完整性约束

#创建专业表
CREATE TABLE Speciality(
	id INT PRIMARY KEY AUTO_INCREMENT,
	SpecialName VARCHAR(20) UNIQUE NOT NULL
)CHARSET=utf8;

#创建课程表(课程表的SpecialId 引用专业表的 id)
CREATE TABLE subject(
	subjectId INT PRIMARY KEY AUTO_INCREMENT,
  subjectName VARCHAR(20) UNIQUE NOT NULL,
  subjectHours INT DEFAULT 20,
  specialId INT NOT NULL,
  CONSTRAINT fk_subject_specialId  FOREIGN KEY(specialId) REFERENCES Speciality(id)  #引用专业表里的 id 作为外键,新增课程信息时,约束课程所属的专业。
)charset=utf8;

#专业表新增数据
INSERT INTO Speciality(SpecialName) VALUES('Java');
INSERT INTO Speciality(SpecialName) VALUES('C#');
#课程信息表添加数据
INSERT INTO subject(subjectName,subjectHours) VALUES('Java',30,1);#专业 id 为 1,引用的是专业表的 Java
INSERT INTO subject(subjectName,subjectHours) VALUES('C#MVC',10,2);#专业 id 为 2,引用的是专业表的 C#

七 事务【重点

7.1 事务的概念

事务是一个原子操作。是一个最小执行单元。可以由一个或多个SQL语句组成,在同一个事务当中,所有的SQL语句都成功执行时,整个事务成功,有一个SQL语句执行失败,整个事务都执行失败。

7.2 事务的边界

  • 开始:连接到数据库,执行一条DML语句。 上一个事务结束后,又输入了一条DML语句,即事务的开始
  • 结束:
    ​ 1). 提交:
    ​ a. 显示提交:commit;
    ​ b. 隐式提交:一条创建、删除的语句,正常退出(客户端退出连接);

    2). 回滚:
    ​ a. 显示回滚:rollback;
    ​ b. 隐式回滚:非正常退出(断电、宕机),执行了创建、删除的语句, 但是失败了,会为这个无效的语句执行回滚。

7.3 事务的特性 (重要)

  • Atomicity(原子性)
        表示一个事务内的所有操作是一个整体,要么全部成功,要么全部失败
  • Consistency(一致性)
        表示一个事务内有一个操作失败时,所有的更改过的数据都必须回滚到修改前状态
  • Isolation(隔离性)
        事务查看数据操作时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看中间状态的数据。
  • Durability(持久性)
        持久性事务完成之后,它对于系统的影响是永久性的。

八 权限管理

8.1 创建用户

CREATE USER 用户名 IDENTIFIED BY 密码

8.2 授权

GRANT ALL ON 数据库.表 TO 用户名;

8.3 撤销权限

REVOKE ALL ON 数据库.表名 FROM 用户名

8.4 删除用户

DROP USER 用户名

九 视图

9.1 概念

视图,虚拟表,从一个表或多个表中查询出来的表,作用和真实表一样,包含一系列带有行和列的数据。视图中,用户可以使用SELECT语句查询数据,也可以使用INSERT,UPDATE,DELETE修改记录,视图可以使用户操作方便,并保障数据库系统安全。

9.2 视图特点

  • 优点
    简单化,数据所见即所得。
    安全性,用户只能查询或修改他们所能见到得到的数据。
    逻辑独立性,可以屏蔽真实表结构变化带来的影响。
  • 缺点
    性能相对较差,简单的查询也会变得稍显复杂。
    修改不方便,特变是复杂的聚合视图基本无法修改。

9.3 视图的创建

语法:CREATE VIEW 视图名 AS 查询数据源表语句;

#创建 t_empInfo 的视图,其视图从 t_employees 表中查询到员工编号、员工姓名、员工邮箱、工资
CREATE VIEW t_empInfo 
AS 
SELECT EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,SALARY from t_employees;
#查询 t_empInfo 视图中编号为 101 的员工信息
SELECT * FROM t_empInfo where employee_id = '101';

9.4 视图的修改

#方式 1:如果视图存在则进行修改,反之,进行创建
CREATE  OR  REPLACE VIEW t_empInfo 
AS
SELECT EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,SALARY,DEPARTMENT_ID from t_employees;

#方式 2:直接对已存在的视图进行修改
ALTER VIEW t_empInfo
AS 
SELECT EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,SALARY from t_employees;

9.5 视图的删除

DROP VIEW 视图名

9.6 视图的注意事项

  • 注意:
  • 视图不会独立存储数据,原表发生改变,视图也发生改变。没有优化任何查询性能。
  • 如果视图包含以下结构中的一种,则视图不可更新
    1.聚合函数的结果
    2.DISTINCT 去重后的结果
    3.GROUP BY 分组后的结果
    4.HAVING 筛选过滤后的结果
    5.UNION、UNION ALL 联合后的结果
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值