Day04-数据库服务查询语句

课程知识内容概述:
01 数据库操作数据语句 (insert update delete)
02 数据库查询语句基础 (select)
03 数据库查询语句进阶 (分组查询 连表查询 子查询)
04 数据库获取元数据信息 (批量管理 服务监控)
05 数据库索引概述介绍 (索引构建-原理)
06 数据库索引分类介绍 (主键索引 辅助索引 联合索引 前缀索引 唯一键索引)
07 数据库索引应用配置 (创建索引 删除索引 查看索引) 执行计划

作业:
01 如果创建了多个数据库,或者数据库中创建了多个表,如何批量除?

02 删除表数据的方法 drop truncate delete 三种方式的详细区别?(面试题)

1、数据库操作数据语句

update

语法结构:

update 表名 set 字段=新值,where 条件;
-- 属于表内容信息变更操作,需要按照表结构预先定义好的字段信息修改,并且按照条件修改,默认全表修改

具体操作:

mysql> update stu1 set name="zhangsan" where id=6;
-- 修改表数据内容标准方式,修改时一定要加条件信息(条件信息建议为主键或具有唯一性信息)

delete:

语法结构:

mysql> delete from 表名 where 表达式;
-- 属于表内容信息变更操作,需要按照表结构预先定义好的字段信息删除,并且按照条件删除,默认全表删除

具体操作:

mysql> delete from stu1 where id=8;

避免update或delete语句对数据产生破坏:

方式一:利用事务机制,对数据进行操作

完成一件事情,可以有多个步骤,要么所有步骤都成功,要么都失败?

交易 – 账户钱减少 – 另一个账户增加 – 事务 ???

begin;

update 或者 delete

select xxx;

rollback; 回退

commit; – 落盘

方式二:使用update或delete时,必须加上where,若不加会报错(数据库安全模式设置)

sql_safe_updates=1 – 激活数据库的安全模式

全局生效:对所有用户生效

临时激活此功能:

mysql> set global sql_safe_updates=1;

mysql> select @@sql_safe_updates;
+--------------------+
| @@sql_safe_updates |
+--------------------+
|                  1 |
+--------------------+
1 row in set (0.00 sec)

mysql> use oldboy;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed

# 修改测试
mysql> select * from stu1;
+----+------------+-----+-------+
| id | name       | age | dept  |
+----+------------+-----+-------+
|  1 | oldboy     |  35 |       |
|  2 | oldboy     |  35 | net   |
|  3 | oldboy     |  35 | go    |
|  4 | oldgirl    |  25 | Linux |
|  5 | littlegirl |   2 | net   |
|  6 | littleboy  |   1 | Linux |
|  7 | oldboy     |  35 | Linux |
|  9 | 老男孩     |  32 |       |
+----+------------+-----+-------+
8 rows in set (0.00 sec)

mysql> update stu1 set name='老女孩';
ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column. 
mysql> update stu1 set name='老女孩' where id=9;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from stu1;
+----+------------+-----+-------+
| id | name       | age | dept  |
+----+------------+-----+-------+
|  1 | oldboy     |  35 |       |
|  2 | oldboy     |  35 | net   |
|  3 | oldboy     |  35 | go    |
|  4 | oldgirl    |  25 | Linux |
|  5 | littlegirl |   2 | net   |
|  6 | littleboy  |   1 | Linux |
|  7 | oldboy     |  35 | Linux |
|  9 | 老女孩     |  32 |       |
+----+------------+-----+-------+
8 rows in set (0.00 sec)

# 删除测试
mysql> delete from stu1;
ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column. 
mysql> delete from stu1 where id=9;
Query OK, 1 row affected (0.01 sec)

mysql> select * from stu1;
+----+------------+-----+-------+
| id | name       | age | dept  |
+----+------------+-----+-------+
|  1 | oldboy     |  35 |       |
|  2 | oldboy     |  35 | net   |
|  3 | oldboy     |  35 | go    |
|  4 | oldgirl    |  25 | Linux |
|  5 | littlegirl |   2 | net   |
|  6 | littleboy  |   1 | Linux |
|  7 | oldboy     |  35 | Linux |
+----+------------+-----+-------+
7 rows in set (0.00 sec)

永久激活此功能:

[root@db01 ~]# echo 'set global sql_safe_updates=1;' >/opt/init.sql
[root@db01 ~]# chmod +x /opt/init.sql
[root@db01 ~]# vim /etc/my80.cnf 
[mysqld]
init-file=/opt/init.sql                                               
[root@db01 ~]# systemctl restart mysqld
[root@db01 ~]# 
[root@db01 ~]# mysql --defaults-file=/etc/my80.cnf
mysql> select @@sql_safe_updates;
+--------------------+
| @@sql_safe_updates |
+--------------------+
|                  1 |
+--------------------+
1 row in set (0.00 sec)

局部配置:只针对部分客户端生效

方法一:把safe_updates=1加入到my.cnf的client标签下

[root@db01 ~]# cat /etc/my80.cnf
[client]
safe_updates=1
[root@db01 ~]# systemctl restart mysqld
[root@db01 ~]# mysql --defaults-file=/etc/my80.cnf

方式二:客户端连接时,利用参数激活安全模式功能

[root@db01 ~]# mysql --defaults-file=/etc/my80.cnf -U
-U, --safe-updates  Only allow UPDATE and DELETE that uses keys
-- 表示以安全更新模式登录数据库,并放入/etc/profile永久生效。

方式三:避免删除对数据的损坏(删除–伪删除)

插入状态列信息

ALTER TABLE `oldboy`.`stu1` 
ADD COLUMN `state` INT UNSIGNED NOT NULL DEFAULT 1 AFTER `dept`;
-- 在原有表中添加新的状态列
mysql> update stu1 set state=0 where id=6;
-- 将原本删除列信息的状态改为0,实现伪删除效果
mysql> select * from stu1 where state=1;
-- 实现查询时不要获取状态为0的信息,即不查看获取伪删除数据信息

作业:

01 如果创建了多个数据库,或者数据库中创建了多个表,如何批量删除?

02 删除表数据的方法 drop truncate delete 三种方式的详细区别?(面试题)

drop table stu;
truncate table stu;
delete from stu;

数据表环境准备:

source ~/t100w_oldboy.sql;

问题解答分析:

区别分析drop table stu;truncate table stu;delete from stu;
功能效果删除表结构+数据(存储空间释放)删除表数据(释放空间)删除表数据(标记删除)
删除逻辑彻底删除物理删除(段区页层面删除)逻辑删除(逐行删除)
删除效率效率快(和数据量无关)效率快(和数据量无关)效率慢(和数据量有关)
自增影响新增自增序列重置自增序列(释放高水位线)延续自增序列
数据恢复?利用日志文件恢复利用备份恢复/延时从库恢复利用日志文件恢复(快速)

知识扩展:自增列信息值调整方法:

mysql> alter table stu auto_increment=10;

2、数据库查询语句基础

1)查看数据库服务配置信息

  • 查看数据库变量配置
select @@配置参数信息;
show variables like '%xxx%';

# 查询获取参数配置信息
mysql> select @@port;
+-----------+
| @@port |
+-----------+
|   3306     |
+-----------+
1 row in set (0.00 sec)
-- 查询数据库服务端口配置信息
mysql> select @@socket;
+-----------------+
| @@socket        |
+-----------------+
| /tmp/mysql.sock |
+-----------------+
1 row in set (0.00 sec)
-- 查询数据库服务套接字文件信息
mysql> select @@innodb_flush_log_at_trx_commit;
+----------------------------------------------+
| @@innodb_flush_log_at_trx_commit |
+----------------------------------------------+
|                                                              1 |
+----------------------------------------------+
1 row in set (0.00 sec)
-- 查询数据库服务比较长的配置参数信息

# 查询获取参数配置信息(模糊查找)
mysql> show variables;
-- 查看数据库服务所有配置参数信息
mysql> show variables like 'po%';
-- 查看数据库服务配置信息模糊查找(查找po开头的信息)
mysql> show variables like '%po';
-- 查看数据库服务配置信息模糊查找(查找po结尾的信息)
mysql> show variables like '%po%';
-- 查看数据库服务配置信息模糊查找(查找含有po的信息)

参数变量可以进行设置:

临时设置:

set global
set session
# 数据库配置参数在线调整
mysql > set session innodb_flush_log_at_trx_commit=1;
mysql > set session sql_log_bin='off';
-- 表示在线临时调整配置参数,并且只是当前会话生效(session是默认方式,不是所有配置都可以调整)
mysql > set global innodb_flush_log_at_trx_commit=1;
-- 表示在线临时调整配置参数,并且将会影响所有连接(global是全局方式,可以进行所有配置调整)

说明:数据库服务配置参数在线调整参数,只是临时生效,数据库服务重启后配置会失效,想要永久生效需要修改配置文件信息

永久设置:

服务端进行配置

配置参数/加载配置命令文件(set global)

  • 查看数据库函数信息
# 查询获取函数输出信息
mysql> select version();
+-----------+
| version() |
+-----------+
| 8.0.26    |
+-----------+
1 row in set (0.00 sec)
-- 查询数据库服务函数输出信息,获取服务版本信息
mysql> select now();
+--------------------------+
| now()                         |
+--------------------------+
| 2022-11-04 09:13:27 |
+--------------------------+
1 row in set (0.00 sec)
-- 查询数据库服务函数输出信息,获取当前日期时间
mysql> select concat(123);
+-----------------+
| concat(123) |
+-----------------+
| 123               |
+-----------------+
1 row in set (0.00 sec)
-- 查询数据库服务函数输出信息,获取拼接函数信息
mysql> select concat(user,"@","'",host,"'") from mysql.user;
+-------------------------------------+
| concat(user,"@","'",host,"'") |
+-------------------------------------+
| user02@'%'                              |     
| blog@'192.168.30.%'              |
+-------------------------------------+
-- 拼接函数应用演示

函数或者其他配置指令的官方参考:https://dev.mysql.com/doc/refman/8.4/en/dynindex-function.html

2)查看数据库服务数据信息

单表数据信息查看(基础)

# 数据表数据查询命令语法 
mysql> select <字段1,字段2...> from <表名> [WHERE 条件] group by <字段1,字段2...> having 条件 order by 字段 limit 限制信息;
-- 属于表内容信息查询操作,可以获取表中数据行信息(子句信息需要按顺序书写)

应用方式一:select+from 结合使用情况

select * from city;          -- > 等价于 cat a.txt
select id,name,countrycode,district,population from city;
-- 进入world数据库中,查询数据库中city表所有内容信息(企业应用不要对大表查看所有数据)
select name,population from city;     -- > 等价于 awk $1 $2
-- 查询city表中的部分字段信息,显示查看城市名称和人口数量

应用方式二:select+from+where 结合使用情况

方式一:定义等值条件信息进行数据查询

# 查询中国的所有城市信息,中国代码信息 ”CHN”
mysql > SELECT * FROM city WHERE countrycode='CHN'; 

# 查询中国的所有城市信息,只关注城市名称和人口数量列信息
mysql > SELECT NAME,population FROM city WHERE countrycode='CHN';

方式二:定义区间条件信息进行数据查询

可使用区间条件表示方法:

序号符号解释说明
01<表示小于指定数值的信息作为条件
02>表示大于指定数值的信息作为条件
03<=表示小于等于指定数值的信息作为条件
04>=表示大于等于指定数值的信息作为条件
05!= / <>表示不等于指定数值的信息作为条件
# 查询大于700万人的所有城市信息
mysql > SELECT * FROM city WHERE population>7000000;

# 查询小于等于1000人的所有城市信息
mysql > SELECT * FROM city WHERE population<=1000;

方式三:定义逻辑条件信息进行数据查询

可以使用逻辑判断符号,进行条件设定查找相应数据信息:

序号逻辑判断符号解释说明
01and(并且)/ &&表示多个条件均都满足才能被查找出来
02or(或者)/ ||表示多个条件之一满足就能被查找出来
03not (取反) / !表示查找除过滤查找的信息以外的内容
# 查询中国境内,大于520万人口的城市信息
mysql> SELECT * FROM city WHERE countrycode='CHN' AND population>5200000;

# 查询中国和美国的所有城市 
mysql> SELECT * FROM city WHERE countrycode='chn' OR countrycode='USA';

# 查询人口数在100w到200w之间的城市信息
mysql> SELECT * FROM city WHERE population>=1000000 AND population<=2000000;

方式四:定义模糊条件信息进行数据查询(like )

# 查询国家代号是CH开头的城市信息
mysql> SELECT * FROM city WHERE countrycode LIKE 'CH%';

# 查询国家代号含US内容的城市信息
mysql> SELECT * FROM city WHERE countrycode LIKE '%US%';
-- 在模糊查询时,%符号在前面进行检索数据时,是不会走索引信息进行检索的,查询性能较慢

方式五:特殊查询条件组合进行数据查询(配合in, not in, between and )

# 查询中国和美国的所有城市 
mysql> SELECT * FROM city WHERE countrycode in ('CHN','USA');
-- in的查询条件方式表示包含意思,实际应用更广泛

# 查询世界上的所有城市信息,但排除中国和美国的城市不查询
mysql> SELECT * FROM city WHERE countrycode not in ('CHN','USA');
-- not in的查询条件方式表示排除意思,实际应用比较少见,因为not in不能走索引扫描,查询检索性能较慢

# 查询人口数量在50w-100w之间的城市信息
mysql> SELECT * FROM city WHERE population between 500000 and 10000000;
-- between and的查询条件方式是包含边界取值信息的,即包含50w人口的城市,也包含100w人口的城市

方式六:查询数据信息取消重复信息(distinct)

mysql> select CountryCode from city where CountryCode='USA';
mysql> select Distinct CountryCode from city where CountryCode='USA';
+-----------------+
| CountryCode |
+-----------------+
| USA                 |
+-----------------+
1 row in set (0.19 sec)
-- 列字段信息必须完全相同内容,才可以实现去重;

方式七:查询数据信息为空的内容(is null)

mysql> select * from city where CountryCode is null;   
-- 查询国家编码字段为空的信息

mysql> select * from city where CountryCode not null;
-- 查询国家编码字段为非空的信息

3、数据库查询语句进阶

查询数据语法:

# 数据表数据查询命令语法 
mysql> select <字段1,字段2...> from <表名> [WHERE 条件] group by <字段1,字段2...> having 条件 order by 字段 limit 限制信息;

数据库服务中常用的聚合函数(统计函数):

序号函数信息解释说明
01count()此函数表示对数量信息进行统计
02sum()此函数表示对数值信息进行求和
03avg()此函数表示对数值信息进行求平均值
04min()此函数表示对数值信息进行取最小值
05max()此函数表示对数值信息进行取最大值
06group_concat()此函数表示输出信息无法匹配分组和聚合函数时,进行拼接整合显示
07distinct此指令表示作用是对表中的单个字段或多个字段去重操作

group by:主要用于将数据信息进行排序分组;

having: 主要用于对分组后/聚合后的数据进行过滤;

order by:主要用于对指定列数据信息进行排序;(升序/降序)

limit: 主要用于显示部分数据信息;

分组查询数据信息:

1)查询统计每个国家的人口总数

分组机制:

  • 先指定某列信息 -> 进行排序 -> 去重合并 实现分组
mysql > select countrycode,sum(population) from world.city group by countrycode;
-- 根据国家信息分组聚合,在将分组后所有城市的人口数量进行sum求和运算,实现国家信息对应人口总数的1对1关系

2)查询统计中国每个省份的城市个数

mysql> select district,count(name) from city where countrycode='chn' group by district;
mysql> select district,count(*) from city where countrycode='chn' group by district;

# 正确查询方式
mysql> select district,count(*),group_concat(name) from city where countrycode='chn' group by district;

# 补充:sql_mode ONLY_FULL_GROUP_BY
# 当分组后,不能实现一对多显示时,就直接报错,而不是只显示部分匹配的信息;

3)查询统计每个省份的城市个数,以及城市名称信息

# 补充说明:分组查询数据经常看到错误信息  --  mysql 8.0 (数据库是一个二维表关系型的数据库)
mysql> select district,count(*),name from city where countrycode='chn' group by district;
ERROR 1055 (42000): Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'world.city.Name' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
-- 由于数据库sql_mode配置了only_full_group_by,由于输出的name信息不能和district信息实现1对1关系,因此报错
mysql> select district,count(*),group_concat(name) from city where countrycode='chn' group by district;
-- 利用group_concat()就可以实现没有出现在分组和聚合函数中的字段,采取拼接整合方式显示,满足分组1对1关系

4)查询统计每个国家的人口总数,只显示人口数量超过1个亿的信息

mysql> select countrycode,sum(population) from world.city group by countrycode having sum(population)>100000000;

5)查询统计每个国家的人口总数,只显示人口数量超过5千万的信息,并且按照国家人口总数排序显示

mysql > select countrycode,sum(population) from world.city group by countrycode having sum(population)>50000000 order by sum(population);
-- 实现了人口数量从小到大排序(升序/正序)

mysql > select countrycode,sum(population) from world.city group by countrycode having sum(population)>50000000 order by sum(population) desc;
-- 实现了人口数量从大到小排序(降序/逆序)

6)查询统计每个国家的人口总数,只显示人口数量超过5千万的信息,并且按照国家人口总数从大到小排序,只显示前三名

mysql > select countrycode,sum(population) from world.city group by countrycode having sum(population)>50000000 order by sum(population) desc limit 3;
或者
mysql > select countrycode,sum(population) from world.city group by countrycode having sum(population)>50000000 order by sum(population) desc limit 0,3;
mysql > select countrycode,sum(population) from world.city group by countrycode having sum(population)>50000000 order by sum(population) desc limit 3 offset 0;

7) 查询统计每个国家的人口总数,只显示人口数量超过5千万的信息,并且按照国家人口总数从大到小排序,只显示三~五名

mysql > select countrycode,sum(population) from world.city group by countrycode having sum(population)>50000000 order by sum(population) desc limit 2,3;
-- 2表示从第几行开始截取,3表示截取几行内容
或者
mysql > select countrycode,sum(population) from world.city group by countrycode having sum(population)>50000000 order by sum(population) desc limit 3 offset 2;
-- 跳过前2名,显示后面的三名数据信息

连表查询(多表查询数据)

准备环境:建立多个相关联的数据表

# 创建多表查询所需模拟数据库和数据表信息
CREATE DATABASE school CHARSET utf8;
USE school;

CREATE TABLE student (
    sno INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '学号',
    sname VARCHAR(20) NOT NULL COMMENT '姓名',
    sage TINYINT UNSIGNED NOT NULL COMMENT '年龄',
    ssex ENUM('f','m') NOT NULL DEFAULT 'm' COMMENT '性别'
) ENGINE=INNODB CHARSET=utf8;

CREATE TABLE course (
    cno INT NOT NULL PRIMARY KEY COMMENT '课程编号',
    cname VARCHAR(20) NOT NULL COMMENT '课程名字',
    tno INT NOT NULL COMMENT '教师编号'
) ENGINE=INNODB CHARSET=utf8;

CREATE TABLE sc (
    sno INT NOT NULL COMMENT '学号',
    cno INT NOT NULL COMMENT '课程编号',
    score INT NOT NULL DEFAULT 0 COMMENT '成绩'
) ENGINE=INNODB CHARSET=utf8;

CREATE TABLE teacher (
    tno INT NOT NULL PRIMARY KEY COMMENT '教师编号',
    tname VARCHAR(20) NOT NULL COMMENT '教师名字'
) ENGINE=INNODB CHARSET=utf8;

# 4张表关联:
student --(sno)-- sc -- course -- (tno) -- course  --  teacher

# 在数据库与数据表中插入模拟数据
INSERT INTO student(sno,sname,sage,ssex)
VALUES
(1,'zhang3',18,'m'),
(2,'zhang4',18,'m'),
(3,'li4',18,'m'),
(4,'wang5',19,'f'),
(5,'zh4',18,'m'),
(6,'zhao4',18,'m'),
(7,'ma6',19,'f'),
(8,'oldboy',20,'m'),
(9,'oldgirl',20,'f'),
(10,'oldp',25,'m');

INSERT INTO teacher(tno,tname)
VALUES
(101,'oldboy'),
(102,'xiaoQ'),
(103,'xiaoA'),
(104,'xiaoB');

INSERT INTO course(cno,cname,tno)
VALUES
(1001,'linux',101),
(1002,'python',102),
(1003,'mysql',103),
(1004,'go',105);

INSERT INTO sc(sno,cno,score)
VALUES
(1,1001,80),
(1,1002,59),
(2,1002,90),
(2,1003,100),
(3,1001,99),
(3,1003,40),
(4,1001,79),
(4,1002,61),
(4,1003,99),
(5,1003,40),
(6,1001,89),
(6,1003,77),
(7,1001,67),
(7,1003,82),
(8,1001,70),
(9,1003,80),
(10,1003,96);

SELECT * FROM student;
SELECT * FROM teacher;
SELECT * FROM course;
SELECT * FROM sc;

连表查询数据方法:

# 笛卡尔乘积连接多表:
select * from t1,t2;

# 内连接查询多表:
select * from t1,t2 where t1.=t2.;
select * from t1 [inner] join t2 on t1.=t2.;

# 演示:
# 内连接查询的简单描述:两个表中有关联条件的行显示出来;
# 比较传统的SQL 92的内连接标准方式
mysql> select * from teacher,course where teacher.tno=course.tno;
# 比较新颖的SQL 99的内连接使用方式
mysql> select * from teacher [inner] join course on teacher.tno=course.tno;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '[inner] join course on teacher.tno=course.tno' at line 1
mysql> select * from teacher join course on teacher.tno=course.tno;


# 外连接查询多表:左外连接
select * from t1 left join t2 on  t1.=t2.;
-- 以左表作为驱动表,进行连接其他表

# 外连接查询多表:右外连接
select * from t1 right join t2 on  t1.=t2.;
-- 以右表作为驱动表,进行连接其他表

# 演示
mysql> select * from teacher join course on teacher.tno=course.tno;
+-----+--------+------+--------+-----+
| tno | tname  | cno  | cname  | tno |
+-----+--------+------+--------+-----+
| 101 | oldboy | 1001 | linux  | 101 |
| 102 | xiaoQ  | 1002 | python | 102 |
| 103 | xiaoA  | 1003 | mysql  | 103 |
+-----+--------+------+--------+-----+
3 rows in set (0.00 sec)

mysql> select * from teacher left join course on teacher.tno=course.tno;
+-----+--------+------+--------+------+
| tno | tname  | cno  | cname  | tno  |
+-----+--------+------+--------+------+
| 101 | oldboy | 1001 | linux  |  101 |
| 102 | xiaoQ  | 1002 | python |  102 |
| 103 | xiaoA  | 1003 | mysql  |  103 |
| 104 | xiaoB  | NULL | NULL   | NULL |
+-----+--------+------+--------+------+
4 rows in set (0.00 sec)

mysql> select * from teacher right join course on teacher.tno=course.tno;
+------+--------+------+--------+-----+
| tno  | tname  | cno  | cname  | tno |
+------+--------+------+--------+-----+
|  101 | oldboy | 1001 | linux  | 101 |
|  102 | xiaoQ  | 1002 | python | 102 |
|  103 | xiaoA  | 1003 | mysql  | 103 |
| NULL | NULL   | 1004 | go     | 105 |
+------+--------+------+--------+-----+
4 rows in set (0.00 sec)

内连接如何解决查询数据问题?

解题思路:

1)根据需求,获取需要连接表信息

2)将多个表连接成一个大表 join on

3)筛选过滤出需要的数据信息

4张表关联:

student --(sno)-- sc – course – (tno) – course – teacher

多表查询信息练习题目分析:

01 统计zhang3,学习了几门课?

zhang3 --> sno 1

步骤一:

sc course

步骤二:

select * from 
sc join
course
on sc.cno = course.cno;

步骤三:

mysql> select count(*) from  sc join course on sc.cno = course.cno where sno=1;
mysql> select sname,count(*) from  student join sc on student.sno=sc.sno join course on sc.cno=course.cno wherestudent.sno=1;
+--------+----------+
| sname  | count(*) |
+--------+----------+
| zhang3 |        2 |
+--------+----------+
1 row in set (0.00 sec)

02 查询zhang3,学习的课程名称有哪些?

步骤一:

student sc course

步骤二:

select * from 
student join
sc
on student.sno=sc.sno
join
course
on sc.cno=course.cno;

步骤三:

mysql> select sname,count(*),group_concat(cname) from  student join sc on student.sno=sc.sno join course on sc.cn
no=course.cno where student.sno=1;
+--------+----------+---------------------+
| sname  | count(*) | group_concat(cname) |
+--------+----------+---------------------+
| zhang3 |        2 | linux,python        |
+--------+----------+---------------------+
1 row in set (0.00 sec)

03 查询xiaoA老师教的学生名?

步骤一:

student --(sno)-- sc – course – (tno) – course – teacher

步骤二:

select * from
student 
join sc
on student.sno=sc.sno
join course
on sc.cno=course.cno
join teacher
on course.tno=teacher.tno;

步骤三:

mysql> select tname,group_concat(sname) from student  join sc on student.sno=sc.sno join course on sc.cno=course..cno join teacher on course.tno=teacher.tno where teacher.tno=103 group by teacher.tno;
+-------+---------------------------------------------+
| tname | group_concat(sname)                         |
+-------+---------------------------------------------+
| xiaoA | zhang4,li4,wang5,zh4,zhao4,ma6,oldgirl,oldp |
+-------+---------------------------------------------+
1 row in set (0.00 sec)

04 查询xiaoA老师教课程的平均分数?

步骤一:

sc – course – (tno) – course – teacher

步骤二:

select * from sc
join course
on sc.cno=course.cno
join teacher
on course.tno=teacher.tno;

步骤三:

mysql> select tname,avg(score) from sc join course on sc.cno=course.cno join teacher on course.tno=teacher.tno where teacher.tno=103;
+-------+------------+
| tname | avg(score) |
+-------+------------+
| xiaoA |    76.7500 |
+-------+------------+
1 row in set (0.00 sec)

05 每位老师所教课程的平均分,并按平均分排序?

步骤一:

sc – course – (tno) – course – teacher

步骤二:

select * from sc
join course
on sc.cno=course.cno
join teacher
on course.tno=teacher.tno;

select tname,cname,avg(score) from sc
join course
on sc.cno=course.cno
join teacher
on course.tno=teacher.tno
group by teacher.tno,course.cno;

步骤三:

mysql> select tname,cname,avg(score) from sc join course on sc.cno=course.cno join teacher on course.tno=teacher.tno group by teacher.tno,course.cno order by avg(score);
+--------+--------+------------+
| tname  | cname  | avg(score) |
+--------+--------+------------+
| xiaoQ  | python |    70.0000 |
| xiaoA  | mysql  |    76.7500 |
| oldboy | linux  |    80.6667 |
+--------+--------+------------+
3 rows in set (0.00 sec)

mysql> select tname,cname,avg(score) from sc join course on sc.cno=course.cno join teacher on course.tno=teacher.tno group by teacher.tno,course.cno order by avg(score) desc;
+--------+--------+------------+
| tname  | cname  | avg(score) |
+--------+--------+------------+
| oldboy | linux  |    80.6667 |
| xiaoA  | mysql  |    76.7500 |
| xiaoQ  | python |    70.0000 |
+--------+--------+------------+
3 rows in set (0.00 sec)

06 查询xiaoA老师教的不及格的学生姓名?

步骤一:

student --(sno)-- sc – course – (tno) – course – teacher

步骤二:

select * from
student 
join sc
on student.sno=sc.sno
join course
on sc.cno=course.cno
join teacher
on course.tno=teacher.tno;

select tname,sname from
student 
join sc
on student.sno=sc.sno
join course
on sc.cno=course.cno
join teacher
on course.tno=teacher.tno
where teacher.tno=103 and sc.score<60

步骤三:

mysql> select tname,sname from student  join sc on student.sno=sc.sno join course on sc.cno=course.cno join teacher on course.tno=teacher.tno where teacher.tno=103 and sc.score<60;
+-------+-------+
| tname | sname |
+-------+-------+
| xiaoA | li4   |
| xiaoA | zh4   |
+-------+-------+
2 rows in set (0.00 sec)

mysql> select tname,group_concat(sname) from student  join sc on student.sno=sc.sno join course on sc.cno=course..cno join teacher on course.tno=teacher.tno where teacher.tno=103 and sc.score<60 group by teacher.tno;
+-------+---------------------+
| tname | group_concat(sname) |
+-------+---------------------+
| xiaoA | li4,zh4             |
+-------+---------------------+
1 row in set (0.00 sec)

07 查询所有老师所教学生不及格的信息?

步骤一:

student --(sno)-- sc – course – (tno) – course – teacher

步骤二:

select * from
student 
join sc
on student.sno=sc.sno
join course
on sc.cno=course.cno
join teacher
on course.tno=teacher.tno;

select tname,group_concat(sname) from
student 
join sc
on student.sno=sc.sno
join course
on sc.cno=course.cno
join teacher
on course.tno=teacher.tno
where sc.score<60
group by teacher.tno,course.cno;

步骤三:

mysql> select tname,group_concat(sname) from student  join sc on student.sno=sc.sno join course on sc.cno=course.cno join teacher on course.tno=teacher.tno where sc.score<60 group by teacher.tno,course.cno;
+-------+---------------------+
| tname | group_concat(sname) |
+-------+---------------------+
| xiaoQ | zhang3              |
| xiaoA | li4,zh4             |
+-------+---------------------+
2 rows in set (0.00 sec)

补充说明:多表查询别名应用

在进行数据信息查询时,有些表和有些字段会被经常调用到,而且生成环境中表明和字段名会比较的复杂,在调用时不是很方便;

而且有些时候,查询的SQL语句信息会出现在代码中,在编写代码时也会不太规范,同时也不方便阅读,因此出现了数据库别名概念;

在进行数据库别名应用时,会经常用到两种别名:

表别名应用:

# 举例说明别名作用,在没有使用别名时
select teacher.tname,group_concat(student.sname)  
from teacher 
join course 
on teacher.tno=course.tno 
join sc 
on course.cno=sc.cno 
join student 
on sc.sno=student.sno 
where sc.score<60 
group by teacher.tno;

# 应用别名:AS
select a.tname,group_concat(d.sname)  
from teacher as a
join course as b
on a.tno=b.tno 
join sc as c
on b.cno=c.cno 
join student as d
on c.sno=d.sno 
where c.score<60 
group by a.tno;
+-------+-----------------------+
| tname | group_concat(d.sname) |
+-------+-----------------------+
| xiaoQ | zhang3                |
| xiaoA | li4,zh4               |
+-------+-----------------------+
2 rows in set (0.00 sec)

列别名应用:

# 举例说明别名作用,在没有使用别名时
select a.tname,group_concat(d.sname)  
from teacher as a
join course as b
on a.tno=b.tno 
join sc as c
on b.cno=c.cno 
join student as d
on c.sno=d.sno 
where c.score<60 
group by a.tno;
+-------+-----------------------+
| tname | group_concat(d.sname) |
+-------+-----------------------+
| xiaoQ | zhang3                |
| xiaoA | li4,zh4               |
+-------+-----------------------+
2 rows in set (0.00 sec)


# 进行列别名化
select a.tname as '老师名',group_concat(d.sname)  as '不及格学生名'
from teacher as a
join course as b
on a.tno=b.tno 
join sc as c
on b.cno=c.cno 
join student as d
on c.sno=d.sno 
where c.score<60 
group by a.tno;
+-----------+--------------------+
| 老师名    | 不及格学生名       |
+-----------+--------------------+
| xiaoQ     | zhang3             |
| xiaoA     | li4,zh4            |
+-----------+--------------------+
2 rows in set (0.00 sec)
-- 列别名信息是可以在group by子句之后进行调用的

子查询应用:(了解)

子查询:实现select语句的嵌套查询(嵌套在where语句后 嵌套在from语句后)

案例演示:

1)01 取出大于Linux课程的平均分学生都有哪些;

第一步:select 获取Linux课程平均分

sc - (cno)-- course

所有信息

select * from
sc as a join
course as b
on a.cno=b.cno
where b.cname='linux';

平均分:-- 80

select avg(a.score) from sc as a join course as b on a.cno=b.cno where b.cname='linux';

第二步:select获取Linux课程大于平均分的学生信息

student --(sno)-- sc – (cno)-- course – (tno)

select * from
student 
join sc
on student.sno=sc.sno
join course
on sc.cno=course.cno;

select cname,sname from student  join sc on student.sno=sc.sno join course on sc.cno=course.cno where course.cnrse.cname='linux' and sc.score>'80';

两个步骤整合:

mysql> select cname,sname from student  join sc on student.sno=sc.sno join course on sc.cno=course.cno where course.cname='linux' and sc.score>(select avg(a.score) from sc as a join course as b on a.cno=b.cno where b.cname='linux');
+-------+-------+
| cname | sname |
+-------+-------+
| linux | li4   |
| linux | zhao4 |
+-------+-------+
2 rows in set (0.00 sec)

2)02 取出Linux课程成绩大于70分的所有男同学信息;多个表查询信息–开发数据分析

第一步:取出Linux课程成绩大于70分

mysql> select * from sc as a join course as b on a.cno=b.cno where b.cname='linux';

第二步:找出男同学大于70分

select name,sc,gender from student where sc >70 and gender='M';
or
select s.name,s.sc,s.gender from (select * from students where gender='M') AS s where s.sc >70;

4、数据库获取元数据信息

1)元数据概念介绍

元数据 == 属性信息

表示在数据库服务中有哪些数据库,库中有哪些表,表中有多少字段,字段是什么类型等等,这样的数据就是数据库的元数据;

2)元数据获取方法

元数据获取方式一:利用命令获取(show)

# 常用SQL语句的show命令查看元数据信息
mysql> show databases;
-- 查询数据库服务中的所有数据库信息(数据库名称-元数据)

mysql> show tables;
mysql> show tables from mysql;
-- 查询数据库服务中的相应数据表信息(数据表名称-元数据)

mysql> show create database <库名>;
-- 查询数据库服务中的建库语句信息 (建库语句参数-元数据 建库语句就是DDL语句,定义建立数据库的属性信息)

mysql> show create table <表名>;
-- 查询数据库服务中的建表语句信息 (建表语句参数-元数据 建表语句就是DDL语句,定义建立数据表的属性信息)

mysql> desc <表名>;
mysql> show columns from <表名>;
-- 查询数据库服务中的数据表的结构(数据表的列定义信息-元数据)

mysql> show table status from <库名>;
-- 查询数据库服务中的相应数据表状态 (数据表的状态信息/统计信息-元数据)

mysql> show table status from world like 'city' \G
*************************** 1. row ***************************
           Name: city                 -- 数据表名称信息
         Engine: InnoDB           -- 使用的数据库引擎信息
        Version: 10
     Row_format: Dynamic
           Rows: 4046                -- 数据表的行数信息
 Avg_row_length: 101         -- 平均行长度
    Data_length: 409600       
Max_data_length: 0
   Index_length: 114688      -- 索引长度信息
      Data_free: 0
 Auto_increment: 4080       -- 自增列的值计数
    Create_time: 2022-11-04 09:13:27   -- 数据表创建时间
    Update_time: NULL
     Check_time: NULL
      Collation: utf8mb4_0900_ai_ci      -- 校对规则信息
       Checksum: NULL
 Create_options: 
        Comment: 
1 row in set (0.00 sec)
-- 查看数据库服务中的具体数据库表的状态信息(属于单库或单表查询)

mysql> show index from world.city;
-- 查询数据库服务中的相应数据表的索引情况(了解即可)

mysql> show grants for root@'localhost';
-- 查询数据库服务中的用户权限属性配置信息

mysql> show [full] processlist;
-- 查询数据库服务的系统状态信息,表示当前数据库的所有连接情况

mysql> show variables; 
mysql> show variables like '%xx%';
-- 查询数据库服务的所有配置信息

mysql> show status;
mysql> show status like '%lock%'; 
-- 查询数据库服务的系统整体状态,表示当前数据库服务运行的即时状态情况

mysql> show binary logs;
-- 查询数据库服务的所有二进制日志信息(binlog日志)

mysql> show master status;
-- 查询数据库服务正在使用的二进制日志

mysql> show binlog events in 'binlog.000009';
-- 查询数据库服务具体二进制日志内容事件信息

mysql> show engine innodb status \G
-- 查询数据库服务存储引擎相关信息

mysql> show slave hosts;
-- 在数据库服务主库查看从库信息

mysql> show slave status;
-- 查询数据库服务主从状态信息

说明:使用show语句虽然可以快速得到相应的数据库元数据信息,但是查询功能过于单一,想查询全面信息,就需要执行多条语句;

元数据获取方式二:利用库中视图(information_schema)

视图概念:

将查询基表元数据语句信息方法封装在一个变量或别名中,这个封装好的变量或别名就成为视图,视图信息都是存储在内存中的表

元数据信息存储在系统基表中,通过一般的select命令只能查看数据信息,不能查看到系统基表,以免被随意调整篡改;

而查询基表的语句过于复杂,可以将整个查询基表语句定义为一个视图信息(等价于别名/变量),调取视图等价于调取查询基表语句;

information_schema库中的内存表都是每次数据库服务启动时生成的,里面存储了查询元数据基表的视图信息;

# 假设查询基表语句信息如下
select a.tname as '老师名',group_concat(d.sname)  as '不及格学生名'
from teacher as a
join course as b
on a.tno=b.tno 
join sc as c
on b.cno=c.cno 
join student as d
on c.sno=d.sno 
where c.score<60 
group by a.tno;


mysql> create view oldboy as select a.tname as '老师名',group_concat(d.sname)  as '不及格学生名' from teacher as a join course as b on a.tno=b.tno  join sc as c on b.cno=c.cno  join student as d on c.sno=d.sno  where c.score<
<60  group by a.tno;
Query OK, 0 rows affected (0.02 sec)

mysql> select * from oldboy;
+-----------+--------------------+
| 老师名    | 不及格学生名       |
+-----------+--------------------+
| xiaoQ     | zhang3             |
| xiaoA     | li4,zh4            |
+-----------+--------------------+
2 rows in set (0.01 sec)

视图查询:

# 切换进入information_schema数据库中查看表信息
mysql> use information_schema;
mysql> show tables;
-- 此时看到的所有表信息,其实都是视图信息

# 查看获取视图信息创建语句
mysql> show create view tables;
-- 查看tables这个视图表的创建过程

# 查看视图表信息应用
# 统计数据库资产信息(数据资产),获取每个库中表的个数和名称信息(业务相关)
mysql> desc information_schema.tables;
-- 查看information_scheam中的tables表的结构信息;
mysql> select table_schema,count(*),group_concat(table_name) from information_schema.tables group by table_schema;
-- 获取相应数据库中表的个数,与数据库中拥有的表信息
mysql> select table_schema,count(*),group_concat(table_name) from information_schema.tables where table_schema not in ('mysql','sys','performance_schema','information_') group by table_schema;

# 统计数据库资产信息(数据资产),获取每个数据库数据占用磁盘空间
mysql> select table_schema,sum(table_rows*avg_row_length+index_length)/1024/1024 from information_schema.tables where table_schema not in ('mysql','sys','performance_schema','information_') group by table_schema;

# 统计数据库资产信息(数据资产),获取具有碎片信息的表
mysql> select table_schema,table_name,data_free from information_schema.tables where table_schema not in ('mysql','sys','performance_schema','information_') and data_free >0 ;
-- 碎片信息过多会导致索引信息失效,以及统计信息不真实的情况

# 统计数据库资产信息(数据资产),处理具有碎片信息的表
mysql> alter table t1 engine=innodb;
-- 可以对已经是innodb存储引擎的表做操作,实现整理碎片功能
mysql> select concat("alter table ",table_schema,".",table_name," engine=innodb") from information_schema.tables where table_schema not in ('mysql','sys','performance_schema','information_') and data_free >0 ;
-- 可以对已经是innodb存储引擎的表做操作,实现批量整理碎片功能

# 统计数据库资产信息(数据资产),获取数据库中非innodb表信息
mysql>select table_schema,table_name,engine from information_schema.tables where table_schema not in ('mysql','sys','performance_schema','information_') and engine!='innodb';
-- 获取非innodb数据库引擎表
mysql> use school;
mysql> create table t1 (id int) engine=myisam;
mysql> create table t2 (id int) engine=myisam;
mysql> create table t3 (id int) engine=myisam;
-- 模拟创建一些myisam引擎数据表

# 统计数据库资产信息(数据资产),修改数据库中非innodb表信息替换成innodb
mysql> alter table world.t1 engine=innodb;
-- 可以对不是innodb存储引擎的表做操作,实现数据表引擎修改
mysql> select concat("alter table ",table_schema,".",table_name," engine=innodb") from information_schema.tables where table_schema not in ('mysql','sys','performance_schema','information_') and  engine !='innodb';
mysql> select concat("alter table ",table_schema,".",table_name," engine=innodb;") from information_schema.tables where table_schema not in ('mysql','sys','performance_schema','information_') and  engine!='innodb' into outfile '/tmp/alter.sql';  
ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
vim /etc/my.cnf
[mysqld]
secure-file-priv=/tmp
-- 修改配置文件参数信息,实现将数据库操作的数据信息导入到系统文件中,配置完毕重启数据库服务

mysql> source /tmp/alter.sql
-- 可以对不是innodb存储引擎的表做操作,实现数据表批量化引擎修改,调用数据库脚本信息

需求一:统计数据库资产信息(数据资产),获取每个库中表的个数和名称信息

mysql> select table_schema,table_name from information_schema.tables where table_schema not in ('mysql','sys','performance_schema','information_schema') ;
+--------------+-----------------+
| TABLE_SCHEMA | TABLE_NAME      |
+--------------+-----------------+
| oldboy       | class           |
| oldboy       | stu1            |
| oldboy       | student         |
| oldboy       | t_foreign       |
| school       | course          |
| school       | oldboy          |
| school       | sc              |
| school       | student         |
| school       | teacher         |
| world        | city            |
| world        | country         |
| world        | countrylanguage |
| xiaoB        | t1              |
| xiaoB        | t2              |
| xiaoQ        | stu01           |
| xiaoQ        | stu02           |
| xiaoQ        | t1              |
| xiaoZ        | t1              |
| xiaoZ        | t2              |
| xiaoZ        | t3              |
+--------------+-----------------+
20 rows in set (0.01 sec)


mysql> select table_schema,count(*),group_concat(table_name) from information_schema.tables where table_schema not in ('mysql','sys','performance_schema','information_schema') group by table_schema;
+--------------+----------+----------------------------------+
| TABLE_SCHEMA | count(*) | group_concat(table_name)         |
+--------------+----------+----------------------------------+
| oldboy       |        4 | stu1,student,t_foreign,class     |
| school       |        5 | course,oldboy,sc,student,teacher |
| world        |        3 | country,countrylanguage,city     |
| xiaoB        |        2 | t1,t2                            |
| xiaoQ        |        3 | stu01,stu02,t1                   |
| xiaoZ        |        3 | t1,t2,t3                         |
+--------------+----------+----------------------------------+
6 rows in set (0.00 sec)

需求二:统计数据库资产信息(数据资产),获取每个数据库数据占用磁盘空间

select table_schema,sum(table_rows*avg_row_length+index_length)/1024/1024 
from information_schema.tables 
where table_schema not in ('mysql','sys','performance_schema','information_schema') group by table_schema;
+--------------+-------------------------------------------------------+
| TABLE_SCHEMA | sum(table_rows*avg_row_length+index_length)/1024/1024 |
+--------------+-------------------------------------------------------+
| oldboy       |                                            0.09374619 |
| school       |                                            0.06248379 |
| world        |                                            0.76367092 |
| xiaoB        |                                            0.00000000 |
| xiaoQ        |                                            0.00000000 |
| xiaoZ        |                                            0.04686356 |
+--------------+-------------------------------------------------------+
6 rows in set (0.00 sec)

需求三:统计数据库资产信息(数据资产),获取具有碎片信息的表

mysql> select table_schema,table_name,data_free from information_schema.tables where table_schema not in ('mysql','sys','performance_schema','information_schema') and data_free >0 ;
-- 碎片信息过多会导致索引信息失效,以及统计信息不真实的情况

需求四:统计数据库资产信息(数据资产),处理具有碎片信息的表

mysql> alter table t1 engine=innodb;
-- 可以对已经是innodb存储引擎的表做操作,实现整理碎片功能

mysql> select concat("alter table ",table_schema,".",table_name," engine=innodb") from information_schema.tables where table_schema not in ('mysql','sys','performance_schema','information_schema') and data_free >0 ;
-- 可以对已经是innodb存储引擎的表做操作,实现批量整理碎片功能

需求五:统计数据库资产信息(数据资产),获取数据库中非innodb表信息

mysql>select table_schema,table_name,engine from information_schema.tables where table_schema not in ('mysql','sys','performance_schema','information_schema') and engine!='innodb';
-- 获取非innodb数据库引擎表
+--------------+------------+--------+
| TABLE_SCHEMA | TABLE_NAME | ENGINE |
+--------------+------------+--------+
| oldboy       | t1         | MyISAM |
| oldboy       | t2         | MyISAM |
| oldboy       | t3         | MyISAM |
+--------------+------------+--------+
3 rows in set (0.01 sec)


mysql> use school;
mysql> create table t1 (id int) engine=myisam;
mysql> create table t2 (id int) engine=myisam;
mysql> create table t3 (id int) engine=myisam;
-- 模拟创建一些myisam引擎数据表

# 调整:批量操作
# 统计数据库资产信息(数据资产),修改数据库中非innodb表信息替换成innodb
mysql> alter table world.t1 engine=innodb;
-- 可以对不是innodb存储引擎的表做操作,实现数据表引擎修改
mysql> select concat("alter table ",table_schema,".",table_name," engine=innodb;") from information_schema.tables where table_schema not in ('mysql','sys','performance_schema','information_schema') and  engine !='innodb';

mysql> select concat("alter table ",table_schema,".",table_name," engine=innodb;") from information_schema.tables where table_schema not in ('mysql','sys','performance_schema','information_schema') and  engine!='innodb' into outfile '/tmp/alter.sql';  
ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement

vim /etc/my.cnf
[mysqld]
secure-file-priv=/tmp
-- 修改配置文件参数信息,实现将数据库操作的数据信息导入到系统文件中,配置完毕重启数据库服务

# 加载sql文件,实现批量修改存储引擎信息
mysql> source /tmp/alter.sql
-- 可以对不是innodb存储引擎的表做操作,实现数据表批量化引擎修改,调用数据库脚本信息

作业:如果创建了多个数据库,或者数据库中创建了多个表,如何批量除?

找出需要删除的库 以及 表 并拼凑命令

mysql> select table_schema,table_name from information_schema.tables where table_schema not in ('mysql','sys','peerformance_schema','information_schema') ;
+--------------+-----------------+
| TABLE_SCHEMA | TABLE_NAME      |
+--------------+-----------------+
| oldboy       | class           |
| oldboy       | stu1            |
| oldboy       | student         |
| oldboy       | t1              |
| oldboy       | t2              |
| oldboy       | t3              |
| oldboy       | t_foreign       |
| school       | course          |
| school       | oldboy          |
| school       | sc              |
| school       | student         |
| school       | teacher         |
| world        | city            |
| world        | country         |
| world        | countrylanguage |
| xiaoB        | t1              |
| xiaoB        | t2              |
| xiaoQ        | stu01           |
| xiaoQ        | stu02           |
| xiaoQ        | t1              |
| xiaoZ        | t1              |
| xiaoZ        | t2              |
| xiaoZ        | t3              |
+--------------+-----------------+
23 rows in set (0.00 sec)

mysql> select concat("drop table ",table_schema,".`",table_name,"`;") from information_schema.tables where table_schema not in ('mysql','sys','performance_schema','information_schema') and table_schema="oldboy" and table_name not in ('t3') into outfile '/tmp/drop_table.sql';
Query OK, 6 rows affected (0.01 sec)

# 执行删除操作
mysql> source /tmp/drop_table.sql;
ERROR 3730 (HY000): Cannot drop table 'class' referenced by a foreign key constraint 'student_ibfk_1' on table 'student'.
Query OK, 0 rows affected (0.03 sec)

Query OK, 0 rows affected (0.01 sec)

Query OK, 0 rows affected (0.02 sec)

Query OK, 0 rows affected (0.01 sec)

Query OK, 0 rows affected (0.01 sec)

mysql> use oldboy;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+------------------+
| Tables_in_oldboy |
+------------------+
| class            |
| t3               |
+------------------+
2 rows in set (0.00 sec)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值