概述
mysql进阶
文章目录
- 内连接
- 外连接
- 左连接
- 右连接
- 分组查询
- GROUP BY单独使用
- GROUP BY 与 GROUP_CONCAT()
- GROUP BY 与聚合函数
- 分组依据与汇总
- 子查询
- mysql数据库备份与恢复
- mysql备份工具mysqldump
- mysql数据恢复
- 差异备份与恢复
内连接
内连接(INNER JOIN)主要通过设置连接条件的方式,来移除查询结果中某些数据行的交叉连接。简单来说,就是利用条件表达式来消除交叉连接的某些数据行。
内连接使用 INNER JOIN 关键字连接两张表,并使用 ON 子句来设置连接条件。如果没有连接条件,INNER JOIN 和 CROSS JOIN 在语法上是等同的,两者可以互换。
内连接的语法格式如下:
SELECT <字段名> FROM <表1> INNER JOIN <表2> [ON子句];
语法说明如下。
- 字段名:需要查询的字段名称。
- <表1><表2>:需要内连接的表名。
- INNER JOIN :内连接中可以省略 INNER 关键字,只用关键字 JOIN。
- ON 子句:用来设置内连接的连接条件
用内连接查询学生姓名和相对应的课程名称
mysql> select
s.name ,c.course_name
from tb_students_info
s
inner join
tb_course c
on
s.course_id
=
c.id;
+--------+-------------+
| name
| course_name |
+--------+-------------+
| Dany
| Java
|
| Green
| Nysql
|
| Henry
| Java
|
| Jane
| Python
|
| Jim
| Nysql
|
| john
| Go
|
| Lilyi
| Go
|
| Suan
| C++
|
| Thomas | C++
|
| Tom
| C++
|
+--------+-------------+
10 rows in set (0.00 sec)
select s.name ,c.course_name from tb_students_info s inner join tb_course c on s.course_id = s.id and c.course_name = ‘Mysql’;
在这里的查询语句中,两个表之间的关系通过 INNER JOIN指定,连接的条件使用ON子句给出。
注意:当对多个表进行查询时,要在 SELECT 语句后面指定字段是来源于哪一张表。因此,在多表查询时,SELECT 语句后面的写法是表名.列名。另外,如果表名非常长的话,也可以给表设置别名,这样就可以直接在 SELECT 语句后面写上表的别名.列名
外连接
内连接的查询结果都是符合连接条件的记录,而外连接会先将连接的表分为基表和参考表,再以基表为依据返回满足和不满足条件的记录。
外连接可以分为左外连接和右外连接2种
左连接
左外连接又称为左连接,使用 LEFT OUTER JOIN 关键字连接两个表,并使用 ON 子句来设置连接条件。
左连接的语法格式如下:
SELECT <字段名> FROM <表1> LEFT OUTER JOIN <表2> <ON子句>;
语法说明如下:
- 字段名:需要查询的字段名称。
- <表1><表2>:需要左连接的表名。
- LEFT OUTER JOIN:左连接中可以省略 OUTER 关键字,只使用关键字 LEFT JOIN。
- ON 子句:用来设置左连接的连接条件,不能省略
在tb_course表中插入一个数据
mysql> insert tb_course(id,course_name) values (6,'HTML');
Query OK, 1 row affected (0.00 sec)
查看tb_course表中的数据
mysql> select * from tb_course;
+----+-------------+
| id | course_name |
+----+-------------+
|
1 | Java
|
|
2 | Nysql
|
|
3 | Python
|
|
4 | Go
|
|
5 | C++
|
|
6 | HTML
|
+----+-------------+
6 rows in set (0.00 sec)
在tb——students表中插入一个数据
mysql> insert tb_students_info(id,name,age,sex,height,course_id) values (11,'LiMing',22,'m','180',7);
Query OK, 1 row affected (0.00 sec)
查看tb_students_info表中的数据
mysql> select * from tb_students_info;
+----+--------+------+------+--------+-----------+
| id | name
| age
| sex
| height | course_id |
+----+--------+------+------+--------+-----------+
|
1 | Dany
|
25 | w
|
160 |
1 |
|
2 | Green
|
23 | w
|
158 |
2 |
|
3 | Henry
|
23 | m
|
185 |
1 |
|
4 | Jane
|
22 | w
|
12 |
3 |
|
5 | Jim
|
24 | m
|
175 |
2 |
|
6 | john
|
21 | m
|
172 |
4 |
|
7 | Lilyi
|
22 | m
|
165 |
4 |
|
8 | Suan
|
23 | w
|
170 |
5 |
|
9 | Thomas |
22 | w
|
178 |
5 |
| 10 | Tom
|
23 | w
|
165 |
5 |
| 11 | LiMing |
22 | m
|
180 |
7 |
+----+--------+------+------+--------+-----------+
11 rows in set (0.00 sec)
查询所有学生姓名和相对应的课程名称,包括没有课程的学生
mysql> select s.name,c.course_name from tb_students_info s left outer join tb_course c on s.`course_id`=c.`id`;
+--------+-------------+
| name
| course_name |
+--------+-------------+
| Dany
| Java
|
| Green
| Nysql
|
| Henry
| Java
|
| Jane
| Python
|
| Jim
| Nysql
|
| john
| Go
|
| Lilyi
| Go
|
| Suan
| C++
|
| Thomas | C++
|
| Tom
| C++
|
| LiMing | NULL
|
+--------+-------------+
11 rows in set (0.00 sec)
发现tb_students_info 表中相应的值,而从 tb_course 表中取出的值为 NULL。
右连接
右外连接又称为右连接,右连接是左连接的反向连接。使用 RIGHT OUTER JOIN 关键字连接两个表,并使用 ON 子句来设置连接条件。
右连接的语法格式如下:
SELECT <字段名> FROM <表1> RIGHT OUTER JOIN <表2> <ON子句>;
语法说明如下:
- 字段名:需要查询的字段名称。
- <表1><表2>:需要右连接的表名。
- RIGHT OUTER JOIN:右连接中可以省略 OUTER 关键字,只使用关键字 RIGHT JOIN。
- ON 子句:用来设置右连接的连接条件,不能省略
mysql> select s.name,c.course_name from tb_students_info s right outer join tb_course c on s.`course_id`=c.`id`;
+--------+-------------+
| name
| course_name |
+--------+-------------+
| Dany
| Java
|
| Green
| Nysql
|
| Henry
| Java
|
| Jane
| Python
|
| Jim
| Nysql
|
| john
| Go
|
| Lilyi
| Go
|
| Suan
| C++
|
| Thomas | C++
|
| Tom
| C++
|
| NULL
| HTML
|
+--------+-------------+
11 rows in set (0.00 sec)
发现该条记录只取出了 tb_course 表中相应的值,而从 tb_students_info 表中取出的值为 NULL。
分组查询
在 MySQL 中,GROUP BY 关键字可以根据一个或多个字段对查询结果进行分组。
使用 GROUP BY 关键字的语法格式如下:
GROUP BY
<字段名>
其中,"字段名"表示需要分组的字段名称,多个字段时用逗号隔开
GROUP BY单独使用
单独使用 GROUP BY 关键字时,查询结果会只显示每个分组的第一条记录。
tb_students_info 表中的 sex 字段进行分组查询
mysql> select name,sex from tb_students_info group by sex;
+--------+------+
| name
| sex
|
+--------+------+
| Henry
| m
|
| Dany
| w
|
+--------+------+
2 rows in set (0.00 sec)
结果中只显示了两条记录,这两条记录的 sex 字段的值分别为“女”和“男”。
GROUP BY 与 GROUP_CONCAT()
GROUP BY 关键字可以和 GROUP_CONCAT() 函数一起使用。GROUP_CONCAT() 函数会把每个分组的字段值都显示出来。
tb_students_info 表中的 sex 字段进行分组查询,使用 GROUP_CONCAT() 函数将每个分组的 name 字段的值都显示出来
mysql> select sex, group_concat(name) from tb_students_info group by sex;
+------+---------------------------------+
| sex
| group_concat(name)
|
+------+---------------------------------+
| m
| Henry ,Jim,john,Lilyi,LiMing
|
| w
| Dany,Green,Jane,Suan,Thomas,Tom |
+------+---------------------------------+
2 rows in set (0.00 sec)
由结果可以看到,查询结果分为两组,sex 字段值为"女"的是一组,值为"男"的是一组,且每组的学生姓名都显示出来了。
tb_students_info 表中的年龄和性别和名字字段进行分组查询
mysql> select age,sex,group_concat(name) from tb_students_info group by age,sex;
+------+------+--------------------+
| age
| sex
| group_concat(name) |
+------+------+--------------------+
|
21 | m
| john
|
|
22 | m
| Lilyi,LiMing
|
|
22 | w
| Jane,Thomas
|
|
23 | m
| Henry
|
|
23 | w
| Green,Suan,Tom
|
|
24 | m
| Jim
|
|
25 | w
| Dany
|
+------+------+--------------------+
7 rows in set (0.00 sec)
-
实例在分组过程中,先按照 age 字段进行分组,当 age 字段值相等时,再把 age 字段值相等的记录按照 字段进行分组
-
多个字段分组查询时,会先按照第一个字段进行分组。如果第一个字段中有相同的值,MySQL 才会按照第二个字段进行分组。如果第一个字段中的数据都是唯一的,那么 MySQL 将不再对第二个字段进行分组
GROUP BY 与聚合函数
在数据统计时,GROUP BY 关键字经常和聚合函数一起使用。
聚合函数包括 COUNT(),SUM(),AVG(),MAX() 和 MIN()。其中,COUNT() 用来统计记录的条数;SUM() 用来计算字段值的总和;AVG() 用来计算字段值的平均值;MAX() 用来查询字段的最大值;MIN() 用来查询字段的最小值
tb_students_info 表的 字段进行分组查询,使用 COUNT() 函数计算每一组的记录数
mysql> select sex,count(sex) from tb_students_info group by sex;
+------+------------+
| sex
| count(sex) |
+------+------------+
| m
|
5 |
| w
|
6 |
+------+------------+
2 rows in set (0.00 sec)
结果显示,字段值为“女”的记录是一组,有 6条记录;字段值为“男”的记录是一组,有 5 条记录.
分组依据与汇总
WITH POLLUP 关键字用来在所有记录的最后加上一条记录,这条记录是上面所有记录的总和,即统计记录数量。
tb_students_info 表中的 字段进行分组查询,并使用 WITH ROLLUP 显示记录的总和
mysql> select sex,group_concat(name) from tb_students_info group by sex with
rollup;
+------+--------------------------------------------------------------+
| sex
| group_concat(name)
|
+------+--------------------------------------------------------------+
| m
| Henry ,Jim,john,Lilyi,LiMing
|
| w
| Dany,Green,Jane,Suan,Thomas,Tom
|
| NULL | Henry ,Jim,john,Lilyi,LiMing,Dany,Green,Jane,Suan,Thomas,Tom |
+------+--------------------------------------------------------------+
3 rows in set (0.00 sec)
查询结果显示,GROUP_CONCAT(name) 显示了每个分组的 name 字段值。同时,最后一条记录的 GROUP_CONCAT(name) 字段的值刚好是上面分组 name 字段值的总和
子查询
子查询是 MySQL 中比较常用的查询方法,通过子查询可以实现多表查询。子查询指将一个查询语句嵌套在另一个查询语句中。子查询可以在 SELECT、UPDATE 和 DELETE 语句中使用,而且可以进行多层嵌套。在实际开发时,子查询经常出现在 WHERE 子句中。
子查询在 WHERE 中的语法格式如下:
WHERE <表达式> <操作符> (子查询)
其中,操作符可以是比较运算符和 IN、NOT IN、EXISTS、NOT EXISTS 等关键字。
-
在|NOT IN
当表达式与子查询返回的结果集中的某个值相等时,返回 TRUE,否则返回 FALSE;若使用关键字 NOT,则返回值正好相反。 -
存在|NOT EXISTS
用于判断子查询的结果集是否为空,若子查询的结果集不为空,返回 TRUE,否则返回 FALSE;若使用关键字 NOT,则返回的值正好相反。
使用子查询在 tb_students_info 表和 tb_course 表中查询学习 Java 课程的学生姓名
mysql> select name from tb_students_info where course_id in (select id from tb_course where course_name = 'Java');
+--------+
| name
|
+--------+
| Dany
|
| Henry
|
+--------+
2 rows in set (0.00 sec)
结果显示,学习 Java 课程的只有 Dany 和 Henry.
查询出 tb_course 表中课程为 Java 的 id
mysql> select id from tb_course where course_name = 'Java';
+----+
| id |
+----+
|
1 |
+----+
1 row in set (0.00 sec)
可以看到,符合条件的 id 字段的值为 1。
tb_students_info 表中查询 course_id 等于 1 的学生姓名**
mysql> select name from tb_students_info where course_id in(1);
+--------+
| name
|
+--------+
| Dany
|
| Henry
|
+--------+
2 rows in set (0.01 sec)
习惯上,外层的 SELECT 查询称为父查询,圆括号中嵌入的查询称为子查询(子查询必须放在圆括号内)。MySQL 在处理上例的 SELECT 语句时,执行流程为:先执行子查询,再执行父查询。
实例
在 SELECT 语句中使用 NOT IN 关键字,查询没有学习 Java 课程的学生姓名
mysql> select name from tb_students_info where course_id not in (select id from tb_course where course_name = 'Java');
+--------+
| name
|
+--------+
| Green
|
| Jane
|
| Jim
|
| john
|
| Lilyi
|
| Suan
|
| Thomas |
| Tom
|
| LiMing |
+--------+
9 rows in set (0.00 sec)
没有学习 Java 课程的是除了 Dany 和 Henry 之外的学生
使用=运算符,在 tb_course 表和 tb_students_info 表中查询出所有学习 Python 课程的学生姓名
mysql> select name from tb_students_info where course_id = (select id from tb_course where course_name = 'python');
+------+
| name |
+------+
| Jane |
+------+
1 row in set (0.00 sec)
学习python课程的学生只有jane
使用<>运算符,在 tb_course 表和 tb_students_info 表中查询出没有学习 Python 课程的学生姓名
mysql> select name from tb_students_info where course_id <> (select id from tb_course where course_name = 'python');
+--------+
| name
|
+--------+
| Dany
|
| Green
|
| Henry
|
| Jim
|
| john
|
| Lilyi
|
| Suan
|
| Thomas |
| Tom
|
| LiMing |
+--------+
10 rows in set (0.00 sec)
没有学习 Python 课程的是除了 Jane 之外的学生
查询 tb_course 表中是否存在 id=1 的课程,如果存在,就查询出 tb_students_info 表中的记录
mysql> select * from tb_students_info where exists(select course_name from tb_course where id=1);
+----+--------+------+------+--------+-----------+
| id | name
| age
| sex
| height | course_id |
+----+--------+------+------+--------+-----------+
|
1 | Dany
|
25 | w
|
160 |
1 |
|
2 | Green
|
23 | w
|
158 |
2 |
|
3 | Henry
|
23 | m
|
185 |
1 |
|
4 | Jane
|
22 | w
|
12 |
3 |
|
5 | Jim
|
24 | m
|
175 |
2 |
|
6 | john
|
21 | m
|
172 |
4 |
|
7 | Lilyi
|
22 | m
|
165 |
4 |
|
8 | Suan
|
23 | w
|
170 |
5 |
|
9 | Thomas |
22 | w
|
178 |
5 |
| 10 | Tom
|
23 | w
|
165 |
5 |
| 11 | LiMing |
22 | m
|
180 |
7 |
+----+--------+------+------+--------+-----------+
11 rows in set (0.00 sec)
由结果可以看到,tb_course 表中存在 id=1 的记录,因此 EXISTS 表达式返回 TRUE,外层查询语句接收 TRUE 之后对表 tb_students_info 进行查询,返回所有的记录。
查询 tb_course 表中是否存在 id=1 的课如果存在,就查询出 tb_students_info 表中 age 字段大于 24 的记录
mysql> select * from tb_students_info where age>24 and exists(select course_name from tb_course where id=1);
+----+------+------+------+--------+-----------+
| id | name | age
| sex
| height | course_id |
+----+------+------+------+--------+-----------+
|
1 | Dany |
25 | w
|
160 |
1 |
+----+------+------+------+--------+-----------+
1 row in set (0.00 sec)
结果显示,从 tb_students_info 表中查询出了一条记录,这条记录的 age 字段取值为 25。内层查询语句从 tb_course 表中查询到记录,返回 TRUE。外层查询语句开始进行查询。根据查询条件,从 tb_students_info 表中查询 年龄 大于 24 的记录。
子查询的功能也可以通过表连接完成,但是子查询会使 SQL 语句更容易阅读和编写。
一般来说,表连接(内连接和外连接等)都可以用子查询替换,但反过来却不一定,有的子查询不能用表连接来替换。子查询比较灵活、方便、形式多样,适合作为查询的筛选条件,而表连接更适合于查看连接表的数据。
mysql数据库备份与恢复
数据厍备份方案∶
- 全量备份
- 增量备份
- 差异备份
冷备份∶先把数据库服务停掉,然后拷贝数据库目录下的文件进行备份 物理备份
热备份∶数据库服务正常运行情况,直接对数据库的数据直接进行备份∶全量备份、增量备份、差异备份
备份方案 | 特点 |
---|---|
全量备份 | 全量备份就是指对某一个时间点上的所有数据或应用进行的一个完全拷贝。 数据恢复快。 备份时间长 |
增量备份 | 增量备份是指在一次全备份或上一次增量备份后,以后每次的备份只需备份 与前一次相比增加和者被修改的文件。这就意味着,第一次增量备份的对象 是进行全备后所产生的增加和修改的文件;第二次增量备份的对象是进行第一次增量 备份后所产生的增加和修改的文件,如此类推。 没有重复的备份数据 备份时间短 恢复数据时必须按一定的顺序进行 |
差异备份 | 备份上一次的完全备份后发生变化的所有文件。 差异备份是指在一次全备份后到进行差异备份的这段时间内 对那些增加或者修改文件的备份。在进行恢复时,我们只需对第一次全量备份和最后一次差异备份进行恢复。 |
mysql备份工具mysqldump
语法:
mysqldump [OPTIONS] database [tables ...]
mysqldump [OPTIONS] --all-databases [OPTIONS]
mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]
常用的OPTIONS:
-uUSERNAME
//指定数据库用户名
-hHOST
//指定服务器主机,请使用ip地址
-pPASSWORD
//指定数据库用户的密码
-P#
//指定数据库监听的端口
全备
mysql> show databases;
+--------------------+
| Database
|
+--------------------+
| information_schema |
| mysql
|
| performance_schema |
| sys
|
| yyz
|
+--------------------+
5 rows in set (0.00 sec)
[root@localhost ~]# mysqldump -uroot -p12345 --all-databases > all-$(date "+%Y%m%d").sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@localhost ~]# ls
all-20220728.sql
anaconda-ks.cfg
nginx-1.22.0
nginx-1.22.0.tar.gz
备份yyz库的tb_course表和tb_students_info表
[root@localhost ~]# mysqldump -uroot -p12345
yyz tb_students_info tb_course > all-table.sqlmysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@localhost ~]# ls
all-20220728.sql
all-table.sql
anaconda-ks.cfg
nginx-1.22.0
nginx-1.22.0.tar.gz
备份yyz库
[root@localhost ~]# mysqldump -uroot -p12345 --databases yyz > yyz.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@localhost ~]# ls
all-20220728.sql
all-table.sql
anaconda-ks.cfg
nginx-1.22.0
nginx-1.22.0.tar.gz
yyz.sql
模拟误删yyz数据库
mysql> drop database yyz;
Query OK, 2 rows affected (0.01 sec)
mysql> show databases;
+--------------------+
| Database
|
+--------------------+
| information_schema |
| mysql
|
| performance_schema |
| sys
|
+--------------------+
4 rows in set (0.00 sec)
mysql数据恢复
恢复yyz数据库
[root@localhost ~]# ls
all-20220728.sql
all-table.sql
anaconda-ks.cfg
nginx-1.22.0
nginx-1.22.0.tar.gz
yyz.sql
[root@localhost ~]# mysql -uroot -p < yyz.sql
Enter password:
[root@localhost ~]# mysql -uroot -p12345 -e 'show databases;'
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------------------+
| Database
|
+--------------------+
| information_schema |
| mysql
|
| performance_schema |
| sys
|
| yyz
|
+--------------------+
恢复yyz数据库的tb_course表和tb_students_info表
mysql> use yyz;
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> source all-table.sql
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
......
mysql> show tables;
+------------------+
| Tables_in_yyz
|
+------------------+
| tb_course
|
| tb_students_info |
+------------------+
2 rows in set (0.00 sec)
模拟删除整个数据库
mysql> drop database yyz;
Query OK, 2 rows affected (0.01 sec)
mysql> show databases;
+--------------------+
| Database
|
+--------------------+
| information_schema |
| mysql
|
| performance_schema |
| sys
|
+--------------------+
4 rows in set (0.00 sec)
恢复整个数据库
[root@localhost ~]# ls
all-20220728.sql
all-table.sql
anaconda-ks.cfg
nginx-1.22.0
nginx-1.22.0.tar.gz
yyz.sql
[root@localhost ~]# mysql -uroot -p12345 < all-20220728.sql
mysql: [Warning] Using a password on the command line interface can be insecure.
[root@localhost ~]# mysql -uroot -p12345 -e 'show databases;'
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------------------+
| Database
|
+--------------------+
| information_schema |
| mysql
|
| performance_schema |
| sys
|
| yyz
|
+--------------------+
差异备份与恢复
恢复整个数据库
[root@localhost ~]# ls
all-20220728.sql
all-table.sql
anaconda-ks.cfg
nginx-1.22.0
nginx-1.22.0.tar.gz
yyz.sql
[root@localhost ~]# mysql -uroot -p12345 < all-20220728.sql
mysql: [Warning] Using a password on the command line interface can be insecure.
[root@localhost ~]# mysql -uroot -p12345 -e 'show databases;'
mysql: [Warning] Using a password on the command line interface can be insecure.
+--------------------+
| Database
|
+--------------------+
| information_schema |
| mysql
|
| performance_schema |
| sys
|
| yyz
|
+--------------------+
最后
以上就是动人雪糕为你收集整理的mysql进阶的全部内容,希望文章能够帮你解决mysql进阶所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复