mysql
Mysql

目录
[toc]
本站内容
- 关系型数据库基础
- 安装MySQL
- 管理数据库和表
- 用户和权限管理
- 函数,存储过程和触发器
- MySQL架构
- 存储引擎(Mysql支持插件式存储引擎)
- 服务器选项,系统和状态变量(这里容易产生混淆)
- 优化查询和索引管理
- 锁和事务管理
- 日志管理(日志种类更多:事务日志、二级日志、慢查询日志、错误日志、通用日志……)
- 备份还原(必备技能)
- MySQL集群
1、数据库原理
数据的时代
- 涉及的数据量大
- 数据不随程序的结束而消失
- 数据被多个应用程序共享
- 大数据
数据的分类:
- 结构化的数据:即有固定格式和有限长度的数据。例如填的表格就是结构化的数据,国籍:中华人民共和国,民族:汉,性别:男,这都叫结构化数据 (mysql适合管理)
- 非结构化的数据:非结构化的数据越来越多,就是不定长、无固定格式的数据,例如网页,有时候非常长,有时候几句话就没了;例如语音,视频都是非结构化的数据 (redis适合管理)
- 半结构化数据:比如:XML或者HTML的格式的数据
数据库的发展史
- 萌芽阶段:文件系统 使用磁盘文件来存储数据
- 初级阶段:第一代数据库 出现了网状模型、层次模型的数据库
- 中级阶段:第二代数据库 关系型数据库和结构化查询语言
- 高级阶段:新一代数据库 “关系-对象”型数据库
文件管理系统的缺点:
- 编写应用程序不方便
- 数据冗余不可避免
- 应用程序依赖性
- 不支持对文件的并发访问
- 数据间联系弱
- 难以按用户视图表示数据
- 无安全控制功能
DBMS 数据库管理系统
数据库:database是数据的汇集,它以一定的组织形式存于存储介质上
DBMS:是管理数据库的系统软件,它实现数据库系统的各种功能。是数据库系统的核心
DBA:负责数据库的规划、设计、协调、维护和管理等工作
应用程序:指以数据库为基础的应用程序

数据库管理系统的优点
- 相互关联的数据的集合
- 较少的数据冗余
- 程序与数据相互独立
- 保证数据的安全、可靠
- 最大限度地保证数据的正确性
- 数据可以并发使用并能同时保证一致性
数据库管理系统的基本功能
- 数据定义
- 数据处理
- 数据安全
- 数据备份
数据库系统的架构
- 单机架构
- 大型主机/终端架构
- 主从式架构(C/S)
- 分布式架构
各种数据库管理系统
网状数据库

最早出现的是网状DBMS,1964年通用电气公司的Charles Bachman成功地开发出世界上第一个网状IDS,也是第一个数据库管理系统,IDS 具有数据模式和日志的特征,只能在GE主机运行。
层次数据库

以树型结构表示实体及其之间联系,关系只支持一对多 代表数据库:IBM IMS
数据会产生冗余情况。
RDBMS 关系型数据库
关系统型数据库相关概念
- 关系 :关系就是二维表,其中:表中的行、列次序并不重要
- 行row:表中的每一行,又称为一条记录record
- 列column:表中的每一列,称为属性,字段,域field
- 主键PK ==Primary key==:用于惟一确定一个记录的字段,一张表只有一个主键 (主键避免一张表里出现了完全一样的记录,要在合适的字段设置主键!)
- 域domain:属性的取值范围,如,性别只能是‘男’和‘女’两个值,人类的年龄只能0-150

常用关系数据库
- MySQL: MySQL, MariaDB, Percona Server
- PostgreSQL: 简称为pgsql,EnterpriseDB
- Oracle
- MSSQL
- DB2 (IBM)
目前主流的还是这种关系型数据库。
redis,mongdb—no sql(非关系型数据库)
数据库排名
https://db-engines.com/en/ranking

office,access数据库,单机版。
- oracle源代码,上亿行了
linux内核源代码,2千万行
据说oracle源代码,上亿行了
关系型数据库理论
实体-联系模型E-R
实体Entity:客观存在并可以相互区分的客观事物或抽象事件称为实体,在E-R图中用矩形框表示实体,把实体名写在框内
属性:实体所具有的特征或性质
联系:联系是数据之间的关联集合,是客观存在的应用语义链
实体内部的联系:指组成实体的各属性之间的联系。如职工实体中,职工号和部门经理号之间有一种关联关系
实体之间的联系:指不同实体之间联系。例:学生选课实体和学生基本信息实体之间
实体之间的联系用菱形框表示
联系类型
- 一对一联系(1:1)
- 一对多联系(1:n):外键
- 多对多联系(m:n):增加第三张表😜
一对多:
==foreign key外键==

多对多:
节约表空间; 数据更加复杂,性能受影响;

数据的操作
- 数据提取:在数据集合中提取感兴趣的内容。SELECT
- 数据更新:变更数据库中的数据。INSERT、DELETE、UPDATE
数据库规划流程
- 收集数据,得到字段 收集必要且完整的数据项 转换成数据表的字段
- 把字段分类,归入表,建立表的关联 关联:表和表间的关系 分割数据表并建立关联的优点 节省空间 减少输入错误 方便数据修改
- 规范化数据库
数据库的正规化分析
面试也会被经常问到,一个比较经典的问题。
范式(设计数据库的规范)
数据库规范化,又称数据库或资料库的正规化、标准化,是数据库设计中的一系列原理和技术,以减少数据库中数据冗余,增进数据的一致性。关系模型的发明者埃德加·科德最早提出这一概念,并于1970年代初定义了第一范式、第二范式和第三范式的概念
设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,不同的规范要求被称为不同范式,各种范式呈递次规范,越高的范式数据库冗余越小。
目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴德斯科范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。满足最低要求的范式是第一范式(1NF)。在第一范式的基础上进一步满足更多规范要求的称为第二范式(2NF),其余范式以次类推。一般数据库只需满足第三范式(3NF)即可
通常情况:达到第一、二、三范式在生产里就够用了,第4、5范式基本用不到。(或者有时,我们甚至会考虑性能,会故意违反第2/3范式,直接使用第一范式。)
范式级别越高:数据库越节约空间,但复杂性越高,性能越低。
学习范式,并不是为了遵守范式,而是为了违反范式哈哈。
第一范式:1NF
无重复的列,每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性,确保每一列的原子性。除去同类型的字段,就是无重复的列。
说明:第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库
举例:
不属于第一范式:
(除去同类型的字段)

(同一列中不能有多个值)

属于第一范式:

第二范式:2NF
属性完全依赖于主键,第二范式必须先满足第一范式,要求表中的每个行必须可以被唯一地区分,通常为表加上每行的唯一标识PK,非PK的字段需要与整个PK有直接相关性
举例:
不符合 第二范式:2NF
(非PK的字段需要与整个PK有直接相关性)

改进后:符合第2范式(拆分成2张表后,节约了空间,但同时也带来了复杂性及性能问题)

第三范式:3NF
属性不依赖于其它非主属性,满足第三范式必须先满足第二范式。第三范式要求一个数据表中不包含已在其它表中已包含的非主关键字信息,非PK的字段间不能有从属关系
举例:
次场景不符合第三范式:(因为非PK的字段间有了从属关系)(会带来一些数据重复录入,数据冗余问题)

解决方法:
还是一样,拆分成2张表就好。(带来的后果还是和上面第二范式一样的效果)

SQL 结构化查询语言简介
SQL:结构化查询语言,Structure Query Language
SQL解释器;
数据存储协议:应用层协议,C/S S:server, 监听于套接字,接收并处理客户端的应用请求 C:Client
客户端程序接口 CLI GUI
应用编程接口 ODBC:Open Database Connectivity JDBC:Java Data Base Connectivity
SQL 基本概念
- 约束:constraint,表中的数据要遵守的限制
- 主键:一个或多个字段的组合,填入的数据必须能在本表中唯一标识本行;必须提供数据,即NOT NULL,一个表只能有一个
- 惟一键:一个或多个字段的组合,填入的数据必须能在本表中唯一标识本行;允许为NULL,一个表可以存在多个
- 外键:一个表中的某字段可填入的数据取决于另一个表的主键或唯一键已有的数据
- 检查:字段值在一定范围内
- 索引:将表中的一个或多个字段中的数据复制一份另存,并且按特定次序排序存储
关系运算
- 选择:挑选出符合条件的行
- 投影:挑选出需要的字段 (列)
- 连接:表间字段的关联
数据抽象
- 物理层:数据存储格式,即RDBMS在磁盘上如何组织文件
- 逻辑层:DBA角度,描述存储什么数据,以及数据间存在什么样的关系
- 视图层:用户角度,描述DB中的部分数据
关系模型的分类
- 关系模型
- 基于对象的关系模型
- 半结构化的关系模型:XML数据
2、MySQL安装和基本使用
MySQL 介绍
MySQL 历史

1979年:TcX公司 Monty Widenius,Unireg 1996年:发布MySQL1.0,Solaris版本,Linux版本 1999年:MySQL AB公司,瑞典 2003年:MySQL 5.0版本,提供视图、存储过程等功能 2008年:Sun 10亿美元收购MySQL 2009年:Oracle 75亿美元收购sun 2009年:Monty成立MariaDB
MySQL系列
MySQL 的三大主要分支
- mysql (用的最多)
- mariadb
- percona Server
官方网址



官方文档


https://www.percona.com/software/mysql-database/percona-server

==版本演变==
MySQL:5.1 –> 5.5 –> 5.6 –> 5.7 –>8.0
MariaDB:5.5 –>10.0–> 10.1 –> 10.2 –> 10.3 –> 10.4 –> 10.5
特别注意:各自版本ios默认mysql版本
1CentOS 8:安装光盘直接提供
2mysql-server:8.0
3mariadb-server : 10.3.17
4
5CentOS 7:安装光盘直接提供
6mariadb-server:5.5 服务器包
7mariadb 客户端工具包
8
9CentOS 6:
10mysql-server:5.1 服务器包
11mysql 客户端工具包
MYSQL的特性
==插件式存储引擎==:也称为“表类型”,存储管理器有多种实现版本,功能和特性可能均略有差别;用户可根据需要灵活选择,Mysql5.5.5开始,innoDB引擎是MYSQL默认引擎
- MyISAM ==> Aria
- InnoDB ==> XtraDB
这里会有一个经典的面试题:InnoDB和MyISAM存储引擎有什么区别。
单进程,多线程
诸多扩展和新特性
提供了较多测试组件
开源
MySQL 安装方式介绍和快速安装
安装方式介绍
- 源代码:编译安装 (生产环境,可以定制)
- 二进制格式的程序包:展开至特定路径,并经过简单配置后即可使用 (绿色安装)
- 程序包管理器管理的程序包 (测试环境)
RPM包安装MySQL
CentOS 安装光盘 项目官方:https://downloads.mariadb.org/mariadb/repositories/ 国内镜像:https://mirrors.tuna.tsinghua.edu.cn/mariadb/yum/ https://mirrors.tuna.tsinghua.edu.cn/mysql/yum/
初始化脚本提高安全性
运行脚本:mysql_secure_installation
1设置数据库管理员root口令
2禁止root远程登录
3删除anonymous用户帐号
4删除test数据库
- mariadb 10.4.33(centos7安装的)
1Enter current password for root (enter for none): #默认没密码,这里直接回车
2
3
4You already have your root account protected, so you can safely answer 'n'.
5Switch to unix_socket authentication [Y/n] #输入n(远程可以登录)
6
7#mysql.sock 使用unix socket登录(只能在本地登录,不能远程登录);
8/var/lib/mysql/mysql.sock文件
9
10Change the root password? [Y/n] #输入y
11New password: #输入密码:xyy520
12Re-enter new password:
13
14Remove anonymous users? [Y/n] #输入y
15
16Disallow root login remotely? [Y/n] #输入y,禁用root远程登录
17
18Remove test database and access to it? [Y/n] #输入y
19
20Reload privilege tables now? [Y/n] #输入y(是否加载权限)
测试:
(直接空口令也是可以登录的……)
1[root@linux-test ~]#mysql
2Welcome to the MariaDB monitor. Commands end with ; or \g.
3Your MariaDB connection id is 25
4Server version: 10.4.33-MariaDB MariaDB Server
5
6Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
7
8Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
9
10MariaDB [(none)]> status
11--------------
12mysql Ver 15.1 Distrib 10.4.33-MariaDB, for Linux (x86_64) using readline 5.1
13
14Connection id: 25
15Current database:
16Current user: root@localhost #以root身份登录的:
17SSL: Not in use
18Current pager: stdout
19Using outfile: ''
20Using delimiter: ;
21Server: MariaDB
22Server version: 10.4.33-MariaDB MariaDB Server
23Protocol version: 10
24Connection: Localhost via UNIX socket
25Server characterset: latin1
26Db characterset: latin1
27Client characterset: utf8
28Conn. characterset: utf8
29UNIX socket: /var/lib/mysql/mysql.sock
30Uptime: 1 day 3 hours 44 min 16 sec
31
32Threads: 6 Questions: 180 Slow queries: 0 Opens: 37 Flush tables: 1 Open tables: 30 Queries per second avg: 0.001
33--------------
34
35MariaDB [(none)]>
36
37
38
39
40#可以看到root是有口令的:(匿名账号也删除了)
41MariaDB [mysql]> select user,host,password from user;
42+-------------+-----------+-------------------------------------------+
43| User | Host | Password |
44+-------------+-----------+-------------------------------------------+
45| mariadb.sys | localhost | |
46| root | localhost | *ABE374A5F247C93961AD4726B39A5A84FA3BC3B1 |
47| mysql | localhost | invalid |
48+-------------+-----------+-------------------------------------------+
493 rows in set (0.001 sec)
50
51MariaDB [mysql]>
52
53
54
55#重启服务后,root还是可以直接免密登录数据库的:
56[root@linux-test ~]#systemctl restart mariadb
57[root@linux-test ~]#mysql
58Welcome to the MariaDB monitor. Commands end with ; or \g.
59Your MariaDB connection id is 8
60Server version: 10.4.33-MariaDB MariaDB Server
61
62Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
63
64Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
65
66MariaDB [(none)]>
因此,在本地,使用root用户,空口令是可以直接登录数据库的。(正常登录的话,root登录也是需要输入口令的!!!,其他版本是必须要输入口令才能登的)
1[root@linux-test ~]#mysql -uroot -pxyy520 ##这里明确地输密码也是可以的。
2Welcome to the MariaDB monitor. Commands end with ; or \g.
3Your MariaDB connection id is 9
4Server version: 10.4.33-MariaDB MariaDB Server
5
6Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
7
8Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
9
10MariaDB [(none)]>
11
12
13[root@linux-test ~]#mysql -uroot
14Welcome to the MariaDB monitor. Commands end with ; or \g.
15Your MariaDB connection id is 10
16Server version: 10.4.33-MariaDB MariaDB Server
17
18Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
19
20Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
21
22MariaDB [(none)]>
23
24
25[root@linux-test ~]#mysql -uroot -p
26Enter password:
27Welcome to the MariaDB monitor. Commands end with ; or \g.
28Your MariaDB connection id is 11
29Server version: 10.4.33-MariaDB MariaDB Server
30
31Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
32
33Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
34
35MariaDB [(none)]>
退出shell后重新登陆,还是一样的效果。
当然,仅限于root用户而言:(普通用户使用root去登录,不输入密码很定是有问题的)
1[root@linux-test ~]#su - xyy
2Last login: Fri Mar 29 07:43:03 CST 2024 on pts/1
3[xyy@linux-test ~]$mysql -uroot -p
4Enter password:
5ERROR 1698 (28000): Access denied for user 'root'@'localhost'
6[xyy@linux-test ~]$
7
8
9[xyy@linux-test ~]$mysql -uroot -p
10Enter password: ##输入正确密码后。
11Welcome to the MariaDB monitor. Commands end with ; or \g.
12Your MariaDB connection id is 14
13Server version: 10.4.33-MariaDB MariaDB Server
14
15Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
16
17Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
18
19MariaDB [(none)]>
因此:
root是操作系统管理员,当然对mysql具有绝对的控制权哦。
另外,需要注意:
目前配置的策略是,只允许在本机登录数据库才行,远程是不允许被登录的。(只能单机使用,不能跨网络使用)
1MariaDB [mysql]> select user,host,password from user;
2+-------------+-----------+-------------------------------------------+
3| User | Host | Password |
4+-------------+-----------+-------------------------------------------+
5| mariadb.sys | localhost | |
6| root | localhost | *ABE374A5F247C93961AD4726B39A5A84FA3BC3B1 |
7| mysql | localhost | invalid |
8+-------------+-----------+-------------------------------------------+
93 rows in set (0.001 sec)
10
11MariaDB [mysql]>
如果想要远程用户可以登录数据库,那么就要创建基于远程用户的登录:
localhost和127.0.0.1是不同的。
localhost代表的是走套接字方式(Localhost via UNIX socket)/var/lib/mysql/mysql.sock文件 (不存在封装&解封装过程)
127.0.0.1走的是本机127.0.0.1:3306端口(涉及TCP协议,封装&解封装流程)
它是2个渠道。
客户端和服务端进行连接,相当于是2个进程,一个是客户端(mysql),一个是服务端(mysqld),这两个进程之间通信,可以走unix套接字,也可以走3306端口。
如果只有mysql.socket套接字,那就只能支持本地连接,无法支持远程数据库连接了。

测试远程登录数据库:
1[root@linux-test-2 ~]#mysql -uroot -pxyy520 -h172.29.9.31
2ERROR 1130 (HY000): Host '172.29.9.32' is not allowed to connect to this MariaDB server
3[root@linux-test-2 ~]#
4
5[root@linux-test ~]#mysql
6……
7MariaDB [mysql]> select user,host,password from user;
8+-------------+-----------+-------------------------------------------+
9| User | Host | Password |
10+-------------+-----------+-------------------------------------------+
11| mariadb.sys | localhost | |
12| root | localhost | *ABE374A5F247C93961AD4726B39A5A84FA3BC3B1 |
13| mysql | localhost | invalid |
14+-------------+-----------+-------------------------------------------+
153 rows in set (0.001 sec)
符合预期。
通过127.0.0.1和unix sokcet登录数据库:
1[root@linux-test ~]#mysql
2……
3MariaDB [mysql]> select user,host,password from user;
4+-------------+-----------+-------------------------------------------+
5| User | Host | Password |
6+-------------+-----------+-------------------------------------------+
7| mariadb.sys | localhost | |
8| root | localhost | *ABE374A5F247C93961AD4726B39A5A84FA3BC3B1 |
9| mysql | localhost | invalid |
10+-------------+-----------+-------------------------------------------+
113 rows in set (0.001 sec)
12
13
14[root@linux-test ~]#mysql -uroot -pxyy520 -h127.0.0.1
15Welcome to the MariaDB monitor. Commands end with ; or \g.
16Your MariaDB connection id is 10
17Server version: 10.4.33-MariaDB MariaDB Server
18
19Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
20
21Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
22
23MariaDB [(none)]> status
24--------------
25mysql Ver 15.1 Distrib 10.4.33-MariaDB, for Linux (x86_64) using readline 5.1
26
27Connection id: 10
28Current database:
29Current user: root@localhost
30SSL: Not in use
31Current pager: stdout
32Using outfile: ''
33Using delimiter: ;
34Server: MariaDB
35Server version: 10.4.33-MariaDB MariaDB Server
36Protocol version: 10
37Connection: 127.0.0.1 via TCP/IP
38Server characterset: latin1
39Db characterset: latin1
40Client characterset: utf8
41Conn. characterset: utf8
42TCP port: 3306
43Uptime: 3 min 49 sec
44
45Threads: 6 Questions: 42 Slow queries: 0 Opens: 37 Flush tables: 1 Open tables: 30 Queries per second avg: 0.183
46--------------
47
48MariaDB [(none)]>
49
50
51
52[root@linux-test ~]#mysql -uroot -pxyy520 -hlocalhost
53Welcome to the MariaDB monitor. Commands end with ; or \g.
54Your MariaDB connection id is 11
55Server version: 10.4.33-MariaDB MariaDB Server
56
57Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
58
59Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
60
61MariaDB [(none)]> \s
62--------------
63mysql Ver 15.1 Distrib 10.4.33-MariaDB, for Linux (x86_64) using readline 5.1
64
65Connection id: 11
66Current database:
67Current user: root@localhost
68SSL: Not in use
69Current pager: stdout
70Using outfile: ''
71Using delimiter: ;
72Server: MariaDB
73Server version: 10.4.33-MariaDB MariaDB Server
74Protocol version: 10
75Connection: Localhost via UNIX socket
76Server characterset: latin1
77Db characterset: latin1
78Client characterset: utf8
79Conn. characterset: utf8
80UNIX socket: /var/lib/mysql/mysql.sock
81Uptime: 4 min 42 sec
82
83Threads: 6 Questions: 46 Slow queries: 0 Opens: 37 Flush tables: 1 Open tables: 30 Queries per second avg: 0.163
84--------------
85
86MariaDB [(none)]>
MySQL 组成
客户端程序
- mysql: 交互式的CLI工具
- mysqldump:备份工具,基于mysql协议向mysqld发起查询请求,并将查得的所有数据转换成insert等写操作语句保存文本文件中
- mysqladmin:基于mysql协议管理mysqld
- mysqlimport:数据导入工具
- MyISAM存储引擎的管理工具:
- myisamchk:检查MyISAM库
- myisampack:打包MyISAM表,只读
服务器端程序
- mysqld_safe
- mysqld
- mysqld_multi 多实例 ,示例:mysqld_multi –example
用户账号
mysql用户账号由两部分组成:
'USERNAME'@'HOST‘
说明:
HOST限制此用户可通过哪些远程主机连接mysql服务器
支持使用通配符:
1 % 匹配任意长度的任意字符
2 172.16.0.0/255.255.0.0 或 172.16.%.%
3 _ 匹配任意单个字符
mysql 客户端命令
mysql 运行命令类型
- 客户端命令:本地执行,每个命令都完整形式和简写格式
1mysql> \h, help
2mysql> \u,use
3mysql> \s,status
4mysql> \!,system
1MariaDB [mysql]> help
2
3General information about MariaDB can be found at
4http://mariadb.org
5
6List of all client commands:
7Note that all text commands must be first on line and end with ';'
8? (\?) Synonym for `help'.
9clear (\c) Clear the current input statement.
10connect (\r) Reconnect to the server. Optional arguments are db and host.
11delimiter (\d) Set statement delimiter.
12edit (\e) Edit command with $EDITOR.
13ego (\G) Send command to MariaDB server, display result vertically.
14exit (\q) Exit mysql. Same as quit. ##常用
15go (\g) Send command to MariaDB server.
16help (\h) Display this help. ##常用
17nopager (\n) Disable pager, print to stdout.
18notee (\t) Don't write into outfile.
19pager (\P) Set PAGER [to_pager]. Print the query results via PAGER.
20print (\p) Print current command.
21prompt (\R) Change your mysql prompt.
22quit (\q) Quit mysql.
23rehash (\#) Rebuild completion hash.
24source (\.) Execute an SQL script file. Takes a file name as an argument.
25status (\s) Get status information from the server. ##常用
26system (\!) Execute a system shell command.
27tee (\T) Set outfile [to_outfile]. Append everything into given outfile.
28use (\u) Use another database. Takes database name as argument.
29charset (\C) Switch to another charset. Might be needed for processing binlog with multi-byte charsets.
30warnings (\W) Show warnings after every statement.
31nowarning (\w) Don't show warnings after every statement.
32
33For server side help, type 'help contents'
34
35MariaDB [mysql]>
举例:(和awk里的system()功能类似)
1system (\!) Execute a system shell command.
2
3MariaDB [(none)]> system ls
4MariaDB [(none)]> system date
5Sat Mar 30 12:17:32 CST 2024
6MariaDB [(none)]> system pwd
7/root
8MariaDB [(none)]>
举例:
1prompt (\R) Change your mysql prompt. #修改提示符
2
3MariaDB [(none)]> (修改这里的提示符的,类似与PS1)
- 服务端命令:通过mysql协议发往服务器执行并取回结果,命令末尾都必须使用命令结束符号,默认为分号
1#示例:
2mysql>SELECT VERSION();
1MariaDB [(none)]> show databases
2 -> ; ##必须要加;号才行,不然不给结束;
3+--------------------+
4| Database |
5+--------------------+
6| information_schema |
7| mysql |
8| performance_schema |
9+--------------------+
103 rows in set (0.001 sec)
11
12MariaDB [(none)]>
mysql 使用模式
交互模式:
脚本模式:
1 mysql –uUSERNAME -pPASSWORD < /path/somefile.sql
2 cat /path/somefile.sql | mysql –uUSERNAME -pPASSWORD
3
4 mysql>source /path/from/somefile.sql
举例:
1[root@linux-test ~]#mysql -uroot -pxyy520 < /tmp/test.sql
2User Host
3mariadb.sys localhost
4mysql localhost
5root localhost
6[root@linux-test ~]#
7
8
9[root@linux-test ~]#cat /tmp/test.sql |mysql -uroot -pxyy520
10User Host
11mariadb.sys localhost
12mysql localhost
13root localhost
14[root@linux-test ~]#
mysql命令使用格式
1mysql [OPTIONS] [database]
mysql客户端常用选项:
1-A, --no-auto-rehash 禁止补全
2-u, --user= 用户名,默认为root
3-h, --host= 服务器主机,默认为localhost
4-p, --passowrd= 用户密码,建议使用-p,默认为空密码
5
6-P, --port= 服务器端口
7-S, --socket= 指定连接socket文件路径
8
9-D, --database= 指定默认数据库
10-C, --compress 启用压缩
11
12-e “SQL“ 执行SQL命令
13
14-V, --version 显示版本
15-v --verbose 显示详细信息
16--print-defaults 获取程序默认使用的配置
登录系统:
1#默认空密码登录
2mysql –uroot –p
运行mysql命令:
1mysql>use mysql
2mysql>select user(); #查看当前用户
3mysql>SELECT User,Host,Password FROM user;
范例:配置客户端mysql的自动登录
1vim/etc/my.cnf.d/client.conf
2[client]
3user=wang
4password=centos
服务器端配置
服务器端(mysqld):工作特性有多种配置方式
1、命令行选项:
2、配置文件:类ini格式,集中式的配置,能够为mysql的各应用程序提供配置信息
服务器端配置文件:
/etc/my.cnf #Global选项(主流)
/etc/mysql/my.cnf #Global选项
~/.my.cnf #User-specific 选项
配置文件格式:
1[mysqld]
2[mysqld_safe]
3[mysqld_multi]
4[mysql]
5[mysqldump]
6[server]
7[client]
格式:parameter = value
说明:_和- 相同 (不区分)
1,ON,TRUE意义相同, 0,OFF,FALSE意义相同
mariadb 10.4.33
[root@linux-test ~]#ls /etc/my.cnf.d/server.cnf /etc/my.cnf.d/server.cnf
mariadb 10.3.17

socket地址
服务器监听的两种socket地址:
- ip socket: 监听在tcp的3306端口,支持远程通信 ,侦听3306/tcp端口可以在绑定有一个或全部接口IP上
- unix sock: 监听在sock文件上,仅支持本机通信, 如:/var/lib/mysql/mysql.sock)
说明:host为localhost 时自动使用unix sock
关闭mysqld网络连接
只侦听本地客户端, 所有客户端和服务器的交互都通过一个socket文件实现,socket的配置存放在/var/lib/mysql/mysql.sock) 可在/etc/my.cnf修改
范例:
1#vim /etc/my.cnf
2或者
3vim /etc/my.cnf.d/server.cnf
4[mysqld]
5skip-networking=1
记得配置后,要重启maridb服务的:
1systemctl restart mariadb
3、SQL语言
关系型数据库的常见组件
- 数据库:database
- 表:table,行:row 列:column
- 索引:index
- 视图:view
- 用户:user
- 权限:privilege
- 存储过程:procedure
- 存储函数:function
- 触发器:trigger
- 事件调度器:event scheduler,任务计划
SQL语言的兴起与语法标准
20世纪70年代,IBM开发出SQL,用于DB2
1981年,IBM推出SQL/DS数据库
业内标准微软和Sybase的T-SQL,Oracle的PL/SQL
SQL作为关系型数据库所使用的标准语言,最初是基于IBM的实现在1986年被批准的。1987年,国际标准化组织(ISO) 把ANSI(美国国家标准化组织) SQL作为国际标准
SQL:ANSI SQL,SQL-1986, SQL-1989, SQL-1992, SQL-1999, SQL-2003,SQL-2008, SQL-2011
SQL语言规范
在数据库系统中,SQL语句不区分大小写,建议用大写;
SQL语句可单行或多行书写,以“;”结尾
关键词不能跨多行或简写
用空格和缩进来提高语句的可读性
子句通常位于独立行,便于编辑,提高可读性
注释:
1SQL标准:
2-- 注释内容 单行注释,注意有空格
3/*注释内容*/ 多行注释
4
5MySQL注释:
6# 注释内容
数据库对象和命名
数据库的组件(对象):
数据库、表、索引、视图、用户、存储过程、函数、触发器、事件调度器等
命名规则:
必须以字母开头,可包括数字和三个特殊字符(# _ $)
不要使用MySQL的保留字
同一database(Schema)下的对象不能同名
在mysql里,Schema和database在数据库下是同义词。但在别的数据库里,不是同义词。
SQL语句分类
- DDL: Data Defination Language 数据定义语言
CREATE,DROP,ALTER(改表的结构)
- DML: Data Manipulation Language 数据操纵语言
INSERT,DELETE,UPDATE
- DQL:Data Query Language 数据查询语言
SELECT
- DCL:Data Control Language 数据控制语言
GRANT(授权),REVOKE(取消),COMMIT,ROLLBACK(撤销)
软件开发:CRUD (R:recieve)
面试会经常问到这块儿。
SQL语句构成
关健字Keyword组成子句clause,多条clause组成语句
示例:
1SELECT * #SELECT子句
2FROM products #FROM子句
3WHERE price>400 #WHERE子句
说明:一组SQL语句,由三个子句构成,SELECT,FROM和WHERE是关键字
数据库操作
管理数据库
创建数据库
1CREATE DATABASE|SCHEMA [IF NOT EXISTS] 'DB_NAME'
2CHARACTER SET 'character set name'
3COLLATE 'collate name';
4
5
6CREATE DATABASE|SCHEMA [IF NOT EXISTS] 'DB_NAME';
7
8
9CREATE DATABASE|SCHEMA 'DB_NAME';
🍊 范例:创建数据库
1mysql> create database db1;
2Query OK, 1 row affected (0.00 sec)
3
4mysql> show create database db1;
5+----------+-----------------------------------------------------------------+
6| Database | Create Database |
7+----------+-----------------------------------------------------------------+
8| db1 | CREATE DATABASE `db1` /*!40100 DEFAULT CHARACTER SET utf8mb4 */ |
9+----------+-----------------------------------------------------------------+
101 row in set (0.00 sec)
11
12mysql>
13[root@linux-test ~]#cat /data/mysql/db1/db.opt
14default-character-set=utf8mb4
15default-collation=utf8mb4_general_ci
16[root@linux-test ~]#
17
18
19
20mysql> create database db1;
21ERROR 1007 (HY000): Can't create database 'db1'; database exists
22mysql> create database IF NOT EXISTS db1;
23Query OK, 1 row affected, 1 warning (0.00 sec)
24
25mysql> show warnings;
26+-------+------+----------------------------------------------+
27| Level | Code | Message |
28+-------+------+----------------------------------------------+
29| Note | 1007 | Can't create database 'db1'; database exists |
30+-------+------+----------------------------------------------+
311 row in set (0.00 sec)
32
33mysql>
🍊 范例:指定字符集创建新数据库
1mysql> create database IF NOT EXISTS db2 CHARACTER SET 'utf8';
2Query OK, 1 row affected (0.01 sec)
3
4mysql> show create database db2;
5+----------+--------------------------------------------------------------+
6| Database | Create Database |
7+----------+--------------------------------------------------------------+
8| db2 | CREATE DATABASE `db2` /*!40100 DEFAULT CHARACTER SET utf8 */ |
9+----------+--------------------------------------------------------------+
101 row in set (0.00 sec)
11
12mysql>
13
14
15default-character-set=utf8
16default-collation=utf8_general_ci
17[root@linux-test ~]#
修改数据库
1ALTER DATABASE DB_NAME character set utf8;
修改字符集后,此刻数据库里会存在2种类型字符集,刚修改的只会对新数据产生影响,老的数据会保持旧字符集不变,可能会出现乱码问题,因此最好在创建数据库时就规划好字符集。
🍊 范例:修改数据库的字符集
1mysql> show create database db1;
2+----------+-----------------------------------------------------------------+
3| Database | Create Database |
4+----------+-----------------------------------------------------------------+
5| db1 | CREATE DATABASE `db1` /*!40100 DEFAULT CHARACTER SET utf8mb4 */ |
6+----------+-----------------------------------------------------------------+
71 row in set (0.00 sec)
8
9mysql> alter database db1 character set utf8;
10Query OK, 1 row affected (0.00 sec)
11
12mysql> show create database db1;
13+----------+--------------------------------------------------------------+
14| Database | Create Database |
15+----------+--------------------------------------------------------------+
16| db1 | CREATE DATABASE `db1` /*!40100 DEFAULT CHARACTER SET utf8 */ |
17+----------+--------------------------------------------------------------+
181 row in set (0.00 sec)
19
20mysql>
21
22[root@linux-test ~]#cat /data/mysql/db1/db.opt
23default-character-set=utf8
24default-collation=utf8_general_ci
25[root@linux-test ~]#
删除数据库
1DROP DATABASE|SCHEMA [IF EXISTS] 'DB_NAME';
🍊 范例:删除数据库
1mysql> show databases;
2+--------------------+
3| Database |
4+--------------------+
5| information_schema |
6| db1 |
7| db2 |
8| mysql |
9| performance_schema |
10+--------------------+
115 rows in set (0.00 sec)
12
13mysql> drop database db1;
14Query OK, 0 rows affected (0.02 sec)
15
16mysql> show databases;
17+--------------------+
18| Database |
19+--------------------+
20| information_schema |
21| db2 |
22| mysql |
23| performance_schema |
24+--------------------+
254 rows in set (0.00 sec)
26
27mysql>
28
29[root@linux-test ~]#ls /data/mysql/db1
30ls: cannot access /data/mysql/db1: No such file or directory
31[root@linux-test ~]#
🍊 范例:如果在数据库目录里创建一个文件,删除数据库后,还能删除这个数据库目录吗
1[root@linux-test ~]#ll /data/mysql/db2
2total 4
3-rw-rw---- 1 mysql mysql 61 Apr 23 07:04 db.opt
4[root@linux-test ~]#touch /data/mysql/db2/xxx.txt
5[root@linux-test ~]#ll /data/mysql/db2
6total 4
7-rw-rw---- 1 mysql mysql 61 Apr 23 07:04 db.opt
8-rw-r--r-- 1 root root 0 Apr 23 07:25 xxx.txt
9[root@linux-test ~]#
10
11
12mysql> drop database db2;
13ERROR 1010 (HY000): Error dropping database (can't rmdir './db2/', errno: 17)
14mysql>
15
16#修改权限
17[root@linux-test ~]#ll /data/mysql/db2
18total 0
19-rw-r--r-- 1 root root 0 Apr 23 07:25 xxx.txt
20[root@linux-test ~]#chown -R mysql.mysql /data/mysql/
21[root@linux-test ~]#ll /data/mysql/db2
22total 0
23-rw-r--r-- 1 mysql mysql 0 Apr 23 07:25 xxx.txt
24[root@linux-test ~]#
25
26
27#再次删除还是报错……
28mysql> drop database db2;
29ERROR 1010 (HY000): Error dropping database (can't rmdir './db2/', errno: 17)
30mysql> show databases;
31+--------------------+
32| Database |
33+--------------------+
34| information_schema |
35| db2 |
36| mysql |
37| performance_schema |
38+--------------------+
394 rows in set (0.00 sec)
40
41mysql>
🍊 范例:删除mysql数据库(自杀)
1mysql> show databases;
2+--------------------+
3| Database |
4+--------------------+
5| information_schema |
6| db2 |
7| mysql |
8| performance_schema |
9+--------------------+
104 rows in set (0.00 sec)
11
12mysql> drop database mysql;
13Query OK, 28 rows affected, 2 warnings (0.03 sec)
14
15mysql> show databases;
16+--------------------+
17| Database |
18+--------------------+
19| information_schema |
20| db2 |
21| performance_schema |
22+--------------------+
233 rows in set (0.00 sec)
24
25mysql>
26
27
28##删除mysql数据库后,停止mysql服务再次启动后,会报错的,完了,mysql废了哈哈😂
29[root@linux-test ~]#systemctl status mysql
30● mysqld.service - LSB: start and stop MySQL
31 Loaded: loaded (/etc/rc.d/init.d/mysqld; bad; vendor preset: disabled)
32 Active: active (running) since Tue 2024-04-23 06:40:40 CST; 47min ago
33 Docs: man:systemd-sysv-generator(8)
34 Process: 6518 ExecStart=/etc/rc.d/init.d/mysqld start (code=exited, status=0/SUCCESS)
35 CGroup: /system.slice/mysqld.service
36 ├─6536 /bin/sh /usr/local/mysql/bin/mysqld_safe --datadir=/data/mysql --pid-file=/data/mysql/linux...
37 └─6788 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/data/mysql --plugin-dir=/...
38
39Apr 23 06:40:40 linux-test systemd[1]: Starting LSB: start and stop MySQL...
40Apr 23 06:40:40 linux-test mysqld[6518]: Starting MySQL SUCCESS!
41Apr 23 06:40:40 linux-test systemd[1]: Started LSB: start and stop MySQL.
42[root@linux-test ~]#systemctl stop mysql
43[root@linux-test ~]#systemctl start mysql
44Job for mysqld.service failed because the control process exited with error code. See "systemctl status mysqld.service" and "journalctl -xe" for details.
45[root@linux-test ~]#
46[root@linux-test ~]#netstat -ntlp
47Active Internet connections (only servers)
48Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
49tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 6514/sshd
50tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 6877/master
51tcp6 0 0 :::22 :::* LISTEN 6514/sshd
52tcp6 0 0 ::1:25 :::* LISTEN 6877/master
53[root@linux-test ~]#
查看数据库列表
1SHOW DATABASES;
🍊 范例:查看数据库列表
1mysql> show databases;
2+--------------------+
3| Database |
4+--------------------+
5| information_schema |
6| db1 |
7| db2 |
8| mysql |
9| performance_schema |
10+--------------------+
115 rows in set (0.00 sec)
12
13mysql>
数据类型
数据类型:
数据长什么样
数据需要多少空间来存放
数据类型
系统内置数据类型
用户定义数据类型
MySQL支持多种内置数据类型
数值类型
日期/时间类型
字符串(字符)类型
数据类型参考链接
https://dev.mysql.com/doc/refman/8.0/en/data-types.html

1tinyint:2^8-1=255 -127到+128 符号位
2unsigned 无符号位;
3截断;
选择正确的数据类型对于获得高性能至关重要,三大原则:
- 更小的通常更好,尽量使用可正确存储数据的最小数据类型
- 简单就好,简单数据类型的操作通常需要更少的CPU周期
- 尽量避免NULL,包含为NULL的列,对MySQL更难优化
整数型
tinyint(m) 1个字节 范围(-128~127)
smallint(m) 2个字节 范围(-32768~32767)
mediumint(m) 3个字节 范围(-8388608~8388607)
int(m) 4个字节 范围(-2147483648~2147483647)
bigint(m) 8个字节 范围(+-9.22*10的18次方)
上述数据类型,如果加修饰符unsigned后,则最大值翻倍
如:tinyint unsigned的取值范围为(0~255)
int(m)里的m是表示SELECT查询结果集中的显示宽度,并不影响实际的取值范围,规定了MySQL的一些交互工具(例如MySQL命令行客户端)用来显示字符的个数。对于存储和计算来说,Int(1)和Int(20)是相同的
BOOL,BOOLEAN:布尔型,是TINYINT(1)的同义词。zero值被视为假,非zero值视为真。
浮点型(float和double),近似值
float(m,d) 单精度浮点型 8位精度(4字节) m总个数,d小数位
double(m,d) 双精度浮点型16位精度(8字节) m总个数,d小数位
设一个字段定义为float(6,3),如果插入一个数123.45678,实际数据库里存的是123.457,但总个数还以实际为准,即6位
定点数
在数据库中存放的是精确值,存为十进制
decimal(m,d) 参数m<65 是总个数,d<30且 d<m 是小数位
MySQL5.0和更高版本将数字打包保存到一个二进制字符串中(每4个字节存9个数字)。
例如:
decimal(18,9)小数点两边将各存储9个数字,一共使用9个字节:其中,小数点前的9个数字用4个字节,小数点后的9个数字用4个字节,小数点本身占1个字节
浮点类型在存储同样范围的值时,通常比decimal使用更少的空间。float使用4个字节存储。double占用8个字节
因为需要额外的空间和计算开销,所以应该尽量只在对小数进行精确计算时才使用decimal,例如存储财务数据。但在数据量比较大的时候,可以考虑使用bigint代替decimal。
字符串(char,varchar,text)
char(n) 固定长度,最多255个字符
varchar(n) 可变长度,最多65535个字符
tinytext 可变长度,最多255个字符
text 可变长度,最多65535个字符
mediumtext 可变长度,最多2的24次方-1个字符
longtext 可变长度,最多2的32次方-1个字符
BINARY(M) 固定长度,可存二进制或字符,长度为0-M字节
VARBINARY(M) 可变长度,可存二进制或字符,允许长度为0-M字节
内建类型:ENUM枚举, SET集合
char和varchar:
参考:https://dev.mysql.com/doc/refman/8.0/en/char.html

1.char(n) 若存入字符数小于n,则以空格补于其后,查询之时再将空格去掉,所以char类型存储的字符串末尾不能有空格,varchar不限于此
2.char(n) 固定长度,char(4)不管是存入几个字符,都将占用4个字节,varchar是存入的实际字符数+1个字节(n< n>255),所以varchar(4),存入3个字符将占用4个字节
3.char类型的字符串检索速度要比varchar类型的快
varchar和text: 1.varchar可指定n,text不能指定,内部存储varchar是存入的实际字符数+1个字节(n< n>255),text是实际字符数+2个字节。 2.text类型不能有默认值 3.varchar可直接创建索引,text创建索引要指定前多少个字符。varchar查询速度快于text数据类型。
二进制数据BLOB
BLOB和text存储方式不同,TEXT以文本方式存储,英文存储区分大小写,而Blob以二进制方式存储,不分大小写
BLOB存储的数据只能整体读出
TEXT可以指定字符集,BLOB不用指定字符集
日期时间类型
date 日期 ‘2008-12-2’
time 时间 ‘12:25:36’
datetime 日期时间 ‘2008-12-2 22:06:44’
timestamp 自动存储记录修改时间
YEAR(2), YEAR(4):年份
timestamp字段里的时间数据会随其他字段修改的时候自动刷新,这个数据类型的字段可以存放这条记录最后被修改的时间
修饰符
适用所有类型的修饰符:
NULL 数据列可包含NULL值,默认值
NOT NULL 数据列不允许包含NULL值,为必填选项
DEFAULT 默认值
PRIMARY KEY 主键,所有记录中此字段的值不能重复,且不能为NULL
UNIQUE KEY 唯一键,所有记录中此字段的值不能重复,但可以为NULL
CHARACTER SET name 指定一个字符集
适用数值型的修饰符:
AUTO_INCREMENT 自动递增,适用于整数类型
UNSIGNED 无符号
DDL语句
表:二维关系
设计表:遵循规范
定义:字段,索引
- 字段:字段名,字段数据类型,修饰符
- 约束,索引:应该创建在经常用作查询条件的字段上
创建表
创建表:
1CREATE TABLE
获取帮助:
1HELP CREATE TABLE
1CREATE TABLE [IF NOT EXISTS] ‘tbl_name’ (col1 type1 修饰符, col2 type2 修饰符,
2...)
3#字段信息
4col type1
5PRIMARY KEY(col1,...)
6INDEX(col1, ...)
7UNIQUE KEY(col1, ...)
8#表选项:
9ENGINE [=] engine_name
10ROW_FORMAT [=] {DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT}
注意:
- Storage Engine是指表类型,也即在表创建时指明其使用的存储引擎
- 同一库中不同表可以使用不同的存储引擎
- 同一个库中表建议要使用同一种存储引擎类型
方式1:直接创建(常用)
范例:表的创建和修改
1CREATE TABLE student (
2id int UNSIGNED AUTO_INCREMENT PRIMARY KEY,
3name VARCHAR(20) NOT NULL,
4age tinyint UNSIGNED,
5gender ENUM('M','F') default 'M'
6)ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
范例:
1student | CREATE TABLE `student` (
2 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
3 `name` varchar(20) CHARACTER SET utf8 NOT NULL,
4 `age` tinyint(3) unsigned DEFAULT NULL,
5 `gender` enum('M','F') CHARACTER SET utf8 DEFAULT 'M',
6 PRIMARY KEY (`id`)
7) ;
测试过程:
1##创建表
2mysql> CREATE TABLE student (
3 -> id int UNSIGNED AUTO_INCREMENT PRIMARY KEY,
4 -> name VARCHAR(20) NOT NULL,
5 -> age tinyint UNSIGNED,
6 -> gender ENUM('M','F') default 'M'
7 -> )ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
8Query OK, 0 rows affected (0.00 sec)
9#id字段以10初始值
10
11##查看表结构
12mysql> desc student;
13+--------+---------------------+------+-----+---------+----------------+
14| Field | Type | Null | Key | Default | Extra |
15+--------+---------------------+------+-----+---------+----------------+
16| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
17| name | varchar(20) | NO | | NULL | |
18| age | tinyint(3) unsigned | YES | | NULL | |
19| gender | enum('M','F') | YES | | M | |
20+--------+---------------------+------+-----+---------+----------------+
214 rows in set (0.01 sec)
22
23mysql>
24#说明:enum 是枚举类型。 括号里的数字不是字节大小,而是代表的对其宽度;
25
26##查看表内容
27mysql> select * from student;
28Empty set (0.00 sec)
29
30
31##修改表
32mysql> insert student (name,age)values('xiaoming',20);
33Query OK, 1 row affected (0.00 sec)
34
35mysql> select * from student;
36+----+----------+------+--------+
37| id | name | age | gender |
38+----+----------+------+--------+
39| 10 | xiaoming | 20 | M |
40+----+----------+------+--------+
411 row in set (0.00 sec)
42mysql> insert student (name,age,gender)values('xiaohong',18,'f'); ##注意:枚举类型,这里小写字母f或者大写字母F都是可以的;
43Query OK, 1 row affected (0.00 sec)
44
45mysql> select * from student;
46+----+----------+------+--------+
47| id | name | age | gender |
48+----+----------+------+--------+
49| 10 | xiaoming | 20 | M |
50| 11 | xiaohong | 18 | F |
51+----+----------+------+--------+
522 rows in set (0.00 sec)
53
54mysql>
🍊 范例:创建复合主键
1CREATE TABLE employee (id int UNSIGNED NOT NULL ,name VARCHAR(20) NOT NULL,age tinyint UNSIGNED,PRIMARY KEY(id,name));
🍊 范例:auto_increment 属性
demo1:
1# auto_increment_offset 定义初始值
2# auto_increment_increment 定义步进
3
4
5mysql> SHOW VARIABLES LIKE 'auto_inc%';
6+--------------------------+-------+
7| Variable_name | Value |
8+--------------------------+-------+
9| auto_increment_increment | 1 |
10| auto_increment_offset | 1 |
11+--------------------------+-------+
122 rows in set (0.00 sec)
13
14##设置auto_increment 属性
15mysql> SET @@auto_increment_increment=10;
16Query OK, 0 rows affected (0.00 sec)
17
18mysql> SET @@auto_increment_offset=3;
19Query OK, 0 rows affected (0.00 sec)
20
21
22mysql> SHOW VARIABLES LIKE 'auto_inc%';
23+--------------------------+-------+
24| Variable_name | Value |
25+--------------------------+-------+
26| auto_increment_increment | 10 |
27| auto_increment_offset | 3 |
28+--------------------------+-------+
292 rows in set (0.00 sec)
30
31
32##创建表和修改表
33mysql> CREATE TABLE autoinc1 (col INT NOT NULL AUTO_INCREMENT PRIMARY KEY);
34Query OK, 0 rows affected (0.01 sec)
35
36mysql> INSERT INTO autoinc1 VALUES (NULL), (NULL), (NULL), (NULL); ##代表插入4条数据
37Query OK, 4 rows affected (0.01 sec)
38Records: 4 Duplicates: 0 Warnings: 0
39
40
41
42mysql> SELECT * FROM autoinc1;
43+-----+
44| col |
45+-----+
46| 3 |
47| 13 |
48| 23 |
49| 33 |
50+-----+
514 rows in set (0.00 sec)
52
53mysql>
demo2:
1🍊 范例:表的创建及auto_increment测试
2
3```sql
4mysql> create database test;
5Query OK, 1 row affected (0.00 sec)
6mysql> use test
7Database changed
8
9mysql> create table t1(id int unsigned auto_increment primary key);
10Query OK, 0 rows affected (0.02 sec)
11
12mysql> desc t1;
13+-------+------------------+------+-----+---------+----------------+
14| Field | Type | Null | Key | Default | Extra |
15+-------+------------------+------+-----+---------+----------------+
16| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
17+-------+------------------+------+-----+---------+----------------+
181 row in set (0.00 sec)
19
20
21mysql> insert into t1 values(null);
22Query OK, 1 row affected (0.00 sec)
23
24mysql> select * from t1;
25+----+
26| id |
27+----+
28| 1 |
29+----+
301 row in set (0.00 sec)
31
32
33
34#又插入一条
35mysql> insert into t1 values(null);
36Query OK, 1 row affected (0.01 sec)
37
38mysql> select * from t1;
39+----+
40| id |
41+----+
42| 1 |
43| 2 |
44+----+
452 rows in set (0.00 sec)
46
47
48
49##测试auto_increment
50mysql> create table t2(id int unsigned auto_increment primary key) auto_increment = 4294967294;
51Query OK, 0 rows affected (0.00 sec)
52
53mysql> desc t2;
54+-------+------------------+------+-----+---------+----------------+
55| Field | Type | Null | Key | Default | Extra |
56+-------+------------------+------+-----+---------+----------------+
57| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
58+-------+------------------+------+-----+---------+----------------+
591 row in set (0.00 sec)
60
61mysql> insert into t2 values(null);
62Query OK, 1 row affected (0.00 sec)
63
64mysql> select * from t2;
65+------------+
66| id |
67+------------+
68| 4294967294 |
69+------------+
701 row in set (0.00 sec)
71
72mysql> insert into t2 values(null);
73Query OK, 1 row affected (0.00 sec)
74
75mysql> select * from t2;
76+------------+
77| id |
78+------------+
79| 4294967294 |
80| 4294967295 |
81+------------+
822 rows in set (0.00 sec)
83
84mysql> insert into t2 values(null);
85ERROR 1062 (23000): Duplicate entry '4294967295' for key 'PRIMARY'
86mysql>
87
88##说明
89int(10) unsigned 4个字节
900~4294967295
91
92[root@linux-test ~]#echo 2^32|bc
934294967296
94[root@linux-test ~]#
95```
🍊 范例:timestamp修饰符
1mysql> create table testdate (id int auto_increment primary key,date timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL);
测试过程:
1##创建表
2mysql> create table testdate (id int auto_increment primary key,date timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL);
3Query OK, 0 rows affected (0.02 sec)
4
5
6##插入数据
7mysql> insert testdate (id)values(1);
8Query OK, 1 row affected (0.01 sec)
9
10mysql> insert testdate (id)values(2);
11Query OK, 1 row affected (0.00 sec)
12
13mysql> insert testdate (id)values(3);
14Query OK, 1 row affected (0.01 sec)
15
16mysql> insert testdate (id)values(4);
17Query OK, 1 row affected (0.00 sec)
18
19
20##查询表
21mysql> select * from testdate;
22+----+---------------------+
23| id | date |
24+----+---------------------+
25| 1 | 2024-04-27 13:35:20 |
26| 2 | 2024-04-27 13:35:22 |
27| 3 | 2024-04-27 13:35:24 |
28| 4 | 2024-04-27 13:35:27 |
29+----+---------------------+
304 rows in set (0.00 sec)
31
32mysql>
方式2: 通过查询现存表创建;新表会被直接插入查询而来的数据
1CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(create_definition,...)]
2[table_options]
3[partition_options] select_statement
范例:
1##当前表:
2mysql> desc testdate;
3+-------+-----------+------+-----+-------------------+----------------+
4| Field | Type | Null | Key | Default | Extra |
5+-------+-----------+------+-----+-------------------+----------------+
6| id | int(11) | NO | PRI | NULL | auto_increment |
7| date | timestamp | NO | | CURRENT_TIMESTAMP | |
8+-------+-----------+------+-----+-------------------+----------------+
92 rows in set (0.00 sec)
10
11mysql> select * from testdate;
12+----+---------------------+
13| id | date |
14+----+---------------------+
15| 1 | 2024-04-27 13:35:20 |
16| 2 | 2024-04-27 13:35:22 |
17| 3 | 2024-04-27 13:35:24 |
18| 4 | 2024-04-27 13:35:27 |
19+----+---------------------+
204 rows in set (0.00 sec)
21
22
23##新创建表
24mysql> create table testdate2 select * from testdate;
25Query OK, 4 rows affected (0.02 sec)
26Records: 4 Duplicates: 0 Warnings: 0
27
28mysql> desc testdate2;
29+-------+-----------+------+-----+-------------------+-------+
30| Field | Type | Null | Key | Default | Extra |
31+-------+-----------+------+-----+-------------------+-------+
32| id | int(11) | NO | | 0 | |
33| date | timestamp | NO | | CURRENT_TIMESTAMP | |
34+-------+-----------+------+-----+-------------------+-------+
352 rows in set (0.00 sec)
36
37mysql> select * from testdate2;
38+----+---------------------+
39| id | date |
40+----+---------------------+
41| 1 | 2024-04-27 13:35:20 |
42| 2 | 2024-04-27 13:35:22 |
43| 3 | 2024-04-27 13:35:24 |
44| 4 | 2024-04-27 13:35:27 |
45+----+---------------------+
464 rows in set (0.00 sec)
47
48#注意:新创建的表里的数据和原表一致,只是表结构里可能会缺少一些属性值;
49mysql> desc testdate;
50+-------+-----------+------+-----+-------------------+----------------+
51| Field | Type | Null | Key | Default | Extra |
52+-------+-----------+------+-----+-------------------+----------------+
53| id | int(11) | NO | PRI | NULL | auto_increment |
54| date | timestamp | NO | | CURRENT_TIMESTAMP | |
55+-------+-----------+------+-----+-------------------+----------------+
562 rows in set (0.00 sec)
57mysql> desc testdate2;
58+-------+-----------+------+-----+-------------------+-------+
59| Field | Type | Null | Key | Default | Extra |
60+-------+-----------+------+-----+-------------------+-------+
61| id | int(11) | NO | | 0 | |
62| date | timestamp | NO | | CURRENT_TIMESTAMP | |
63+-------+-----------+------+-----+-------------------+-------+
642 rows in set (0.00 sec)
方式3:通过复制现存的表的表结构创建,但不复制数据
1CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name { LIKE old_tbl_name | (LIKEold_tbl_name) }
范例:
1##老表
2mysql> desc testdate;
3+-------+-----------+------+-----+-------------------+----------------+
4| Field | Type | Null | Key | Default | Extra |
5+-------+-----------+------+-----+-------------------+----------------+
6| id | int(11) | NO | PRI | NULL | auto_increment |
7| date | timestamp | NO | | CURRENT_TIMESTAMP | |
8+-------+-----------+------+-----+-------------------+----------------+
92 rows in set (0.00 sec)
10
11mysql> select * from testdate;
12+----+---------------------+
13| id | date |
14+----+---------------------+
15| 1 | 2024-04-27 13:35:20 |
16| 2 | 2024-04-27 13:35:22 |
17| 3 | 2024-04-27 13:35:24 |
18| 4 | 2024-04-27 13:35:27 |
19+----+---------------------+
204 rows in set (0.00 sec)
21
22
23
24##新表
25mysql> create table testdate3 like testdate;
26Query OK, 0 rows affected (0.00 sec)
27mysql> desc testdate3;
28+-------+-----------+------+-----+-------------------+----------------+
29| Field | Type | Null | Key | Default | Extra |
30+-------+-----------+------+-----+-------------------+----------------+
31| id | int(11) | NO | PRI | NULL | auto_increment |
32| date | timestamp | NO | | CURRENT_TIMESTAMP | |
33+-------+-----------+------+-----+-------------------+----------------+
342 rows in set (0.00 sec)
35
36mysql> select * from testdate3;
37Empty set (0.00 sec)
38
39#说明:通过这种方式创建的表,数据为空,但表结构和老表完全一致。
表查看
- 查看支持的engine类型
1SHOW ENGINES;
- 查看表:
1SHOW TABLES [FROM db_name]
2
3范例:
4mysql> SHOW TABLES;
5+----------------+
6| Tables_in_test |
7+----------------+
8| autiinc1 |
9| autoinc1 |
10| student |
11| t1 |
12| t2 |
13| testdate |
14| testdate2 |
15| testdate3 |
16+----------------+
178 rows in set (0.00 sec)
- 查看表结构:
1DESC [db_name.]tb_name
2SHOW COLUMNS FROM [db_name.]tb_name
范例:
1mysql> desc testdate;
2+-------+-----------+------+-----+-------------------+----------------+
3| Field | Type | Null | Key | Default | Extra |
4+-------+-----------+------+-----+-------------------+----------------+
5| id | int(11) | NO | PRI | NULL | auto_increment |
6| date | timestamp | NO | | CURRENT_TIMESTAMP | |
7+-------+-----------+------+-----+-------------------+----------------+
82 rows in set (0.00 sec)
9
10mysql> show columns from testdate;
11+-------+-----------+------+-----+-------------------+----------------+
12| Field | Type | Null | Key | Default | Extra |
13+-------+-----------+------+-----+-------------------+----------------+
14| id | int(11) | NO | PRI | NULL | auto_increment |
15| date | timestamp | NO | | CURRENT_TIMESTAMP | |
16+-------+-----------+------+-----+-------------------+----------------+
172 rows in set (0.00 sec)
- 查看表创建命令:
1SHOW CREATE TABLE tbl_name
范例:
1mysql> show create table student;
2+---------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
3| Table | Create Table |
4+---------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
5| student | CREATE TABLE `student` (
6 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
7 `name` varchar(20) NOT NULL,
8 `age` tinyint(3) unsigned DEFAULT NULL,
9 `gender` enum('M','F') DEFAULT 'M',
10 PRIMARY KEY (`id`)
11) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8 |
12+---------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
131 row in set (0.00 sec)
14
15mysql> select * from stu
16+----+----------+------+
17| id | name | age |
18+----+----------+------+
19| 10 | xiaoming | 20 |
20| 11 | xiaohong | 18 |
21+----+----------+------+
222 rows in set (0.00 sec)
- 查看表状态:
1SHOW TABLE STATUS LIKE 'student'\G
范例:
1mysql> SHOW TABLE STATUS LIKE 'student'\G
2*************************** 1. row ***************************
3 Name: student
4 Engine: InnoDB
5 Version: 10
6 Row_format: Compact
7 Rows: 2
8 Avg_row_length: 8192
9 Data_length: 16384
10Max_data_length: 0
11 Index_length: 0
12 Data_free: 0
13 Auto_increment: 12
14 Create_time: 2024-04-27 09:10:06
15 Update_time: NULL
16 Check_time: NULL
17 Collation: utf8_general_ci
18 Checksum: NULL
19 Create_options:
20 Comment:
211 row in set (0.00 sec)
22
23mysql>
- 查看库中所有表状态
1SHOW TABLE STATUS FROM db_name;
范例:
1mysql> show table status from test\G;
2*************************** 1. row ***************************
3 Name: autiinc1
4 Engine: InnoDB
5 Version: 10
6 Row_format: Compact
7 Rows: 0
8 Avg_row_length: 0
9 Data_length: 16384
10Max_data_length: 0
11 Index_length: 0
12 Data_free: 0
13 Auto_increment: 1
14 Create_time: 2024-04-27 09:29:38
15 Update_time: NULL
16 Check_time: NULL
17 Collation: latin1_swedish_ci
18 Checksum: NULL
19 Create_options:
20 Comment:
21*************************** 2. row ***************************
22 Name: autoinc1
23 Engine: InnoDB
24 Version: 10
25 Row_format: Compact
26 Rows: 4
27 Avg_row_length: 4096
28 Data_length: 16384
29Max_data_length: 0
30 Index_length: 0
31 Data_free: 0
32 Auto_increment: 43
33 Create_time: 2024-04-27 09:32:21
34 Update_time: NULL
35 Check_time: NULL
36 Collation: latin1_swedish_ci
37 Checksum: NULL
38 Create_options:
39 Comment:
40*************************** 3. row ***************************
41 Name: student
42 Engine: InnoDB
43 Version: 10
44 Row_format: Compact
45 Rows: 2
46 Avg_row_length: 8192
47 Data_length: 16384
48Max_data_length: 0
49 Index_length: 0
50 Data_free: 0
51 Auto_increment: 12
52 Create_time: 2024-04-27 09:10:06
53 Update_time: NULL
54 Check_time: NULL
55 Collation: utf8_general_ci
56 Checksum: NULL
57 Create_options:
58 Comment:
59 ……
修改和删除表
- 删除表
1DROP TABLE [IF EXISTS] 'tbl_name';
范例:
1mysql> drop table autoinc1; ##就是删除了mysql目录对应表的2个文件
2Query OK, 0 rows affected (0.00 sec)
3
4mysql>
- 修改表
1ALTER TABLE 'tbl_name'
2#字段:
3#添加字段:add
4ADD col1 data_type [FIRST|AFTER col_name]
5#删除字段:drop
6#修改字段:
7alter(默认值), change(字段名), modify(字段属性)
范例:添加字段:add
1mysql> alter table student add mobile char(11) not null default '13801380000' after name;
2Query OK, 0 rows affected (0.01 sec)
3Records: 0 Duplicates: 0 Warnings: 0
4
5mysql> select *from student;
6+----+----------+-------------+------+--------+
7| id | name | mobile | age | gender |
8+----+----------+-------------+------+--------+
9| 10 | xiaoming | 13801380000 | 20 | M |
10| 11 | xiaohong | 13801380000 | 18 | F |
11+----+----------+-------------+------+--------+
122 rows in set (0.00 sec)
13
14mysql>
范例:修改字段属性
1mysql> alter table student modify mobile char(12);
2Query OK, 2 rows affected (0.02 sec)
3Records: 2 Duplicates: 0 Warnings: 0
4
5mysql> desc student;
6+--------+---------------------+------+-----+---------+----------------+
7| Field | Type | Null | Key | Default | Extra |
8+--------+---------------------+------+-----+---------+----------------+
9| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
10| name | varchar(20) | NO | | NULL | |
11| mobile | char(12) | YES | | NULL | |
12| age | tinyint(3) unsigned | YES | | NULL | |
13| gender | enum('M','F') | YES | | M | |
14+--------+---------------------+------+-----+---------+----------------+
155 rows in set (0.00 sec)
16
17mysql>
范例:删除表的某一列
1mysql> select *from student;
2+----+----------+-------------+------+--------+
3| id | name | mobile | age | gender |
4+----+----------+-------------+------+--------+
5| 10 | xiaoming | 13801380000 | 20 | M |
6| 11 | xiaohong | 13801380000 | 18 | F |
7+----+----------+-------------+------+--------+
82 rows in set (0.00 sec)
9
10mysql> alter table student drop column mobile;
11Query OK, 0 rows affected (0.03 sec)
12Records: 0 Duplicates: 0 Warnings: 0
13
14mysql> select *from student;
15+----+----------+------+--------+
16| id | name | age | gender |
17+----+----------+------+--------+
18| 10 | xiaoming | 20 | M |
19| 11 | xiaohong | 18 | F |
20+----+----------+------+--------+
212 rows in set (0.00 sec)
- 查看修改表帮助
1Help ALTER TABLE
- 修改表范例
1ALTER TABLE students RENAME s1;
2ALTER TABLE s1 ADD phone varchar(11) AFTER name;
3ALTER TABLE s1 MODIFY phone int;
4ALTER TABLE s1 CHANGE COLUMN phone mobile char(11);
5ALTER TABLE s1 DROP COLUMN mobile;
6ALTER TABLE s1 character set utf8;
7ALTER TABLE s1 change name name varchar(20) character set utf8;
8ALTER TABLE students ADD gender ENUM('m','f');
9ALETR TABLE students CHANGE id sid int UNSIGNED NOT NULL PRIMARY KEY;
10ALTER TABLE students DROP age;
11DESC students;
12
13#新建表无主键,添加和删除主键
14CREATE TABLE t1 SELECT * FROM students;
15ALTER TABLE t1 add primary key (stuid);
16ALTER TABLE t1 drop primary key ;
🍊 范例:
1ALTER TABLE s1 character set utf8;
DML语句
DML: INSERT, DELETE, UPDATE
INSERT 语句
功能:一次插入一行或多行数据 语法
1INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
2 [INTO] tbl_name [(col_name,...)]
3 {VALUES | VALUE} ({expr | DEFAULT},...),(...),...
4 [ ON DUPLICATE KEY UPDATE #如果重复更新之
5 col_name=expr
6 [, col_name=expr] ... ]
7
8INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
9 [INTO] tbl_name
10 SET col_name={expr | DEFAULT}, ...
11 [ ON DUPLICATE KEY UPDATE
12 col_name=expr
13 [, col_name=expr] ... ]
14INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
15 [INTO] tbl_name [(col_name,...)]
16 SELECT ...
17 [ ON DUPLICATE KEY UPDATE
18 col_name=expr
19 [, col_name=expr] ... ]
简化写法:
1INSERT tbl_name [(col1,...)] VALUES (val1,...), (val21,...)
方法1:
🍊 范例:省略col_name,给所有value赋值
1mysql> select *from student;
2+----+----------+------+--------+
3| id | name | age | gender |
4+----+----------+------+--------+
5| 10 | xiaoming | 20 | M |
6| 11 | xiaohong | 18 | F |
7+----+----------+------+--------+
82 rows in set (0.00 sec)
9
10mysql> insert student value (1,'xyy',18,'F');
11Query OK, 1 row affected (0.02 sec)
12
13mysql> select *from student;
14+----+----------+------+--------+
15| id | name | age | gender |
16+----+----------+------+--------+
17| 1 | xyy | 18 | F |
18| 10 | xiaoming | 20 | M |
19| 11 | xiaohong | 18 | F |
20+----+----------+------+--------+
213 rows in set (0.00 sec)
🍊 范例:给部分列属性赋值
1mysql> select *from student;
2+----+----------+------+--------+
3| id | name | age | gender |
4+----+----------+------+--------+
5| 1 | xyy | 18 | F |
6| 10 | xiaoming | 20 | M |
7| 11 | xiaohong | 18 | F |
8+----+----------+------+--------+
93 rows in set (0.00 sec)
10
11mysql> insert student (name,age,gender) value ('hg',19,'M');
12Query OK, 1 row affected (0.02 sec)
13
14mysql> select *from student;
15+----+----------+------+--------+
16| id | name | age | gender |
17+----+----------+------+--------+
18| 1 | xyy | 18 | F |
19| 10 | xiaoming | 20 | M |
20| 11 | xiaohong | 18 | F |
21| 12 | hg | 19 | M |
22+----+----------+------+--------+
234 rows in set (0.00 sec)
🍊 范例:给部分列属性赋值,并一次性添加多条记录。
1mysql> select *from student;
2+----+----------+------+--------+
3| id | name | age | gender |
4+----+----------+------+--------+
5| 1 | xyy | 18 | F |
6| 10 | xiaoming | 20 | M |
7| 11 | xiaohong | 18 | F |
8| 12 | hg | 19 | M |
9+----+----------+------+--------+
104 rows in set (0.00 sec)
11
12mysql> insert student (name,age,gender) value ('lianlian',18,'F'),('xiaoxiao',18,'F'),('yanyan',19,'F');
13Query OK, 3 rows affected (0.00 sec)
14Records: 3 Duplicates: 0 Warnings: 0
15
16mysql> select *from student;
17+----+----------+------+--------+
18| id | name | age | gender |
19+----+----------+------+--------+
20| 1 | xyy | 18 | F |
21| 10 | xiaoming | 20 | M |
22| 11 | xiaohong | 18 | F |
23| 12 | hg | 19 | M |
24| 13 | lianlian | 18 | F |
25| 14 | xiaoxiao | 18 | F |
26| 15 | yanyan | 19 | F |
27+----+----------+------+--------+
287 rows in set (0.00 sec)
方法2:
🍊 范例:利用旧表的数据批量地导入
1mysql> create table student2 like student;
2Query OK, 0 rows affected (0.02 sec)
3
4mysql> select *from student2;
5Empty set (0.00 sec)
6
7mysql> insert student2 select *from student;
8Query OK, 7 rows affected (0.01 sec)
9Records: 7 Duplicates: 0 Warnings: 0
10
11mysql> select *from student2;
12+----+----------+------+--------+
13| id | name | age | gender |
14+----+----------+------+--------+
15| 1 | xyy | 18 | F |
16| 10 | xiaoming | 20 | M |
17| 11 | xiaohong | 18 | F |
18| 12 | hg | 19 | M |
19| 13 | lianlian | 18 | F |
20| 14 | xiaoxiao | 18 | F |
21| 15 | yanyan | 19 | F |
22+----+----------+------+--------+
237 rows in set (0.00 sec)
方法3:set方式
1mysql> insert student set name='hao',age=22,gender='M';
范例:
1mysql> insert student set name='hao',age=22,gender='M';
2Query OK, 1 row affected (0.01 sec)
3
4mysql> select *from student;
5+----+----------+------+--------+
6| id | name | age | gender |
7+----+----------+------+--------+
8| 1 | xyy | 18 | F |
9| 10 | xiaoming | 20 | M |
10| 11 | xiaohong | 18 | F |
11| 12 | hg | 19 | M |
12| 13 | lianlian | 18 | F |
13| 14 | xiaoxiao | 18 | F |
14| 15 | yanyan | 19 | F |
15| 16 | hao | 22 | M |
16+----+----------+------+--------+
178 rows in set (0.00 sec)
UPDATE 语句
语法:
1UPDATE [LOW_PRIORITY] [IGNORE] table_reference
2 SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...
3 [WHERE where_condition]
4 [ORDER BY ...]
5 [LIMIT row_count]
注意:一定要有限制条件,否则将修改所有行的指定字段
可利用mysql 选项避免此错误:
1mysql -U | --safe-updates| --i-am-a-dummy
2[root@centos8 ~]#vim /etc/my.cnf
3[mysql]
4safe-updates
🍊 范例:更新某个单元格的数据
1mysql> select *from student;
2+----+----------+------+--------+
3| id | name | age | gender |
4+----+----------+------+--------+
5| 1 | xyy | 18 | F |
6| 10 | xiaoming | 20 | M |
7| 11 | xiaohong | 18 | F |
8| 12 | hg | 19 | M |
9| 13 | lianlian | 18 | F |
10| 14 | xiaoxiao | 18 | F |
11| 15 | yanyan | 19 | F |
12| 16 | hao | 22 | M |
13+----+----------+------+--------+
148 rows in set (0.00 sec)
15
16#mysql> update student set age=18; ##这个是灾难性的后果,会修改该列的所有值的;
17mysql> update student set age=18 where id=15;
18Query OK, 1 row affected (0.00 sec)
19Rows matched: 1 Changed: 1 Warnings: 0
20
21mysql> select *from student;
22+----+----------+------+--------+
23| id | name | age | gender |
24+----+----------+------+--------+
25| 1 | xyy | 18 | F |
26| 10 | xiaoming | 20 | M |
27| 11 | xiaohong | 18 | F |
28| 12 | hg | 19 | M |
29| 13 | lianlian | 18 | F |
30| 14 | xiaoxiao | 18 | F |
31| 15 | yanyan | 18 | F |
32| 16 | hao | 22 | M |
33+----+----------+------+--------+
348 rows in set (0.00 sec)
🍊 范例:多个字段同时修改
1mysql> update student set age=28,gender='F' where id=16;
1mysql> select *from student;
2+----+----------+------+--------+
3| id | name | age | gender |
4+----+----------+------+--------+
5| 1 | xyy | 18 | F |
6| 10 | xiaoming | 20 | M |
7| 11 | xiaohong | 18 | F |
8| 12 | hg | 19 | M |
9| 13 | lianlian | 18 | F |
10| 14 | xiaoxiao | 18 | F |
11| 15 | yanyan | 18 | F |
12| 16 | hao | 22 | M |
13+----+----------+------+--------+
148 rows in set (0.00 sec)
15
16mysql> update student set age=28,gender='F' where id=16;
17Query OK, 1 row affected (0.01 sec)
18Rows matched: 1 Changed: 1 Warnings: 0
19
20mysql> select *from student;
21+----+----------+------+--------+
22| id | name | age | gender |
23+----+----------+------+--------+
24| 1 | xyy | 18 | F |
25| 10 | xiaoming | 20 | M |
26| 11 | xiaohong | 18 | F |
27| 12 | hg | 19 | M |
28| 13 | lianlian | 18 | F |
29| 14 | xiaoxiao | 18 | F |
30| 15 | yanyan | 18 | F |
31| 16 | hao | 28 | F |
32+----+----------+------+--------+
338 rows in set (0.00 sec)
34
35mysql>
🍊 范例:模拟灾难性更新效果
1mysql> update student set age=8;
1##当前表信息
2mysql> select *from student;
3+----+----------+------+--------+
4| id | name | age | gender |
5+----+----------+------+--------+
6| 1 | xyy | 18 | F |
7| 10 | xiaoming | 20 | M |
8| 11 | xiaohong | 18 | F |
9| 12 | hg | 19 | M |
10| 13 | lianlian | 18 | F |
11| 14 | xiaoxiao | 18 | F |
12| 15 | yanyan | 18 | F |
13| 16 | hao | 28 | F |
14+----+----------+------+--------+
158 rows in set (0.00 sec)
16
17
18##灾难性更新
19mysql> update student set age=8;
20Query OK, 8 rows affected (0.00 sec)
21Rows matched: 8 Changed: 8 Warnings: 0
22
23
24##查询
25mysql> select *from student;
26+----+----------+------+--------+
27| id | name | age | gender |
28+----+----------+------+--------+
29| 1 | xyy | 8 | F |
30| 10 | xiaoming | 8 | M |
31| 11 | xiaohong | 8 | F |
32| 12 | hg | 8 | M |
33| 13 | lianlian | 8 | F |
34| 14 | xiaoxiao | 8 | F |
35| 15 | yanyan | 8 | F |
36| 16 | hao | 8 | F |
37+----+----------+------+--------+
388 rows in set (0.00 sec)
如何避免这个问题呢?
1mysql -U | --safe-updates| --i-am-a-dummy
2[root@centos8 ~]#vim /etc/my.cnf
3[mysql]
4safe-updates
方法1:加上-U选项
1[root@linux-test ~]#mysql -uroot -pxyy520 -U
2Warning: Using a password on the command line interface can be insecure.
3Welcome to the MySQL monitor. Commands end with ; or \g.
4Your MySQL connection id is 9
5Server version: 5.6.47 MySQL Community Server (GPL)
6
7Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
8
9Oracle is a registered trademark of Oracle Corporation and/or its
10affiliates. Other names may be trademarks of their respective
11owners.
12
13Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
14
15mysql> use test
16Reading table information for completion of table and column names
17You can turn off this feature to get a quicker startup with -A
18
19Database changed
20mysql> update student set age=18;
21ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
22mysql>
方法2:写到mysql配置文件里
1[root@linux-test ~]#vim /etc/my.cnf
2[mysql]
3safe-updates
4
5然后再次测试:
6[root@linux-test ~]#mysql -uroot -pxyy520
7Warning: Using a password on the command line interface can be insecure.
8Welcome to the MySQL monitor. Commands end with ; or \g.
9Your MySQL connection id is 10
10Server version: 5.6.47 MySQL Community Server (GPL)
11
12Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
13
14Oracle is a registered trademark of Oracle Corporation and/or its
15affiliates. Other names may be trademarks of their respective
16owners.
17
18Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
19
20mysql> use test
21Reading table information for completion of table and column names
22You can turn off this feature to get a quicker startup with -A
23
24Database changed
25mysql> select *from student;
26+----+----------+------+--------+
27| id | name | age | gender |
28+----+----------+------+--------+
29| 1 | xyy | 8 | F |
30| 10 | xiaoming | 8 | M |
31| 11 | xiaohong | 8 | F |
32| 12 | hg | 8 | M |
33| 13 | lianlian | 8 | F |
34| 14 | xiaoxiao | 8 | F |
35| 15 | yanyan | 8 | F |
36| 16 | hao | 8 | F |
37+----+----------+------+--------+
388 rows in set (0.00 sec)
39
40mysql> update student set age=18;
41ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
42mysql>
43#符合预期。
DELETE语句
删除表中数据,但不会自动缩减数据文件的大小。
语法:
1DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tbl_name
2 [WHERE where_condition]
3 [ORDER BY ...]
4 [LIMIT row_count]
5 可先排序再指定删除的行数
注意:一定要有限制条件,否则将清空表中的所有数据
🍊 范例:删除表里某行数据
1mysql> delete from student where id=16;
1mysql> select *from student;
2+----+----------+------+--------+
3| id | name | age | gender |
4+----+----------+------+--------+
5| 1 | xyy | 8 | F |
6| 10 | xiaoming | 8 | M |
7| 11 | xiaohong | 8 | F |
8| 12 | hg | 8 | M |
9| 13 | lianlian | 8 | F |
10| 14 | xiaoxiao | 8 | F |
11| 15 | yanyan | 8 | F |
12| 16 | hao | 8 | F |
13+----+----------+------+--------+
148 rows in set (0.00 sec)
15
16mysql> delete from student where id=16;
17Query OK, 1 row affected (0.02 sec)
18
19mysql> select *from student;
20+----+----------+------+--------+
21| id | name | age | gender |
22+----+----------+------+--------+
23| 1 | xyy | 8 | F |
24| 10 | xiaoming | 8 | M |
25| 11 | xiaohong | 8 | F |
26| 12 | hg | 8 | M |
27| 13 | lianlian | 8 | F |
28| 14 | xiaoxiao | 8 | F |
29| 15 | yanyan | 8 | F |
30+----+----------+------+--------+
317 rows in set (0.00 sec)
🍊 范例:删除表里所有数据
1mysql> delete from student;
1mysql> select *from student;
2+----+----------+------+--------+
3| id | name | age | gender |
4+----+----------+------+--------+
5| 1 | xyy | 8 | F |
6| 10 | xiaoming | 8 | M |
7| 11 | xiaohong | 8 | F |
8| 12 | hg | 8 | M |
9| 13 | lianlian | 8 | F |
10| 14 | xiaoxiao | 8 | F |
11| 15 | yanyan | 8 | F |
12+----+----------+------+--------+
137 rows in set (0.00 sec)
14
15mysql> delete from student;
16Query OK, 7 rows affected (0.02 sec)
17
18mysql> select *from student;
19Empty set (0.00 sec)
🍊 范例:TRUNCATE命令来删除表数据
如果想清空表,保留表结构,也可以使用下面语句,此语句会自动缩减数据文件的大小。
1TRUNCATE TABLE tbl_name; #当表数据量很大的时候,这个方式删除会比前面 delete from student; 这条命令速度更快些的;
1mysql> insert student select *from student2;
2Query OK, 7 rows affected (0.00 sec)
3Records: 7 Duplicates: 0 Warnings: 0
4
5mysql> select *from student;
6+----+----------+------+--------+
7| id | name | age | gender |
8+----+----------+------+--------+
9| 1 | xyy | 18 | F |
10| 10 | xiaoming | 20 | M |
11| 11 | xiaohong | 18 | F |
12| 12 | hg | 19 | M |
13| 13 | lianlian | 18 | F |
14| 14 | xiaoxiao | 18 | F |
15| 15 | yanyan | 19 | F |
16+----+----------+------+--------+
177 rows in set (0.00 sec)
18
19mysql> truncate table student;
20Query OK, 0 rows affected (0.02 sec)
21
22mysql> select *from student;
23Empty set (0.00 sec)
注意:mysql -U选项也可以防止delete命令忘记添加where条件导致误删数据的,但对truncate命令无影响。
🍊 范例:缩减表大小
1OPTIMIZE TABLE tb_name
如下是一个生成大文件表的sql脚本:
testlog.sql
1create table testlog (id int auto_increment primary key,name char(10),age int default 20);
2
3delimiter $$
4
5create procedure pro_testlog()
6begin
7declare i int;
8set i = 1;
9while i < 100000
10do insert into testlog(name,age) values (concat('wang',i),i);
11set i = i +1;
12end while;
13end$$
14
15delimiter ;
将这个代码拷贝到自己数据库里:
1[root@linux-test ~]#mysql -uroot -pxyy520 test
2
3mysql> create table testlog (id int auto_increment primary key,name char(10),age int default 20);
4Query OK, 0 rows affected (0.01 sec)
5
6mysql>
7mysql> delimiter $$
8mysql>
9mysql> create procedure pro_testlog()
10 -> begin
11 -> declare i int;
12 -> set i = 1;
13 -> while i < 100000
14 -> do insert into testlog(name,age) values (concat('wang',i),i);
15 -> set i = i +1;
16 -> end while;
17 -> end$$
18Query OK, 0 rows affected (0.01 sec)
19
20mysql>
21mysql> delimiter ;
22mysql>
查看当前表信息:
1mysql> select *from testlog;
2Empty set (0.00 sec)
3
4[root@linux-test ~]#ll -h /data/mysql/test
5total 1.1M
6……
7-rw-rw---- 1 mysql mysql 8.5K Apr 28 07:19 testlog.frm
8-rw-rw---- 1 mysql mysql 96K Apr 28 07:19 testlog.ibd #这个文件是96K
触发脚本:
1mysql> call pro_testlog;
2Query OK, 1 row affected (16.77 sec)
3
4[root@linux-test ~]#ll -h /data/mysql/test/testlog.ibd
5-rw-rw---- 1 mysql mysql 11M Apr 28 07:21 /data/mysql/test/testlog.ibd
6[root@linux-test ~]#ll -h /data/mysql/test/testlog.ibd
7-rw-rw---- 1 mysql mysql 12M Apr 28 07:21 /data/mysql/test/testlog.ibd
8#可以看到这个testlog.ibd文件已经增大到12M了。
此时直接使用delete from testlog; 命令删除表后,那么这个/data/mysql/test/testlog.ibd文件大小是否会变小呢?
1mysql> delete from testlog;
2Query OK, 99999 rows affected (0.20 sec)
3
4mysql> select *from testlog;
5Empty set (0.00 sec)
6
7mysql>
8
9
10[root@linux-test ~]#ll -h /data/mysql/test/testlog.ibd
11-rw-rw---- 1 mysql mysql 12M Apr 28 07:24 /data/mysql/test/testlog.ibd
12#可以发现这个文件大小依然没有变化。
那么我们可以利用如下命令来清理这种空洞文件:
1mysql> OPTIMIZE TABLE testlog;
2+--------------+----------+----------+-------------------------------------------------------------------+
3| Table | Op | Msg_type | Msg_text |
4+--------------+----------+----------+-------------------------------------------------------------------+
5| test.testlog | optimize | note | Table does not support optimize, doing recreate + analyze instead |
6| test.testlog | optimize | status | OK |
7+--------------+----------+----------+-------------------------------------------------------------------+
82 rows in set (0.01 sec)
9
10##再次验证(符合预期)
11[root@linux-test ~]#ll -h /data/mysql/test/testlog.ibd
12-rw-rw---- 1 mysql mysql 96K Apr 28 07:25 /data/mysql/test/testlog.ibd
当然,truncate命令直接是可以会自动缩减数据文件的大小的。
1| 199997 | wang99998 | 99998 |
2| 199998 | wang99999 | 99999 |
3+--------+-----------+-------+
499999 rows in set (0.04 sec)
5
6mysql> truncate table testlog;
7Query OK, 0 rows affected (0.01 sec)
8
9[root@linux-test ~]#ll -h /data/mysql/test/testlog.ibd
10-rw-rw---- 1 mysql mysql 96K Apr 28 07:26 /data/mysql/test/testlog.ibd
DQL语句
行的过滤才是至关重要的!
单表操作
语法:
1SELECT
2 [ALL | DISTINCT | DISTINCTROW ]
3 [SQL_CACHE | SQL_NO_CACHE]
4 select_expr [, select_expr ...]
5 [FROM table_references
6 [WHERE where_condition]
7 [GROUP BY {col_name | expr | position}
8 [ASC | DESC], ... [WITH ROLLUP]]
9 [HAVING where_condition]
10 [ORDER BY {col_name | expr | position}
11 [ASC | DESC], ...]
12 [LIMIT {[offset,] row_count | row_count OFFSET offset}]
13 [FOR UPDATE | LOCK IN SHARE MODE]
说明:
字段显示可以使用别名:
col1 AS alias1, col2 AS alias2, ...WHERE子句:指明过滤条件以实现“选择”的功能:
过滤条件:布尔型表达式
算术操作符:+, -, *, /, %
比较操作符:=,<=>(相等或都为空), <>(不等), !=(非标准SQL), >, >=, <, <=
BETWEEN min_num AND max_num
IN (element1, element2, …)
IS NULL
IS NOT NULL
DISTINCT 去除重复行,范例:SELECT DISTINCT gender FROM students;
LIKE:
**% 任意长度的任意字符**
_ 任意单个字符
RLIKE:正则表达式,索引失效,不建议使用 –一般不建议使用正则表达式,它的性能很差。
REGEXP:匹配字符串可用正则表达式书写模式,同上
逻辑操作符:NOT,AND,OR,XOR
GROUP:根据指定的条件把查询结果进行“分组”以用于做“聚合”运算
常见聚合函数:avg(), max(), min(), count(), sum()
HAVING: 对分组聚合运算后的结果指定过滤条件
一旦分组group by ,select语句后只跟分组的字段,聚合函数
ORDER BY: 根据指定的字段对查询结果进行排序
升序:ASC
降序:DESC
LIMIT [[offset,]row_count]:对查询的结果进行输出行数数量限制
对查询结果中的数据请求施加“锁”
FOR UPDATE: 写锁,独占或排它锁,只有一个读和写操作
LOCK IN SHARE MODE: 读锁,共享锁,同时多个读操作
范例:整张表的所有内容
106:44:07(root@localhost) [test]> select * from student; #*代表对所有列不过滤,student后面也没where,代表对所有航也不过滤,即显示整张表的所有内容。
2+----+-----------+------+--------+
3| id | name | age | gender |
4+----+-----------+------+--------+
5| 1 | xyy | 18 | F |
6| 10 | xiaoming | 20 | M |
7| 11 | xiaohong | 18 | F |
8| 12 | hg | 19 | M |
9| 13 | lianlian | 18 | F |
10| 14 | xiaoxiao | 18 | F |
11| 15 | yanyan | 19 | F |
12| 17 | 马哥 | 30 | M |
13| 18 | 马云 | 30 | M |
14| 19 | 马弟弟 | 30 | M |
15| 20 | 小彦彦 | 18 | F |
16+----+-----------+------+--------+
1711 rows in set (0.00 sec)
范例:过滤列
1select name,age from student; #列的字段名是不区分大小写的,但数据库、表名是区分大小写的;
2select NAME,AGE from student;
106:44:18(root@localhost) [test]> select name,age from student; #列的字段名是不区分大小写的,但数据库、表名是区分大小写的;
2+-----------+------+
3| name | age |
4+-----------+------+
5| xyy | 18 |
6| xiaoming | 20 |
7| xiaohong | 18 |
8| hg | 19 |
9| lianlian | 18 |
10| xiaoxiao | 18 |
11| yanyan | 19 |
12| 马哥 | 30 |
13| 马云 | 30 |
14| 马弟弟 | 30 |
15| 小彦彦 | 18 |
16+-----------+------+
1711 rows in set (0.00 sec)
18
1906:51:25(root@localhost) [test]> select NAME,AGE from student;
20+-----------+------+
21| NAME | AGE |
22+-----------+------+
23| xyy | 18 |
24| xiaoming | 20 |
25| xiaohong | 18 |
26| hg | 19 |
27| lianlian | 18 |
28| xiaoxiao | 18 |
29| yanyan | 19 |
30| 马哥 | 30 |
31| 马云 | 30 |
32| 马弟弟 | 30 |
33| 小彦彦 | 18 |
34+-----------+------+
3511 rows in set (0.00 sec)
范例:过滤列(给字段起别名)
106:51:41(root@localhost) [test]> select name as 姓名,age 年龄,gender 性别 from student; #加不加as都行的。
2+-----------+--------+--------+
3| 姓名 | 年龄 | 性别 |
4+-----------+--------+--------+
5| xyy | 18 | F |
6| xiaoming | 20 | M |
7| xiaohong | 18 | F |
8| hg | 19 | M |
9| lianlian | 18 | F |
10| xiaoxiao | 18 | F |
11| yanyan | 19 | F |
12| 马哥 | 30 | M |
13| 马云 | 30 | M |
14| 马弟弟 | 30 | M |
15| 小彦彦 | 18 | F |
16+-----------+--------+--------+
1711 rows in set (0.00 sec)
🍊 范例:(多表的情况下,别名还是经常会用的)
注意:mysql里,一旦定义了别名就必须要使用别名,再使用原名是不行的。
1MariaDB [hellodb]> select stuid,students.name 学生姓名,s.age 学生年龄,tid,t.name 老师姓名,t.age 老师 年龄 from students s cross join teachers t;;
2ERROR 1054 (42S22): Unknown column 'students.name' in 'field list'
3
4MariaDB [hellodb]> select stuid,s.name 学生姓名,s.age 学生年龄,tid,t.name 老师姓名,t.age 老师年龄 from students s cross join teachers t;
5+-------+---------------+--------------+-----+---------------+--------------+
6| stuid | 学生姓名 | 学生年龄 | tid | 老师姓名 | 老师年龄 |
7+-------+---------------+--------------+-----+---------------+--------------+
8| 1 | Shi Zhongyu | 22 | 1 | Song Jiang | 45 |
9| 1 | Shi Zhongyu | 22 | 2 | Zhang Sanfeng | 94 |
10| 1 | Shi Zhongyu | 22 | 3 | Miejue Shitai | 77 |
范例:针对特定字段DISTINCT 去除重复行
107:03:09(root@localhost) [test]> SELECT DISTINCT gender FROM student;
2+--------+
3| gender |
4+--------+
5| F |
6| M |
7+--------+
82 rows in set (0.00 sec)
范例:过滤列和行(等于/不等于)
107:03:13(root@localhost) [test]> select * from student where gender='F';
2+----+-----------+------+--------+
3| id | name | age | gender |
4+----+-----------+------+--------+
5| 1 | xyy | 18 | F |
6| 11 | xiaohong | 18 | F |
7| 13 | lianlian | 18 | F |
8| 14 | xiaoxiao | 18 | F |
9| 15 | yanyan | 19 | F |
10| 20 | 小彦彦 | 18 | F |
11+----+-----------+------+--------+
126 rows in set (0.01 sec)
13
1407:08:45(root@localhost) [test]> select name,age,gender from student where gender='F';
15+-----------+------+--------+
16| name | age | gender |
17+-----------+------+--------+
18| xyy | 18 | F |
19| xiaohong | 18 | F |
20| lianlian | 18 | F |
21| xiaoxiao | 18 | F |
22| yanyan | 19 | F |
23| 小彦彦 | 18 | F |
24+-----------+------+--------+
256 rows in set (0.00 sec)
26
27其它demo:
28select name,age,gender from student where gender <> 'F';
29select name,age,gender from student where gender != 'F';
30
31select name,age,gender from student where gender = 'F';
32select name,age,gender from student where gender <=> 'F';
范例:(>=或者between …… and ……)
107:09:46(root@localhost) [test]> select name,age,gender from student where age<=18;
2+-----------+------+--------+
3| name | age | gender |
4+-----------+------+--------+
5| xyy | 18 | F |
6| xiaohong | 18 | F |
7| lianlian | 18 | F |
8| xiaoxiao | 18 | F |
9| 小彦彦 | 18 | F |
10+-----------+------+--------+
115 rows in set (0.00 sec)
12
1307:13:07(root@localhost) [test]> select name,age,gender from student where age>=18 and age <=28;
14+-----------+------+--------+
15| name | age | gender |
16+-----------+------+--------+
17| xyy | 18 | F |
18| xiaoming | 20 | M |
19| xiaohong | 18 | F |
20| hg | 19 | M |
21| lianlian | 18 | F |
22| xiaoxiao | 18 | F |
23| yanyan | 19 | F |
24| 小彦彦 | 18 | F |
25+-----------+------+--------+
268 rows in set (0.00 sec)
27
2807:13:29(root@localhost) [test]> select name,age,gender from student where age between 18 and 28;
29+-----------+------+--------+
30| name | age | gender |
31+-----------+------+--------+
32| xyy | 18 | F |
33| xiaoming | 20 | M |
34| xiaohong | 18 | F |
35| hg | 19 | M |
36| lianlian | 18 | F |
37| xiaoxiao | 18 | F |
38| yanyan | 19 | F |
39| 小彦彦 | 18 | F |
40+-----------+------+--------+
418 rows in set (0.00 sec)
范例:参与数字运算
107:14:44(root@localhost) [test]> select name,age+18,gender from student;
2+-----------+--------+--------+
3| name | age+18 | gender |
4+-----------+--------+--------+
5| xyy | 36 | F |
6| xiaoming | 38 | M |
7| xiaohong | 36 | F |
8| hg | 37 | M |
9| lianlian | 36 | F |
10| xiaoxiao | 36 | F |
11| yanyan | 37 | F |
12| 马哥 | 48 | M |
13| 马云 | 48 | M |
14| 马弟弟 | 48 | M |
15| 小彦彦 | 36 | F |
16+-----------+--------+--------+
1711 rows in set (0.00 sec)
18
19
20
2107:16:40(root@localhost) [test]> select 10*20;
22+-------+
23| 10*20 |
24+-------+
25| 200 |
26+-------+
271 row in set (0.00 sec)
28
2907:18:17(root@localhost) [test]> select 10*20 as result;
30+--------+
31| result |
32+--------+
33| 200 |
34+--------+
351 row in set (0.00 sec)
范例:in用法
107:19:22(root@localhost) [test]> select name,age,gender from student where age in (18,19,20);
2+-----------+------+--------+
3| name | age | gender |
4+-----------+------+--------+
5| xyy | 18 | F |
6| xiaoming | 20 | M |
7| xiaohong | 18 | F |
8| hg | 19 | M |
9| lianlian | 18 | F |
10| xiaoxiao | 18 | F |
11| yanyan | 19 | F |
12| 小彦彦 | 18 | F |
13+-----------+------+--------+
148 rows in set (0.00 sec)
范例:判断为空
107:24:26(root@localhost) [hellodb]> select * from students where classid == NULL;
2ERROR 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 '== NULL' at line 1
307:24:30(root@localhost) [hellodb]> select * from students where classid == null;
4ERROR 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 '== null' at line 1
5
6
707:24:39(root@localhost) [hellodb]> select * from students where classid is NULL;
8+-------+-------------+-----+--------+---------+-----------+
9| StuID | Name | Age | Gender | ClassID | TeacherID |
10+-------+-------------+-----+--------+---------+-----------+
11| 24 | Xu Xian | 27 | M | NULL | NULL |
12| 25 | Sun Dasheng | 100 | M | NULL | NULL |
13+-------+-------------+-----+--------+---------+-----------+
142 rows in set (0.00 sec)
15
1607:24:45(root@localhost) [hellodb]> select * from students where classid is null;
17+-------+-------------+-----+--------+---------+-----------+
18| StuID | Name | Age | Gender | ClassID | TeacherID |
19+-------+-------------+-----+--------+---------+-----------+
20| 24 | Xu Xian | 27 | M | NULL | NULL |
21| 25 | Sun Dasheng | 100 | M | NULL | NULL |
22+-------+-------------+-----+--------+---------+-----------+
232 rows in set (0.00 sec)
24
2507:24:49(root@localhost) [hellodb]> select * from students where classid <=> null; #这个写法也是可以的。
26+-------+-------------+-----+--------+---------+-----------+
27| StuID | Name | Age | Gender | ClassID | TeacherID |
28+-------+-------------+-----+--------+---------+-----------+
29| 24 | Xu Xian | 27 | M | NULL | NULL |
30| 25 | Sun Dasheng | 100 | M | NULL | NULL |
31+-------+-------------+-----+--------+---------+-----------+
322 rows in set (0.00 sec)
33
34select * from students where classid is not null;
范例:模糊查找
107:27:07(root@localhost) [hellodb]> select * from students where name like 'xu%'; #大小写不敏感的,过滤xu开头的
2+-------+-------------+-----+--------+---------+-----------+
3| StuID | Name | Age | Gender | ClassID | TeacherID |
4+-------+-------------+-----+--------+---------+-----------+
5| 16 | Xu Zhu | 21 | M | 1 | NULL |
6| 19 | Xue Baochai | 18 | F | 6 | NULL |
7| 24 | Xu Xian | 27 | M | NULL | NULL |
8+-------+-------------+-----+--------+---------+-----------+
93 rows in set (0.00 sec)
范例:SQL 注入攻击
1方式1:
2select * from user where username='admin' and password='' or '1'='1';
3select * from user where username='admin' and password='' or '1=1';
4
5方式2:注释方式
6select * from user where username='admin'; -- ' and password='magedu123';
7select * from user where username='admin'; # ' and password='magedu123';
1##先创建一张表:
207:26:13(root@localhost) [test]> create table user (id int primary key auto_increment, username varchar(30) not null, password varchar(50));
3Query OK, 0 rows affected (0.01 sec)
4
507:27:40(root@localhost) [test]> select *from user;
6Empty set (0.00 sec)
7
8
9##插入一条数据:
1007:27:49(root@localhost) [test]> insert user (username,password)values('admin','Magedu20230206');
11Query OK, 1 row affected (0.01 sec)
12
1307:29:23(root@localhost) [test]> select *from user;
14+----+----------+----------------+
15| id | username | password |
16+----+----------+----------------+
17| 1 | admin | Magedu20230206 |
18+----+----------+----------------+
191 row in set (0.00 sec)
20##再插入一条数据:
2107:32:18(root@localhost) [test]> insert user (username,password)values('hg','Magedu');
22Query OK, 1 row affected (0.01 sec)
23
2407:33:17(root@localhost) [test]> select *from user;
25+----+----------+----------------+
26| id | username | password |
27+----+----------+----------------+
28| 1 | admin | Magedu20230206 |
29| 2 | hg | Magedu |
30+----+----------+----------------+
312 rows in set (0.00 sec)
32
33
34
35
36##一般网页登录时会查询后台数据库里用户名和密码是否匹配
3707:29:26(root@localhost) [test]> select *from user where username='admin' and password='mage';
38Empty set (0.00 sec)
39
4007:32:03(root@localhost) [test]> select *from user where username='admin' and password='Magedu20230206';
41+----+----------+----------------+
42| id | username | password |
43+----+----------+----------------+
44| 1 | admin | Magedu20230206 |
45+----+----------+----------------+
461 row in set (0.00 sec)
47
48
49
50##此时如何利用mysql注入攻击呢?
5107:33:36(root@localhost) [test]> select * from user where username='admin' and password='' or '1'='1';
52+----+----------+----------------+
53| id | username | password |
54+----+----------+----------------+
55| 1 | admin | Magedu20230206 |
56| 2 | hg | Magedu |
57+----+----------+----------------+
582 rows in set (0.00 sec)
59##呃呃,这个也就绕过来密码,直接查到了user表里的所有信息。
6007:34:59(root@localhost) [test]> select * from user where '1'='1'; ##这个同理也是可以查出表的所有信息的!
61+----+----------+----------------+
62| id | username | password |
63+----+----------+----------------+
64| 1 | admin | Magedu20230206 |
65| 2 | hg | Magedu |
66+----+----------+----------------+
672 rows in set (0.00 sec)
68
69
70
71
72另一个方式测试SQL注入攻击:
73构建一个特殊的用户名:
74#-- 和 #代表注释;
7507:49:29(root@localhost) [test]> select * from user where username='admin'; -- ' and password='magedu123';
76+----+----------+----------------+
77| id | username | password |
78+----+----------+----------------+
79| 1 | admin | Magedu20230206 |
80+----+----------+----------------+
811 row in set (0.00 sec)
82
8307:50:30(root@localhost) [test]> select * from user where username='admin'; # ' and password='magedu123';
84+----+----------+----------------+
85| id | username | password |
86+----+----------+----------------+
87| 1 | admin | Magedu20230206 |
88+----+----------+----------------+
891 row in set (0.00 sec)
范例:rlike正则表达式
107:56:39(root@localhost) [hellodb]> select *from students where name rlike '^Shi';
2+-------+-------------+-----+--------+---------+-----------+
3| StuID | Name | Age | Gender | ClassID | TeacherID |
4+-------+-------------+-----+--------+---------+-----------+
5| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
6| 2 | Shi Potian | 22 | M | 1 | 7 |
7| 6 | Shi Qing | 46 | M | 5 | NULL |
8+-------+-------------+-----+--------+---------+-----------+
93 rows in set (0.01 sec)
10
1107:56:43(root@localhost) [hellodb]> select *from students where name rlike '^shi'; #这里的正则表达式后不区分大小写。
12+-------+-------------+-----+--------+---------+-----------+
13| StuID | Name | Age | Gender | ClassID | TeacherID |
14+-------+-------------+-----+--------+---------+-----------+
15| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
16| 2 | Shi Potian | 22 | M | 1 | 7 |
17| 6 | Shi Qing | 46 | M | 5 | NULL |
18+-------+-------------+-----+--------+---------+-----------+
193 rows in set (0.00 sec)
范例:group分组
一个是分组字段本身;
或者是聚合函数;
其它字段毫无意义。
108:10:34(root@localhost) [hellodb]> select gender,avg(age),max(age),min(age) from students group by gender;
2+--------+----------+----------+----------+
3| gender | avg(age) | max(age) | min(age) |
4+--------+----------+----------+----------+
5| F | 19.0000 | 22 | 17 |
6| M | 33.0000 | 100 | 19 |
7+--------+----------+----------+----------+
82 rows in set (0.00 sec)
908:13:35(root@localhost) [hellodb]> select gender,avg(age),sum(age),max(age),min(age) from students group by gender;
10+--------+----------+----------+----------+----------+
11| gender | avg(age) | sum(age) | max(age) | min(age) |
12+--------+----------+----------+----------+----------+
13| F | 19.0000 | 190 | 22 | 17 |
14| M | 33.0000 | 495 | 100 | 19 |
15+--------+----------+----------+----------+----------+
162 rows in set (0.00 sec)
对多字段分别统计:
108:11:41(root@localhost) [hellodb]> select classid,gender,avg(age),max(age),min(age) from students group by classid,gender;
2+---------+--------+----------+----------+----------+
3| classid | gender | avg(age) | max(age) | min(age) |
4+---------+--------+----------+----------+----------+
5| NULL | M | 63.5000 | 100 | 27 |
6| 1 | F | 19.5000 | 20 | 19 |
7| 1 | M | 21.5000 | 22 | 21 |
8| 2 | M | 36.0000 | 53 | 22 |
9| 3 | F | 18.3333 | 19 | 17 |
10| 3 | M | 26.0000 | 26 | 26 |
11| 4 | M | 24.7500 | 32 | 19 |
12| 5 | M | 46.0000 | 46 | 46 |
13| 6 | F | 20.0000 | 22 | 18 |
14| 6 | M | 23.0000 | 23 | 23 |
15| 7 | F | 18.0000 | 19 | 17 |
16| 7 | M | 23.0000 | 23 | 23 |
17+---------+--------+----------+----------+----------+
1812 rows in set (0.00 sec)
- 范例:统计某个班的平均年龄:
方法1:先分组后过滤
106:10:38(root@localhost) [hellodb]> select classid,avg(age) from students group by classid;
2+---------+----------+
3| classid | avg(age) |
4+---------+----------+
5| NULL | 63.5000 |
6| 1 | 20.5000 |
7| 2 | 36.0000 |
8| 3 | 20.2500 |
9| 4 | 24.7500 |
10| 5 | 46.0000 |
11| 6 | 20.7500 |
12| 7 | 19.6667 |
13+---------+----------+
148 rows in set (0.00 sec)
15
16##如果分组右面有where筛选的话,那么where要替换成having才行!
1706:11:28(root@localhost) [hellodb]> select classid,avg(age) from students group by classid where classid is not null;
18ERROR 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 'where classid is not null' at line 1
19
20
21
2206:11:42(root@localhost) [hellodb]> select classid,avg(age) from students group by classid having classid is not null;
23+---------+----------+
24| classid | avg(age) |
25+---------+----------+
26| 1 | 20.5000 |
27| 2 | 36.0000 |
28| 3 | 20.2500 |
29| 4 | 24.7500 |
30| 5 | 46.0000 |
31| 6 | 20.7500 |
32| 7 | 19.6667 |
33+---------+----------+
347 rows in set (0.00 sec)
方法2:先过滤后分组
106:11:52(root@localhost) [hellodb]> select classid,avg(age) from students where classid is not null group by classid;
2+---------+----------+
3| classid | avg(age) |
4+---------+----------+
5| 1 | 20.5000 |
6| 2 | 36.0000 |
7| 3 | 20.2500 |
8| 4 | 24.7500 |
9| 5 | 46.0000 |
10| 6 | 20.7500 |
11| 7 | 19.6667 |
12+---------+----------+
137 rows in set (0.00 sec)
范例:排序
- 范例:排序
106:20:16(root@localhost) [hellodb]> select *from students order by age;
2+-------+---------------+-----+--------+---------+-----------+
3| StuID | Name | Age | Gender | ClassID | TeacherID |
4+-------+---------------+-----+--------+---------+-----------+
5| 8 | Lin Daiyu | 17 | F | 7 | NULL |
6| 14 | Lu Wushuang | 17 | F | 3 | NULL |
7| 19 | Xue Baochai | 18 | F | 6 | NULL |
8| 12 | Wen Qingqing | 19 | F | 1 | NULL |
9| 10 | Yue Lingshan | 19 | F | 3 | NULL |
10| 7 | Xi Ren | 19 | F | 3 | NULL |
11| 15 | Duan Yu | 19 | M | 4 | NULL |
12| 20 | Diao Chan | 19 | F | 7 | NULL |
13| 9 | Ren Yingying | 20 | F | 6 | NULL |
14| 22 | Xiao Qiao | 20 | F | 1 | NULL |
15| 16 | Xu Zhu | 21 | M | 1 | NULL |
16| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
17| 21 | Huang Yueying | 22 | F | 6 | NULL |
18| 2 | Shi Potian | 22 | M | 1 | 7 |
19| 23 | Ma Chao | 23 | M | 4 | NULL |
20| 18 | Hua Rong | 23 | M | 7 | NULL |
21| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
22| 17 | Lin Chong | 25 | M | 4 | NULL |
23| 5 | Yu Yutong | 26 | M | 3 | 1 |
24| 24 | Xu Xian | 27 | M | NULL | NULL |
25| 4 | Ding Dian | 32 | M | 4 | 4 |
26| 13 | Tian Boguang | 33 | M | 2 | NULL |
27| 6 | Shi Qing | 46 | M | 5 | NULL |
28| 3 | Xie Yanke | 53 | M | 2 | 16 |
29| 25 | Sun Dasheng | 100 | M | NULL | NULL |
30+-------+---------------+-----+--------+---------+-----------+
3125 rows in set (0.00 sec)
- 范例:排序(逆序)
106:20:33(root@localhost) [hellodb]> select *from students order by age desc;
2+-------+---------------+-----+--------+---------+-----------+
3| StuID | Name | Age | Gender | ClassID | TeacherID |
4+-------+---------------+-----+--------+---------+-----------+
5| 25 | Sun Dasheng | 100 | M | NULL | NULL |
6| 3 | Xie Yanke | 53 | M | 2 | 16 |
7| 6 | Shi Qing | 46 | M | 5 | NULL |
8| 13 | Tian Boguang | 33 | M | 2 | NULL |
9| 4 | Ding Dian | 32 | M | 4 | 4 |
10| 24 | Xu Xian | 27 | M | NULL | NULL |
11| 5 | Yu Yutong | 26 | M | 3 | 1 |
12| 17 | Lin Chong | 25 | M | 4 | NULL |
13| 23 | Ma Chao | 23 | M | 4 | NULL |
14| 18 | Hua Rong | 23 | M | 7 | NULL |
15| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
16| 21 | Huang Yueying | 22 | F | 6 | NULL |
17| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
18| 2 | Shi Potian | 22 | M | 1 | 7 |
19| 16 | Xu Zhu | 21 | M | 1 | NULL |
20| 22 | Xiao Qiao | 20 | F | 1 | NULL |
21| 9 | Ren Yingying | 20 | F | 6 | NULL |
22| 15 | Duan Yu | 19 | M | 4 | NULL |
23| 7 | Xi Ren | 19 | F | 3 | NULL |
24| 20 | Diao Chan | 19 | F | 7 | NULL |
25| 10 | Yue Lingshan | 19 | F | 3 | NULL |
26| 12 | Wen Qingqing | 19 | F | 1 | NULL |
27| 19 | Xue Baochai | 18 | F | 6 | NULL |
28| 8 | Lin Daiyu | 17 | F | 7 | NULL |
29| 14 | Lu Wushuang | 17 | F | 3 | NULL |
30+-------+---------------+-----+--------+---------+-----------+
3125 rows in set (0.00 sec)
- 范例:排序(字段含
null处理)(小技巧)
1##默认null优先级比较高,会排在最前面
206:21:00(root@localhost) [hellodb]> select *from students order by classid;
3+-------+---------------+-----+--------+---------+-----------+
4| StuID | Name | Age | Gender | ClassID | TeacherID |
5+-------+---------------+-----+--------+---------+-----------+
6| 25 | Sun Dasheng | 100 | M | NULL | NULL |
7| 24 | Xu Xian | 27 | M | NULL | NULL |
8| 2 | Shi Potian | 22 | M | 1 | 7 |
9| 22 | Xiao Qiao | 20 | F | 1 | NULL |
10| 16 | Xu Zhu | 21 | M | 1 | NULL |
11| 12 | Wen Qingqing | 19 | F | 1 | NULL |
12| 13 | Tian Boguang | 33 | M | 2 | NULL |
13| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
14| 3 | Xie Yanke | 53 | M | 2 | 16 |
15| 10 | Yue Lingshan | 19 | F | 3 | NULL |
16| 7 | Xi Ren | 19 | F | 3 | NULL |
17| 14 | Lu Wushuang | 17 | F | 3 | NULL |
18| 5 | Yu Yutong | 26 | M | 3 | 1 |
19| 23 | Ma Chao | 23 | M | 4 | NULL |
20| 4 | Ding Dian | 32 | M | 4 | 4 |
21| 17 | Lin Chong | 25 | M | 4 | NULL |
22| 15 | Duan Yu | 19 | M | 4 | NULL |
23| 6 | Shi Qing | 46 | M | 5 | NULL |
24| 19 | Xue Baochai | 18 | F | 6 | NULL |
25| 21 | Huang Yueying | 22 | F | 6 | NULL |
26| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
27| 9 | Ren Yingying | 20 | F | 6 | NULL |
28| 18 | Hua Rong | 23 | M | 7 | NULL |
29| 20 | Diao Chan | 19 | F | 7 | NULL |
30| 8 | Lin Daiyu | 17 | F | 7 | NULL |
31+-------+---------------+-----+--------+---------+-----------+
3225 rows in set (0.00 sec)
33
34
35##如果让null排在最后面呢?
3606:22:40(root@localhost) [hellodb]> select *from students order by -classid desc;
37+-------+---------------+-----+--------+---------+-----------+
38| StuID | Name | Age | Gender | ClassID | TeacherID |
39+-------+---------------+-----+--------+---------+-----------+
40| 2 | Shi Potian | 22 | M | 1 | 7 |
41| 22 | Xiao Qiao | 20 | F | 1 | NULL |
42| 16 | Xu Zhu | 21 | M | 1 | NULL |
43| 12 | Wen Qingqing | 19 | F | 1 | NULL |
44| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
45| 13 | Tian Boguang | 33 | M | 2 | NULL |
46| 3 | Xie Yanke | 53 | M | 2 | 16 |
47| 7 | Xi Ren | 19 | F | 3 | NULL |
48| 10 | Yue Lingshan | 19 | F | 3 | NULL |
49| 5 | Yu Yutong | 26 | M | 3 | 1 |
50| 14 | Lu Wushuang | 17 | F | 3 | NULL |
51| 23 | Ma Chao | 23 | M | 4 | NULL |
52| 17 | Lin Chong | 25 | M | 4 | NULL |
53| 4 | Ding Dian | 32 | M | 4 | 4 |
54| 15 | Duan Yu | 19 | M | 4 | NULL |
55| 6 | Shi Qing | 46 | M | 5 | NULL |
56| 9 | Ren Yingying | 20 | F | 6 | NULL |
57| 21 | Huang Yueying | 22 | F | 6 | NULL |
58| 19 | Xue Baochai | 18 | F | 6 | NULL |
59| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
60| 20 | Diao Chan | 19 | F | 7 | NULL |
61| 18 | Hua Rong | 23 | M | 7 | NULL |
62| 8 | Lin Daiyu | 17 | F | 7 | NULL |
63| 24 | Xu Xian | 27 | M | NULL | NULL |
64| 25 | Sun Dasheng | 100 | M | NULL | NULL |
65+-------+---------------+-----+--------+---------+-----------+
6625 rows in set (0.00 sec)
asc–正序;(默认不写)
desc–排序;
- 范例:多列排序
106:22:49(root@localhost) [hellodb]> select *from students order by classid,age; ##先按classid排序,再按age排序;
2+-------+---------------+-----+--------+---------+-----------+
3| StuID | Name | Age | Gender | ClassID | TeacherID |
4+-------+---------------+-----+--------+---------+-----------+
5| 24 | Xu Xian | 27 | M | NULL | NULL |
6| 25 | Sun Dasheng | 100 | M | NULL | NULL |
7| 12 | Wen Qingqing | 19 | F | 1 | NULL |
8| 22 | Xiao Qiao | 20 | F | 1 | NULL |
9| 16 | Xu Zhu | 21 | M | 1 | NULL |
10| 2 | Shi Potian | 22 | M | 1 | 7 |
11| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
12| 13 | Tian Boguang | 33 | M | 2 | NULL |
13| 3 | Xie Yanke | 53 | M | 2 | 16 |
14| 14 | Lu Wushuang | 17 | F | 3 | NULL |
15| 10 | Yue Lingshan | 19 | F | 3 | NULL |
16| 7 | Xi Ren | 19 | F | 3 | NULL |
17| 5 | Yu Yutong | 26 | M | 3 | 1 |
18| 15 | Duan Yu | 19 | M | 4 | NULL |
19| 23 | Ma Chao | 23 | M | 4 | NULL |
20| 17 | Lin Chong | 25 | M | 4 | NULL |
21| 4 | Ding Dian | 32 | M | 4 | 4 |
22| 6 | Shi Qing | 46 | M | 5 | NULL |
23| 19 | Xue Baochai | 18 | F | 6 | NULL |
24| 9 | Ren Yingying | 20 | F | 6 | NULL |
25| 21 | Huang Yueying | 22 | F | 6 | NULL |
26| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
27| 8 | Lin Daiyu | 17 | F | 7 | NULL |
28| 20 | Diao Chan | 19 | F | 7 | NULL |
29| 18 | Hua Rong | 23 | M | 7 | NULL |
30+-------+---------------+-----+--------+---------+-----------+
3125 rows in set (0.00 sec)
32
3306:26:55(root@localhost) [hellodb]>
34
35
36
37
3806:26:55(root@localhost) [hellodb]> select *from students order by classid desc,age;
39+-------+---------------+-----+--------+---------+-----------+
40| StuID | Name | Age | Gender | ClassID | TeacherID |
41+-------+---------------+-----+--------+---------+-----------+
42| 8 | Lin Daiyu | 17 | F | 7 | NULL |
43| 20 | Diao Chan | 19 | F | 7 | NULL |
44| 18 | Hua Rong | 23 | M | 7 | NULL |
45| 19 | Xue Baochai | 18 | F | 6 | NULL |
46| 9 | Ren Yingying | 20 | F | 6 | NULL |
47| 21 | Huang Yueying | 22 | F | 6 | NULL |
48| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
49| 6 | Shi Qing | 46 | M | 5 | NULL |
50| 15 | Duan Yu | 19 | M | 4 | NULL |
51| 23 | Ma Chao | 23 | M | 4 | NULL |
52| 17 | Lin Chong | 25 | M | 4 | NULL |
53| 4 | Ding Dian | 32 | M | 4 | 4 |
54| 14 | Lu Wushuang | 17 | F | 3 | NULL |
55| 10 | Yue Lingshan | 19 | F | 3 | NULL |
56| 7 | Xi Ren | 19 | F | 3 | NULL |
57| 5 | Yu Yutong | 26 | M | 3 | 1 |
58| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
59| 13 | Tian Boguang | 33 | M | 2 | NULL |
60| 3 | Xie Yanke | 53 | M | 2 | 16 |
61| 12 | Wen Qingqing | 19 | F | 1 | NULL |
62| 22 | Xiao Qiao | 20 | F | 1 | NULL |
63| 16 | Xu Zhu | 21 | M | 1 | NULL |
64| 2 | Shi Potian | 22 | M | 1 | 7 |
65| 24 | Xu Xian | 27 | M | NULL | NULL |
66| 25 | Sun Dasheng | 100 | M | NULL | NULL |
67+-------+---------------+-----+--------+---------+-----------+
6825 rows in set (0.00 sec)
范例:limit
LIMIT [[offset,]row_count]:对查询的结果进行输出行数数量限制。
- 范例:显示过滤的前10行
106:27:31(root@localhost) [hellodb]> select *from students order by age limit 10;
2+-------+--------------+-----+--------+---------+-----------+
3| StuID | Name | Age | Gender | ClassID | TeacherID |
4+-------+--------------+-----+--------+---------+-----------+
5| 14 | Lu Wushuang | 17 | F | 3 | NULL |
6| 8 | Lin Daiyu | 17 | F | 7 | NULL |
7| 19 | Xue Baochai | 18 | F | 6 | NULL |
8| 15 | Duan Yu | 19 | M | 4 | NULL |
9| 12 | Wen Qingqing | 19 | F | 1 | NULL |
10| 7 | Xi Ren | 19 | F | 3 | NULL |
11| 20 | Diao Chan | 19 | F | 7 | NULL |
12| 10 | Yue Lingshan | 19 | F | 3 | NULL |
13| 9 | Ren Yingying | 20 | F | 6 | NULL |
14| 22 | Xiao Qiao | 20 | F | 1 | NULL |
15+-------+--------------+-----+--------+---------+-----------+
1610 rows in set (0.00 sec)
17
18
19#跳过前2行,显示后3行;(但是这里有问题,后续几行都是19,这里把Duan Yu给跳过了)
2006:33:17(root@localhost) [hellodb]> select *from students order by age limit 2,3;
21+-------+--------------+-----+--------+---------+-----------+
22| StuID | Name | Age | Gender | ClassID | TeacherID |
23+-------+--------------+-----+--------+---------+-----------+
24| 19 | Xue Baochai | 18 | F | 6 | NULL |
25| 12 | Wen Qingqing | 19 | F | 1 | NULL |
26| 7 | Xi Ren | 19 | F | 3 | NULL |
27+-------+--------------+-----+--------+---------+-----------+
283 rows in set (0.00 sec)
29
30#
3106:33:29(root@localhost) [hellodb]> select distinct age from students;
32+-----+
33| age |
34+-----+
35| 22 |
36| 53 |
37| 32 |
38| 26 |
39| 46 |
40| 19 |
41| 17 |
42| 20 |
43| 23 |
44| 33 |
45| 21 |
46| 25 |
47| 18 |
48| 27 |
49| 100 |
50+-----+
5115 rows in set (0.00 sec)
52
5306:38:22(root@localhost) [hellodb]> select distinct age from students order by age;
54+-----+
55| age |
56+-----+
57| 17 |
58| 18 |
59| 19 |
60| 20 |
61| 21 |
62| 22 |
63| 23 |
64| 25 |
65| 26 |
66| 27 |
67| 32 |
68| 33 |
69| 46 |
70| 53 |
71| 100 |
72+-----+
7315 rows in set (0.00 sec)
74
7506:38:30(root@localhost) [hellodb]> select distinct age from students order by age limit 5;
76+-----+
77| age |
78+-----+
79| 17 |
80| 18 |
81| 19 |
82| 20 |
83| 21 |
84+-----+
855 rows in set (0.00 sec)
86
8706:38:44(root@localhost) [hellodb]> select distinct age from students order by age limit 2,3;
88+-----+
89| age |
90+-----+
91| 19 |
92| 20 |
93| 21 |
94+-----+
953 rows in set (0.00 sec)
96
97
98##当然,我们对主键操作是没问题的,主键里的字段是不重复的。
9906:38:48(root@localhost) [hellodb]> select *from students order by stuid limit 2,3;
100+-------+-----------+-----+--------+---------+-----------+
101| StuID | Name | Age | Gender | ClassID | TeacherID |
102+-------+-----------+-----+--------+---------+-----------+
103| 3 | Xie Yanke | 53 | M | 2 | 16 |
104| 4 | Ding Dian | 32 | M | 4 | 4 |
105| 5 | Yu Yutong | 26 | M | 3 | 1 |
106+-------+-----------+-----+--------+---------+-----------+
1073 rows in set (0.00 sec)
范例:时间查询
- 范例
106:44:19(root@localhost) [test]> show create table testdate;
2+----------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
3| Table | Create Table |
4+----------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
5| testdate | CREATE TABLE `testdate` (
6 `id` int(11) NOT NULL AUTO_INCREMENT,
7 `date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
8 PRIMARY KEY (`id`)
9) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1 |
10+----------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
111 row in set (0.00 sec)
12
13
1406:44:33(root@localhost) [test]> desc testdate;
15+-------+-----------+------+-----+-------------------+----------------+
16| Field | Type | Null | Key | Default | Extra |
17+-------+-----------+------+-----+-------------------+----------------+
18| id | int(11) | NO | PRI | NULL | auto_increment |
19| date | timestamp | NO | | CURRENT_TIMESTAMP | |
20+-------+-----------+------+-----+-------------------+----------------+
212 rows in set (0.00 sec)
22
2306:45:04(root@localhost) [test]> select *from testdate;
24+----+---------------------+
25| id | date |
26+----+---------------------+
27| 1 | 2024-04-27 13:35:20 |
28| 2 | 2024-04-27 13:35:22 |
29| 3 | 2024-04-27 13:35:24 |
30| 4 | 2024-04-27 13:35:27 |
31+----+---------------------+
324 rows in set (0.00 sec)
33
34
35##新加几行数据
3606:45:49(root@localhost) [test]> insert testdate (id)values(5);
37Query OK, 1 row affected (0.01 sec)
38
3906:46:18(root@localhost) [test]> insert testdate (id)values(6);
40Query OK, 1 row affected (0.00 sec)
41
4206:46:20(root@localhost) [test]> insert testdate (id)values(7);
43Query OK, 1 row affected (0.00 sec)
44
4506:46:23(root@localhost) [test]> select *from testdate;
46+----+---------------------+
47| id | date |
48+----+---------------------+
49| 1 | 2024-04-27 13:35:20 |
50| 2 | 2024-04-27 13:35:22 |
51| 3 | 2024-04-27 13:35:24 |
52| 4 | 2024-04-27 13:35:27 |
53| 5 | 2024-05-02 06:46:18 |
54| 6 | 2024-05-02 06:46:20 |
55| 7 | 2024-05-02 06:46:23 |
56+----+---------------------+
577 rows in set (0.00 sec)
58
59
60
61##时间过滤
6206:49:18(root@localhost) [test]> select *from testdate where date between '2024-04-27 13:35:22' and '2024-05-02 06:46:20';
63+----+---------------------+
64| id | date |
65+----+---------------------+
66| 2 | 2024-04-27 13:35:22 |
67| 3 | 2024-04-27 13:35:24 |
68| 4 | 2024-04-27 13:35:27 |
69| 5 | 2024-05-02 06:46:18 |
70| 6 | 2024-05-02 06:46:20 |
71+----+---------------------+
725 rows in set (0.00 sec)
7306:49:36(root@localhost) [test]> select *from testdate where date between '2024-05-02 06:46:20' and '2024-04-27 13:35:22'; ##小的数值一定要放在前面才行的;
74Empty set (0.00 sec)
- 范例:
>= and <=也是可以的。
106:50:38(root@localhost) [test]> select *from testdate where date >='2024-04-27 13:35:22' and date <= '2024-05-02 06:46:20';
2+----+---------------------+
3| id | date |
4+----+---------------------+
5| 2 | 2024-04-27 13:35:22 |
6| 3 | 2024-04-27 13:35:24 |
7| 4 | 2024-04-27 13:35:27 |
8| 5 | 2024-05-02 06:46:18 |
9| 6 | 2024-05-02 06:46:20 |
10+----+---------------------+
115 rows in set (0.00 sec)
多表查询(7个图)🍕

最重要的是这2张图,其它都是从这2个图变过来的。(内连接+左外连接–>其它方式(变种))
多表连接–面试常用的题;工作中也是比较常用的;
多表查询,即查询结果来自于多张表

子查询:在SQL语句嵌套着查询语句,性能较差,基于某语句的查询结果再次进行的查询
联合查询:UNION
交叉连接:笛卡尔乘积
内连接:
等值连接:让表之间的字段以“等值”建立连接关系
不等值连接
自然连接:去掉重复列的等值连接
外连接:
左外连接:FROM tb1 LEFT JOIN tb2 ON tb1.col=tb2.col
右外连接:FROM tb1 RIGHT JOIN tb2 ON tb1.col=tb2.col
自连接:本表和本表进行连接查询
子查询
效率比较低。
常用在WHERE子句中的子查询
1、用于比较表达式中的子查询;子查询仅能返回单个值
1SELECT Name,Age FROM students WHERE Age>(SELECT avg(Age) FROM teachers);
- 范例:
108:37:04(root@localhost) [hellodb]> select avg(age) from students;
2+----------+
3| avg(age) |
4+----------+
5| 27.4000 |
6+----------+
71 row in set (0.00 sec)
8
908:37:13(root@localhost) [hellodb]> select *from students where age > (select avg(age) from students);
10+-------+--------------+-----+--------+---------+-----------+
11| StuID | Name | Age | Gender | ClassID | TeacherID |
12+-------+--------------+-----+--------+---------+-----------+
13| 3 | Xie Yanke | 53 | M | 2 | 16 |
14| 4 | Ding Dian | 32 | M | 4 | 4 |
15| 6 | Shi Qing | 46 | M | 5 | NULL |
16| 13 | Tian Boguang | 33 | M | 2 | NULL |
17| 25 | Sun Dasheng | 100 | M | NULL | NULL |
18+-------+--------------+-----+--------+---------+-----------+
195 rows in set (0.00 sec)
20
21
22
23##当然,也可以从其他表查数据的
2408:37:50(root@localhost) [hellodb]> select avg(age) from teachers;
25+----------+
26| avg(age) |
27+----------+
28| 77.2500 |
29+----------+
301 row in set (0.00 sec)
31
3208:37:59(root@localhost) [hellodb]> select *from students where age > (select avg(age) from teachers);\
33+-------+-------------+-----+--------+---------+-----------+
34| StuID | Name | Age | Gender | ClassID | TeacherID |
35+-------+-------------+-----+--------+---------+-----------+
36| 25 | Sun Dasheng | 100 | M | NULL | NULL |
37+-------+-------------+-----+--------+---------+-----------+
381 row in set (0.00 sec)
39
40
41
42##错误案例演示:子查询仅能返回单个值
4308:38:00(root@localhost) [hellodb]> select *from students where age > (select name,age from teachers order by age desc limit 1);
44ERROR 1241 (21000): Operand should contain 1 column(s)
4508:39:39(root@localhost) [hellodb]> select name,age from teachers order by age desc limit 1;
46+---------------+-----+
47| name | age |
48+---------------+-----+
49| Zhang Sanfeng | 94 |
50+---------------+-----+
511 row in set (0.00 sec)
52
5308:39:44(root@localhost) [hellodb]> select *from students where age > (select name,age from teachers order by age desc limit 1);
54ERROR 1241 (21000): Operand should contain 1 column(s)
2、 用于IN中的子查询:子查询应该单独查询并返回一个或多个值重新构成列表
1SELECT Name,Age FROM students WHERE Age IN (SELECT Age FROM teachers);
范例:
108:47:03(root@localhost) [hellodb]> update students set age=45 where stuid=1;
2Query OK, 1 row affected (0.00 sec)
3Rows matched: 1 Changed: 1 Warnings: 0
4
508:47:20(root@localhost) [hellodb]> update students set age=77 where stuid=3;
6Query OK, 1 row affected (0.00 sec)
7Rows matched: 1 Changed: 1 Warnings: 0
8
908:47:25(root@localhost) [hellodb]> SELECT Name,Age FROM students WHERE Age IN (SELECT Age FROM teachers);
10+-------------+-----+
11| Name | Age |
12+-------------+-----+
13| Shi Zhongyu | 45 |
14| Xie Yanke | 77 |
15+-------------+-----+
162 rows in set (0.00 sec)
3、用于EXISTS 和 Not EXISTS
有点绕……
参考链接:https://dev.mysql.com/doc/refman/8.0/en/exists-and-not-exists-subqueries.html
EXISTS(包括 NOT EXISTS )子句的返回值是一个BOOL值。 EXISTS 内部有一个子查询语句(SELECT … FROM…), 将其称为EXIST的内查询语句。其内查询语句返回一个结果集。 EXISTS子句根据其内查询语句的结果集空或者非空,返回一个布尔值。将外查询表的每一行,代入内查询作为检验,如果内查询返回的结果为非空值,则EXISTS子句返回TRUE,外查询的这一行数据便可作为外查询的结果行返回,否则不能作为结果
1MariaDB [hellodb]> select * from students s where EXISTS (select * from teachers t where s.teacherid=t.tid);
2+-------+-------------+-----+--------+---------+-----------+
3| StuID | Name | Age | Gender | ClassID | TeacherID |
4+-------+-------------+-----+--------+---------+-----------+
5| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
6| 4 | Ding Dian | 32 | M | 4 | 4 |
7| 5 | Yu Yutong | 26 | M | 3 | 1 |
8+-------+-------------+-----+--------+---------+-----------+
9
10#说明:
111、EXISTS (或 NOT EXISTS) 用在 where之后,且后面紧跟子查询语句(带括号)
122、EXISTS (或 NOT EXISTS) 只关心子查询有没有结果,并不关心子查询的结果具体是什么
133、上述语句把students的记录逐条代入到Exists后面的子查询中,如果子查询结果集不为空,即说明存在,那么这条students的记录出现在最终结果集,否则被排除;
14
15
16MariaDB [hellodb]> select * from students s where NOT EXISTS (select * from teachers t where s.teacherid=t.tid);
17+-------+---------------+-----+--------+---------+-----------+
18| StuID | Name | Age | Gender | ClassID | TeacherID |
19+-------+---------------+-----+--------+---------+-----------+
20| 2 | Shi Potian | 22 | M | 1 | 7 |
21| 3 | Xie Yanke | 53 | M | 2 | 16 |
22| 6 | Shi Qing | 46 | M | 5 | NULL |
23| 7 | Xi Ren | 19 | F | 3 | NULL |
24| 8 | Lin Daiyu | 17 | F | 7 | NULL |
25| 9 | Ren Yingying | 20 | F | 6 | NULL |
26| 10 | Yue Lingshan | 19 | F | 3 | NULL |
27| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
28| 12 | Wen Qingqing | 19 | F | 1 | NULL |
29| 13 | Tian Boguang | 33 | M | 2 | NULL |
30| 14 | Lu Wushuang | 17 | F | 3 | NULL |
31| 15 | Duan Yu | 19 | M | 4 | NULL |
32| 16 | Xu Zhu | 21 | M | 1 | NULL |
33| 17 | Lin Chong | 25 | M | 4 | NULL |
34| 18 | Hua Rong | 23 | M | 7 | NULL |
35| 19 | Xue Baochai | 18 | F | 6 | NULL |
36| 20 | Diao Chan | 19 | F | 7 | NULL |
37| 21 | Huang Yueying | 22 | F | 6 | NULL |
38| 22 | Xiao Qiao | 20 | F | 1 | NULL |
39| 23 | Ma Chao | 23 | M | 4 | NULL |
40| 24 | Xu Xian | 27 | M | NULL | NULL |
41| 25 | Sun Dasheng | 100 | M | NULL | NULL |
42+-------+---------------+-----+--------+---------+-----------+
4322 rows in set (0.001 sec)
4、用于FROM子句中的子查询
使用格式:
1SELECT tb_alias.col1,... FROM (SELECT clause) AS tb_alias WHERE Clause;
范例:
109:19:22(root@localhost) [hellodb]> select * from students where age>30;
2+-------+--------------+-----+--------+---------+-----------+
3| StuID | Name | Age | Gender | ClassID | TeacherID |
4+-------+--------------+-----+--------+---------+-----------+
5| 1 | Shi Zhongyu | 45 | M | 2 | 3 |
6| 3 | Xie Yanke | 77 | M | 2 | 16 |
7| 4 | Ding Dian | 32 | M | 4 | 4 |
8| 6 | Shi Qing | 46 | M | 5 | NULL |
9| 13 | Tian Boguang | 33 | M | 2 | NULL |
10| 25 | Sun Dasheng | 100 | M | NULL | NULL |
11+-------+--------------+-----+--------+---------+-----------+
126 rows in set (0.00 sec)
13
1409:19:42(root@localhost) [hellodb]> select name,age from (select * from students where age>30) old_students;
15+--------------+-----+
16| name | age |
17+--------------+-----+
18| Shi Zhongyu | 45 |
19| Xie Yanke | 77 |
20| Ding Dian | 32 |
21| Shi Qing | 46 |
22| Tian Boguang | 33 |
23| Sun Dasheng | 100 |
24+--------------+-----+
256 rows in set (0.00 sec)
26
27
2809:20:32(root@localhost) [hellodb]> SELECT s.aage,s.ClassID FROM (SELECT avg(Age) AS aage,ClassID FROM students
29 -> WHERE ClassID IS NOT NULL GROUP BY ClassID) AS s WHERE s.aage>30;
30+---------+---------+
31| aage | ClassID |
32+---------+---------+
33| 51.6667 | 2 |
34| 46.0000 | 5 |
35+---------+---------+
362 rows in set (0.00 sec)
- 范例:子查询用于更新表
109:22:55(root@localhost) [hellodb]> select *from teachers;
2+-----+---------------+-----+--------+
3| TID | Name | Age | Gender |
4+-----+---------------+-----+--------+
5| 1 | Song Jiang | 45 | M |
6| 2 | Zhang Sanfeng | 94 | M |
7| 3 | Miejue Shitai | 77 | F |
8| 4 | Lin Chaoying | 93 | F |
9+-----+---------------+-----+--------+
104 rows in set (0.00 sec)
11
1209:28:10(root@localhost) [hellodb]> update teachers set age=(select avg(age) from students) where tid=4;
13Query OK, 1 row affected (0.00 sec)
14Rows matched: 1 Changed: 1 Warnings: 0
15
1609:28:57(root@localhost) [hellodb]> select *from teachers;
17+-----+---------------+-----+--------+
18| TID | Name | Age | Gender |
19+-----+---------------+-----+--------+
20| 1 | Song Jiang | 45 | M |
21| 2 | Zhang Sanfeng | 94 | M |
22| 3 | Miejue Shitai | 77 | F |
23| 4 | Lin Chaoying | 29 | F |
24+-----+---------------+-----+--------+
254 rows in set (0.00 sec)
联合查询:UNION
1SELECT Name,Age FROM students UNION SELECT Name,Age FROM teachers;
- 范例:
一般是要对应好字段数量,及字段类型,否则语法没错,但没啥实际意义。
1MariaDB [hellodb]> select *from students;
2+-------+---------------+-----+--------+---------+-----------+
3| StuID | Name | Age | Gender | ClassID | TeacherID |
4+-------+---------------+-----+--------+---------+-----------+
5| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
6| 2 | Shi Potian | 22 | M | 1 | 7 |
7| 3 | Xie Yanke | 53 | M | 2 | 16 |
8| 4 | Ding Dian | 32 | M | 4 | 4 |
9| 5 | Yu Yutong | 26 | M | 3 | 1 |
10| 6 | Shi Qing | 46 | M | 5 | NULL |
11| 7 | Xi Ren | 19 | F | 3 | NULL |
12| 8 | Lin Daiyu | 17 | F | 7 | NULL |
13| 9 | Ren Yingying | 20 | F | 6 | NULL |
14| 10 | Yue Lingshan | 19 | F | 3 | NULL |
15| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
16| 12 | Wen Qingqing | 19 | F | 1 | NULL |
17| 13 | Tian Boguang | 33 | M | 2 | NULL |
18| 14 | Lu Wushuang | 17 | F | 3 | NULL |
19| 15 | Duan Yu | 19 | M | 4 | NULL |
20| 16 | Xu Zhu | 21 | M | 1 | NULL |
21| 17 | Lin Chong | 25 | M | 4 | NULL |
22| 18 | Hua Rong | 23 | M | 7 | NULL |
23| 19 | Xue Baochai | 18 | F | 6 | NULL |
24| 20 | Diao Chan | 19 | F | 7 | NULL |
25| 21 | Huang Yueying | 22 | F | 6 | NULL |
26| 22 | Xiao Qiao | 20 | F | 1 | NULL |
27| 23 | Ma Chao | 23 | M | 4 | NULL |
28| 24 | Xu Xian | 27 | M | NULL | NULL |
29| 25 | Sun Dasheng | 100 | M | NULL | NULL |
30+-------+---------------+-----+--------+---------+-----------+
3125 rows in set (0.00 sec)
32
33MariaDB [hellodb]> select *from teachers;
34+-----+---------------+-----+--------+
35| TID | Name | Age | Gender |
36+-----+---------------+-----+--------+
37| 1 | Song Jiang | 45 | M |
38| 2 | Zhang Sanfeng | 94 | M |
39| 3 | Miejue Shitai | 77 | F |
40| 4 | Lin Chaoying | 93 | F |
41+-----+---------------+-----+--------+
424 rows in set (0.00 sec)
43
44
45
46MariaDB [hellodb]> select *from teachers union select stuid,name,age,gender from students;
47+-----+---------------+-----+--------+
48| TID | Name | Age | Gender |
49+-----+---------------+-----+--------+
50| 1 | Song Jiang | 45 | M |
51| 2 | Zhang Sanfeng | 94 | M |
52| 3 | Miejue Shitai | 77 | F |
53| 4 | Lin Chaoying | 93 | F |
54| 1 | Shi Zhongyu | 22 | M |
55| 2 | Shi Potian | 22 | M |
56| 3 | Xie Yanke | 53 | M |
57| 4 | Ding Dian | 32 | M |
58| 5 | Yu Yutong | 26 | M |
59| 6 | Shi Qing | 46 | M |
60| 7 | Xi Ren | 19 | F |
61| 8 | Lin Daiyu | 17 | F |
62| 9 | Ren Yingying | 20 | F |
63| 10 | Yue Lingshan | 19 | F |
64| 11 | Yuan Chengzhi | 23 | M |
65| 12 | Wen Qingqing | 19 | F |
66| 13 | Tian Boguang | 33 | M |
67| 14 | Lu Wushuang | 17 | F |
68| 15 | Duan Yu | 19 | M |
69| 16 | Xu Zhu | 21 | M |
70| 17 | Lin Chong | 25 | M |
71| 18 | Hua Rong | 23 | M |
72| 19 | Xue Baochai | 18 | F |
73| 20 | Diao Chan | 19 | F |
74| 21 | Huang Yueying | 22 | F |
75| 22 | Xiao Qiao | 20 | F |
76| 23 | Ma Chao | 23 | M |
77| 24 | Xu Xian | 27 | M |
78| 25 | Sun Dasheng | 100 | M |
79+-----+---------------+-----+--------+
8029 rows in set (0.00 sec)
81
82
83
84##没啥实际意义……
85MariaDB [hellodb]> select *from teachers union select name,stuid,age,gender from students;
86+---------------+---------------+-----+--------+
87| TID | Name | Age | Gender |
88+---------------+---------------+-----+--------+
89| 1 | Song Jiang | 45 | M |
90| 2 | Zhang Sanfeng | 94 | M |
91| 3 | Miejue Shitai | 77 | F |
92| 4 | Lin Chaoying | 93 | F |
93| Shi Zhongyu | 1 | 22 | M |
94| Shi Potian | 2 | 22 | M |
95| Xie Yanke | 3 | 53 | M |
96| Ding Dian | 4 | 32 | M |
97| Yu Yutong | 5 | 26 | M |
98| Shi Qing | 6 | 46 | M |
99| Xi Ren | 7 | 19 | F |
100| Lin Daiyu | 8 | 17 | F |
101| Ren Yingying | 9 | 20 | F |
102| Yue Lingshan | 10 | 19 | F |
103| Yuan Chengzhi | 11 | 23 | M |
104| Wen Qingqing | 12 | 19 | F |
105| Tian Boguang | 13 | 33 | M |
106| Lu Wushuang | 14 | 17 | F |
107| Duan Yu | 15 | 19 | M |
108| Xu Zhu | 16 | 21 | M |
109| Lin Chong | 17 | 25 | M |
110| Hua Rong | 18 | 23 | M |
111| Xue Baochai | 19 | 18 | F |
112| Diao Chan | 20 | 19 | F |
113| Huang Yueying | 21 | 22 | F |
114| Xiao Qiao | 22 | 20 | F |
115| Ma Chao | 23 | 23 | M |
116| Xu Xian | 24 | 27 | M |
117| Sun Dasheng | 25 | 100 | M |
118+---------------+---------------+-----+--------+
11929 rows in set (0.00 sec)
120
121MariaDB [hellodb]>
- 范例:2个表union会产生什么问题?(去重)
1##创建新表
2MariaDB [hellodb]> create table teachers2 select *from teachers;
3Query OK, 4 rows affected (0.00 sec)
4Records: 4 Duplicates: 0 Warnings: 0
5
6MariaDB [hellodb]> select *from teachers2;
7+-----+---------------+-----+--------+
8| TID | Name | Age | Gender |
9+-----+---------------+-----+--------+
10| 1 | Song Jiang | 45 | M |
11| 2 | Zhang Sanfeng | 94 | M |
12| 3 | Miejue Shitai | 77 | F |
13| 4 | Lin Chaoying | 93 | F |
14+-----+---------------+-----+--------+
154 rows in set (0.00 sec)
16
17##修改2个字段
18MariaDB [hellodb]> update teachers2 set name='mage' where tid=1;
19Query OK, 1 row affected (0.01 sec)
20Rows matched: 1 Changed: 1 Warnings: 0
21
22MariaDB [hellodb]> update teachers2 set name='wang' where tid=2;
23Query OK, 1 row affected (0.00 sec)
24Rows matched: 1 Changed: 1 Warnings: 0
25
26
27##查询
28MariaDB [hellodb]> select *from teachers2;
29+-----+---------------+-----+--------+
30| TID | Name | Age | Gender |
31+-----+---------------+-----+--------+
32| 1 | mage | 45 | M |
33| 2 | wang | 94 | M |
34| 3 | Miejue Shitai | 77 | F |
35| 4 | Lin Chaoying | 93 | F |
36+-----+---------------+-----+--------+
374 rows in set (0.00 sec)
38
39
40#union操作
41MariaDB [hellodb]> selec
42+-----+---------------+-
43| TID | Name |
44+-----+---------------+-
45| 1 | mage |
46| 2 | wang |
47| 3 | Miejue Shitai |
48| 4 | Lin Chaoying |
49| 1 | Song Jiang |
50| 2 | Zhang Sanfeng |
51+-----+---------------+-
526 rows in set (0.01 sec)
53##可以看到,用这种小技巧也可以实现简单的去重操作;
54
55
56
57##那如何去重呢?
58MariaDB [hellodb]> create table teachers3 select *from teachers2 union select *from teachers;
59Query OK, 6 rows affected (0.01 sec)
60Records: 6 Duplicates: 0 Warnings: 0
61
62MariaDB [hellodb]> select *from teachers3;
63+-----+---------------+-----+--------+
64| TID | Name | Age | Gender |
65+-----+---------------+-----+--------+
66| 1 | mage | 45 | M |
67| 2 | wang | 94 | M |
68| 3 | Miejue Shitai | 77 | F |
69| 4 | Lin Chaoying | 93 | F |
70| 1 | Song Jiang | 45 | M |
71| 2 | Zhang Sanfeng | 94 | M |
72+-----+---------------+-----+--------+
736 rows in set (0.00 sec)
- 范例:能不能不去重呢?
1MariaDB [hellodb]> select *from teachers2 union all select *from teachers;
2+-----+---------------+-----+--------+
3| TID | Name | Age | Gender |
4+-----+---------------+-----+--------+
5| 1 | mage | 45 | M |
6| 2 | wang | 94 | M |
7| 3 | Miejue Shitai | 77 | F |
8| 4 | Lin Chaoying | 93 | F |
9| 1 | Song Jiang | 45 | M |
10| 2 | Zhang Sanfeng | 94 | M |
11| 3 | Miejue Shitai | 77 | F |
12| 4 | Lin Chaoying | 93 | F |
13+-----+---------------+-----+--------+
148 rows in set (0.00 sec)
- 范例:3个语句的union
1MariaDB [hellodb]> select *from teachers2 union all select *from teachers union select stuid,name,age,gender from students;
2+-----+---------------+-----+--------+
3| TID | Name | Age | Gender |
4+-----+---------------+-----+--------+
5| 1 | mage | 45 | M |
6| 2 | wang | 94 | M |
7| 3 | Miejue Shitai | 77 | F |
8| 4 | Lin Chaoying | 93 | F |
9| 1 | Song Jiang | 45 | M |
10| 2 | Zhang Sanfeng | 94 | M |
11| 1 | Shi Zhongyu | 22 | M |
12| 2 | Shi Potian | 22 | M |
13| 3 | Xie Yanke | 53 | M |
14| 4 | Ding Dian | 32 | M |
15| 5 | Yu Yutong | 26 | M |
16| 6 | Shi Qing | 46 | M |
17| 7 | Xi Ren | 19 | F |
18| 8 | Lin Daiyu | 17 | F |
19| 9 | Ren Yingying | 20 | F |
20| 10 | Yue Lingshan | 19 | F |
21| 11 | Yuan Chengzhi | 23 | M |
22| 12 | Wen Qingqing | 19 | F |
23| 13 | Tian Boguang | 33 | M |
24| 14 | Lu Wushuang | 17 | F |
25| 15 | Duan Yu | 19 | M |
26| 16 | Xu Zhu | 21 | M |
27| 17 | Lin Chong | 25 | M |
28| 18 | Hua Rong | 23 | M |
29| 19 | Xue Baochai | 18 | F |
30| 20 | Diao Chan | 19 | F |
31| 21 | Huang Yueying | 22 | F |
32| 22 | Xiao Qiao | 20 | F |
33| 23 | Ma Chao | 23 | M |
34| 24 | Xu Xian | 27 | M |
35| 25 | Sun Dasheng | 100 | M |
36+-----+---------------+-----+--------+
3731 rows in set (0.00 sec)
交叉连接
2张表横向连接,交叉组合。
即笛卡尔乘积,“雨露均沾”,利用 cross join实现
交叉连接通常结果意义不是很大,用的场景不是很多。它还有一个巨大的缺点,两张表明明是小表,但合并后却成为一个巨大的表。所以,cross join在生产里尽可能不要去执行。
- 范例:交叉连接
1 select * from students cross join teachers;
1MariaDB [hellodb]> select *from students;
2+-------+---------------+-----+--------+---------+-----------+
3| StuID | Name | Age | Gender | ClassID | TeacherID |
4+-------+---------------+-----+--------+---------+-----------+
5| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
6| 2 | Shi Potian | 22 | M | 1 | 7 |
7| 3 | Xie Yanke | 53 | M | 2 | 16 |
8| 4 | Ding Dian | 32 | M | 4 | 4 |
9| 5 | Yu Yutong | 26 | M | 3 | 1 |
10| 6 | Shi Qing | 46 | M | 5 | NULL |
11| 7 | Xi Ren | 19 | F | 3 | NULL |
12| 8 | Lin Daiyu | 17 | F | 7 | NULL |
13| 9 | Ren Yingying | 20 | F | 6 | NULL |
14| 10 | Yue Lingshan | 19 | F | 3 | NULL |
15| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
16| 12 | Wen Qingqing | 19 | F | 1 | NULL |
17| 13 | Tian Boguang | 33 | M | 2 | NULL |
18| 14 | Lu Wushuang | 17 | F | 3 | NULL |
19| 15 | Duan Yu | 19 | M | 4 | NULL |
20| 16 | Xu Zhu | 21 | M | 1 | NULL |
21| 17 | Lin Chong | 25 | M | 4 | NULL |
22| 18 | Hua Rong | 23 | M | 7 | NULL |
23| 19 | Xue Baochai | 18 | F | 6 | NULL |
24| 20 | Diao Chan | 19 | F | 7 | NULL |
25| 21 | Huang Yueying | 22 | F | 6 | NULL |
26| 22 | Xiao Qiao | 20 | F | 1 | NULL |
27| 23 | Ma Chao | 23 | M | 4 | NULL |
28| 24 | Xu Xian | 27 | M | NULL | NULL |
29| 25 | Sun Dasheng | 100 | M | NULL | NULL |
30+-------+---------------+-----+--------+---------+-----------+
3125 rows in set (0.00 sec)
32
33MariaDB [hellodb]> select *from teachers;
34+-----+---------------+-----+--------+
35| TID | Name | Age | Gender |
36+-----+---------------+-----+--------+
37| 1 | Song Jiang | 45 | M |
38| 2 | Zhang Sanfeng | 94 | M |
39| 3 | Miejue Shitai | 77 | F |
40| 4 | Lin Chaoying | 93 | F |
41+-----+---------------+-----+--------+
424 rows in set (0.01 sec)
43
44
45
46#会产生4+6=10列数据,25*4=100行数据
47MariaDB [hellodb]> select *from students cross join teachers;
48+-------+---------------+-----+--------+---------+-----------+-----+---------------+-----+--------+
49| StuID | Name | Age | Gender | ClassID | TeacherID | TID | Name | Age | Gender |
50+-------+---------------+-----+--------+---------+-----------+-----+---------------+-----+--------+
51| 1 | Shi Zhongyu | 22 | M | 2 | 3 | 1 | Song Jiang | 45 | M |
52| 1 | Shi Zhongyu | 22 | M | 2 | 3 | 2 | Zhang Sanfeng | 94 | M |
53| 1 | Shi Zhongyu | 22 | M | 2 | 3 | 3 | Miejue Shitai | 77 | F |
54| 1 | Shi Zhongyu | 22 | M | 2 | 3 | 4 | Lin Chaoying | 93 | F |
55| 2 | Shi Potian | 22 | M | 1 | 7 | 1 | Song Jiang | 45 | M |
56| 2 | Shi Potian | 22 | M | 1 | 7 | 2 | Zhang Sanfeng | 94 | M |
57| 2 | Shi Potian | 22 | M | 1 | 7 | 3 | Miejue Shitai | 77 | F |
58| 2 | Shi Potian | 22 | M | 1 | 7 | 4 | Lin Chaoying | 93 | F |
59| 3 | Xie Yanke | 53 | M | 2 | 16 | 1 | Song Jiang | 45 | M |
60| 3 | Xie Yanke | 53 | M | 2 | 16 | 2 | Zhang Sanfeng | 94 | M |
61| 3 | Xie Yanke | 53 | M | 2 | 16 | 3 | Miejue Shitai | 77 | F |
62| 3 | Xie Yanke | 53 | M | 2 | 16 | 4 | Lin Chaoying | 93 | F |
63| 4 | Ding Dian | 32 | M | 4 | 4 | 1 | Song Jiang | 45 | M |
64| 4 | Ding Dian | 32 | M | 4 | 4 | 2 | Zhang Sanfeng | 94 | M |
65| 4 | Ding Dian | 32 | M | 4 | 4 | 3 | Miejue Shitai | 77 | F |
66| 4 | Ding Dian | 32 | M | 4 | 4 | 4 | Lin Chaoying | 93 | F |
67| 5 | Yu Yutong | 26 | M | 3 | 1 | 1 | Song Jiang | 45 | M |
68| 5 | Yu Yutong | 26 | M | 3 | 1 | 2 | Zhang Sanfeng | 94 | M |
69| 5 | Yu Yutong | 26 | M | 3 | 1 | 3 | Miejue Shitai | 77 | F |
70| 5 | Yu Yutong | 26 | M | 3 | 1 | 4 | Lin Chaoying | 93 | F |
71| 6 | Shi Qing | 46 | M | 5 | NULL | 1 | Song Jiang | 45 | M |
72| 6 | Shi Qing | 46 | M | 5 | NULL | 2 | Zhang Sanfeng | 94 | M |
73| 6 | Shi Qing | 46 | M | 5 | NULL | 3 | Miejue Shitai | 77 | F |
74| 6 | Shi Qing | 46 | M | 5 | NULL | 4 | Lin Chaoying | 93 | F |
75| 7 | Xi Ren | 19 | F | 3 | NULL | 1 | Song Jiang | 45 | M |
76| 7 | Xi Ren | 19 | F | 3 | NULL | 2 | Zhang Sanfeng | 94 | M |
77| 7 | Xi Ren | 19 | F | 3 | NULL | 3 | Miejue Shitai | 77 | F |
78| 7 | Xi Ren | 19 | F | 3 | NULL | 4 | Lin Chaoying | 93 | F |
79| 8 | Lin Daiyu | 17 | F | 7 | NULL | 1 | Song Jiang | 45 | M |
80| 8 | Lin Daiyu | 17 | F | 7 | NULL | 2 | Zhang Sanfeng | 94 | M |
81| 8 | Lin Daiyu | 17 | F | 7 | NULL | 3 | Miejue Shitai | 77 | F |
82| 8 | Lin Daiyu | 17 | F | 7 | NULL | 4 | Lin Chaoying | 93 | F |
83| 9 | Ren Yingying | 20 | F | 6 | NULL | 1 | Song Jiang | 45 | M |
84| 9 | Ren Yingying | 20 | F | 6 | NULL | 2 | Zhang Sanfeng | 94 | M |
85| 9 | Ren Yingying | 20 | F | 6 | NULL | 3 | Miejue Shitai | 77 | F |
86| 9 | Ren Yingying | 20 | F | 6 | NULL | 4 | Lin Chaoying | 93 | F |
87| 10 | Yue Lingshan | 19 | F | 3 | NULL | 1 | Song Jiang | 45 | M |
88| 10 | Yue Lingshan | 19 | F | 3 | NULL | 2 | Zhang Sanfeng | 94 | M |
89| 10 | Yue Lingshan | 19 | F | 3 | NULL | 3 | Miejue Shitai | 77 | F |
90| 10 | Yue Lingshan | 19 | F | 3 | NULL | 4 | Lin Chaoying | 93 | F |
91| 11 | Yuan Chengzhi | 23 | M | 6 | NULL | 1 | Song Jiang | 45 | M |
92| 11 | Yuan Chengzhi | 23 | M | 6 | NULL | 2 | Zhang Sanfeng | 94 | M |
93| 11 | Yuan Chengzhi | 23 | M | 6 | NULL | 3 | Miejue Shitai | 77 | F |
94| 11 | Yuan Chengzhi | 23 | M | 6 | NULL | 4 | Lin Chaoying | 93 | F |
95| 12 | Wen Qingqing | 19 | F | 1 | NULL | 1 | Song Jiang | 45 | M |
96| 12 | Wen Qingqing | 19 | F | 1 | NULL | 2 | Zhang Sanfeng | 94 | M |
97| 12 | Wen Qingqing | 19 | F | 1 | NULL | 3 | Miejue Shitai | 77 | F |
98| 12 | Wen Qingqing | 19 | F | 1 | NULL | 4 | Lin Chaoying | 93 | F |
99| 13 | Tian Boguang | 33 | M | 2 | NULL | 1 | Song Jiang | 45 | M |
100| 13 | Tian Boguang | 33 | M | 2 | NULL | 2 | Zhang Sanfeng | 94 | M |
101| 13 | Tian Boguang | 33 | M | 2 | NULL | 3 | Miejue Shitai | 77 | F |
102| 13 | Tian Boguang | 33 | M | 2 | NULL | 4 | Lin Chaoying | 93 | F |
103| 14 | Lu Wushuang | 17 | F | 3 | NULL | 1 | Song Jiang | 45 | M |
104| 14 | Lu Wushuang | 17 | F | 3 | NULL | 2 | Zhang Sanfeng | 94 | M |
105| 14 | Lu Wushuang | 17 | F | 3 | NULL | 3 | Miejue Shitai | 77 | F |
106| 14 | Lu Wushuang | 17 | F | 3 | NULL | 4 | Lin Chaoying | 93 | F |
107| 15 | Duan Yu | 19 | M | 4 | NULL | 1 | Song Jiang | 45 | M |
108| 15 | Duan Yu | 19 | M | 4 | NULL | 2 | Zhang Sanfeng | 94 | M |
109| 15 | Duan Yu | 19 | M | 4 | NULL | 3 | Miejue Shitai | 77 | F |
110| 15 | Duan Yu | 19 | M | 4 | NULL | 4 | Lin Chaoying | 93 | F |
111| 16 | Xu Zhu | 21 | M | 1 | NULL | 1 | Song Jiang | 45 | M |
112| 16 | Xu Zhu | 21 | M | 1 | NULL | 2 | Zhang Sanfeng | 94 | M |
113| 16 | Xu Zhu | 21 | M | 1 | NULL | 3 | Miejue Shitai | 77 | F |
114| 16 | Xu Zhu | 21 | M | 1 | NULL | 4 | Lin Chaoying | 93 | F |
115| 17 | Lin Chong | 25 | M | 4 | NULL | 1 | Song Jiang | 45 | M |
116| 17 | Lin Chong | 25 | M | 4 | NULL | 2 | Zhang Sanfeng | 94 | M |
117| 17 | Lin Chong | 25 | M | 4 | NULL | 3 | Miejue Shitai | 77 | F |
118| 17 | Lin Chong | 25 | M | 4 | NULL | 4 | Lin Chaoying | 93 | F |
119| 18 | Hua Rong | 23 | M | 7 | NULL | 1 | Song Jiang | 45 | M |
120| 18 | Hua Rong | 23 | M | 7 | NULL | 2 | Zhang Sanfeng | 94 | M |
121| 18 | Hua Rong | 23 | M | 7 | NULL | 3 | Miejue Shitai | 77 | F |
122| 18 | Hua Rong | 23 | M | 7 | NULL | 4 | Lin Chaoying | 93 | F |
123| 19 | Xue Baochai | 18 | F | 6 | NULL | 1 | Song Jiang | 45 | M |
124| 19 | Xue Baochai | 18 | F | 6 | NULL | 2 | Zhang Sanfeng | 94 | M |
125| 19 | Xue Baochai | 18 | F | 6 | NULL | 3 | Miejue Shitai | 77 | F |
126| 19 | Xue Baochai | 18 | F | 6 | NULL | 4 | Lin Chaoying | 93 | F |
127| 20 | Diao Chan | 19 | F | 7 | NULL | 1 | Song Jiang | 45 | M |
128| 20 | Diao Chan | 19 | F | 7 | NULL | 2 | Zhang Sanfeng | 94 | M |
129| 20 | Diao Chan | 19 | F | 7 | NULL | 3 | Miejue Shitai | 77 | F |
130| 20 | Diao Chan | 19 | F | 7 | NULL | 4 | Lin Chaoying | 93 | F |
131| 21 | Huang Yueying | 22 | F | 6 | NULL | 1 | Song Jiang | 45 | M |
132| 21 | Huang Yueying | 22 | F | 6 | NULL | 2 | Zhang Sanfeng | 94 | M |
133| 21 | Huang Yueying | 22 | F | 6 | NULL | 3 | Miejue Shitai | 77 | F |
134| 21 | Huang Yueying | 22 | F | 6 | NULL | 4 | Lin Chaoying | 93 | F |
135| 22 | Xiao Qiao | 20 | F | 1 | NULL | 1 | Song Jiang | 45 | M |
136| 22 | Xiao Qiao | 20 | F | 1 | NULL | 2 | Zhang Sanfeng | 94 | M |
137| 22 | Xiao Qiao | 20 | F | 1 | NULL | 3 | Miejue Shitai | 77 | F |
138| 22 | Xiao Qiao | 20 | F | 1 | NULL | 4 | Lin Chaoying | 93 | F |
139| 23 | Ma Chao | 23 | M | 4 | NULL | 1 | Song Jiang | 45 | M |
140| 23 | Ma Chao | 23 | M | 4 | NULL | 2 | Zhang Sanfeng | 94 | M |
141| 23 | Ma Chao | 23 | M | 4 | NULL | 3 | Miejue Shitai | 77 | F |
142| 23 | Ma Chao | 23 | M | 4 | NULL | 4 | Lin Chaoying | 93 | F |
143| 24 | Xu Xian | 27 | M | NULL | NULL | 1 | Song Jiang | 45 | M |
144| 24 | Xu Xian | 27 | M | NULL | NULL | 2 | Zhang Sanfeng | 94 | M |
145| 24 | Xu Xian | 27 | M | NULL | NULL | 3 | Miejue Shitai | 77 | F |
146| 24 | Xu Xian | 27 | M | NULL | NULL | 4 | Lin Chaoying | 93 | F |
147| 25 | Sun Dasheng | 100 | M | NULL | NULL | 1 | Song Jiang | 45 | M |
148| 25 | Sun Dasheng | 100 | M | NULL | NULL | 2 | Zhang Sanfeng | 94 | M |
149| 25 | Sun Dasheng | 100 | M | NULL | NULL | 3 | Miejue Shitai | 77 | F |
150| 25 | Sun Dasheng | 100 | M | NULL | NULL | 4 | Lin Chaoying | 93 | F |
151+-------+---------------+-----+--------+---------+-----------+-----+---------------+-----+--------+
152100 rows in set (0.01 sec)
153
154
155
156##报错:2张表里都有name字段,所以报错了
157MariaDB [hellodb]> select stuid,name,age,tid,name,age from students cross join teachers;
158ERROR 1052 (23000): Column 'name' in field list is ambiguous
159
160
161##
162MariaDB [hellodb]> select stuid,students.name,students.age,tid,teachers.name,teachers.age from students cross join teachers;
163##这里给表起个别名,更简洁。
164MariaDB [hellodb]> select stuid,s.name,s.age,tid,t.name,t.age from students s cross join teachers t;
165+-------+---------------+-----+-----+---------------+-----+
166| stuid | name | age | tid | name | age |
167+-------+---------------+-----+-----+---------------+-----+
168| 1 | Shi Zhongyu | 22 | 1 | Song Jiang | 45 |
169| 1 | Shi Zhongyu | 22 | 2 | Zhang Sanfeng | 94 |
170| 1 | Shi Zhongyu | 22 | 3 | Miejue Shitai | 77 |
171| 1 | Shi Zhongyu | 22 | 4 | Lin Chaoying | 93 |
172| 2 | Shi Potian | 22 | 1 | Song Jiang | 45 |
173| 2 | Shi Potian | 22 | 2 | Zhang Sanfeng | 94 |
174| 2 | Shi Potian | 22 | 3 | Miejue Shitai | 77 |
175| 2 | Shi Potian | 22 | 4 | Lin Chaoying | 93 |
176| 3 | Xie Yanke | 53 | 1 | Song Jiang | 45 |
177| 3 | Xie Yanke | 53 | 2 | Zhang Sanfeng | 94 |
178| 3 | Xie Yanke | 53 | 3 | Miejue Shitai | 77 |
179| 3 | Xie Yanke | 53 | 4 | Lin Chaoying | 93 |
180| 4 | Ding Dian | 32 | 1 | Song Jiang | 45 |
181| 4 | Ding Dian | 32 | 2 | Zhang Sanfeng | 94 |
182| 4 | Ding Dian | 32 | 3 | Miejue Shitai | 77 |
183| 4 | Ding Dian | 32 | 4 | Lin Chaoying | 93 |
184| 5 | Yu Yutong | 26 | 1 | Song Jiang | 45 |
185| 5 | Yu Yutong | 26 | 2 | Zhang Sanfeng | 94 |
186| 5 | Yu Yutong | 26 | 3 | Miejue Shitai | 77 |
187| 5 | Yu Yutong | 26 | 4 | Lin Chaoying | 93 |
188| 6 | Shi Qing | 46 | 1 | Song Jiang | 45 |
189| 6 | Shi Qing | 46 | 2 | Zhang Sanfeng | 94 |
190| 6 | Shi Qing | 46 | 3 | Miejue Shitai | 77 |
191| 6 | Shi Qing | 46 | 4 | Lin Chaoying | 93 |
192| 7 | Xi Ren | 19 | 1 | Song Jiang | 45 |
193| 7 | Xi Ren | 19 | 2 | Zhang Sanfeng | 94 |
194| 7 | Xi Ren | 19 | 3 | Miejue Shitai | 77 |
195| 7 | Xi Ren | 19 | 4 | Lin Chaoying | 93 |
196| 8 | Lin Daiyu | 17 | 1 | Song Jiang | 45 |
197| 8 | Lin Daiyu | 17 | 2 | Zhang Sanfeng | 94 |
198| 8 | Lin Daiyu | 17 | 3 | Miejue Shitai | 77 |
199| 8 | Lin Daiyu | 17 | 4 | Lin Chaoying | 93 |
200| 9 | Ren Yingying | 20 | 1 | Song Jiang | 45 |
201| 9 | Ren Yingying | 20 | 2 | Zhang Sanfeng | 94 |
202| 9 | Ren Yingying | 20 | 3 | Miejue Shitai | 77 |
203| 9 | Ren Yingying | 20 | 4 | Lin Chaoying | 93 |
204| 10 | Yue Lingshan | 19 | 1 | Song Jiang | 45 |
205| 10 | Yue Lingshan | 19 | 2 | Zhang Sanfeng | 94 |
206| 10 | Yue Lingshan | 19 | 3 | Miejue Shitai | 77 |
207| 10 | Yue Lingshan | 19 | 4 | Lin Chaoying | 93 |
208| 11 | Yuan Chengzhi | 23 | 1 | Song Jiang | 45 |
209| 11 | Yuan Chengzhi | 23 | 2 | Zhang Sanfeng | 94 |
210| 11 | Yuan Chengzhi | 23 | 3 | Miejue Shitai | 77 |
211| 11 | Yuan Chengzhi | 23 | 4 | Lin Chaoying | 93 |
212| 12 | Wen Qingqing | 19 | 1 | Song Jiang | 45 |
213| 12 | Wen Qingqing | 19 | 2 | Zhang Sanfeng | 94 |
214| 12 | Wen Qingqing | 19 | 3 | Miejue Shitai | 77 |
215| 12 | Wen Qingqing | 19 | 4 | Lin Chaoying | 93 |
216| 13 | Tian Boguang | 33 | 1 | Song Jiang | 45 |
217| 13 | Tian Boguang | 33 | 2 | Zhang Sanfeng | 94 |
218| 13 | Tian Boguang | 33 | 3 | Miejue Shitai | 77 |
219| 13 | Tian Boguang | 33 | 4 | Lin Chaoying | 93 |
220| 14 | Lu Wushuang | 17 | 1 | Song Jiang | 45 |
221| 14 | Lu Wushuang | 17 | 2 | Zhang Sanfeng | 94 |
222| 14 | Lu Wushuang | 17 | 3 | Miejue Shitai | 77 |
223| 14 | Lu Wushuang | 17 | 4 | Lin Chaoying | 93 |
224| 15 | Duan Yu | 19 | 1 | Song Jiang | 45 |
225| 15 | Duan Yu | 19 | 2 | Zhang Sanfeng | 94 |
226| 15 | Duan Yu | 19 | 3 | Miejue Shitai | 77 |
227| 15 | Duan Yu | 19 | 4 | Lin Chaoying | 93 |
228| 16 | Xu Zhu | 21 | 1 | Song Jiang | 45 |
229| 16 | Xu Zhu | 21 | 2 | Zhang Sanfeng | 94 |
230| 16 | Xu Zhu | 21 | 3 | Miejue Shitai | 77 |
231| 16 | Xu Zhu | 21 | 4 | Lin Chaoying | 93 |
232| 17 | Lin Chong | 25 | 1 | Song Jiang | 45 |
233| 17 | Lin Chong | 25 | 2 | Zhang Sanfeng | 94 |
234| 17 | Lin Chong | 25 | 3 | Miejue Shitai | 77 |
235| 17 | Lin Chong | 25 | 4 | Lin Chaoying | 93 |
236| 18 | Hua Rong | 23 | 1 | Song Jiang | 45 |
237| 18 | Hua Rong | 23 | 2 | Zhang Sanfeng | 94 |
238| 18 | Hua Rong | 23 | 3 | Miejue Shitai | 77 |
239| 18 | Hua Rong | 23 | 4 | Lin Chaoying | 93 |
240| 19 | Xue Baochai | 18 | 1 | Song Jiang | 45 |
241| 19 | Xue Baochai | 18 | 2 | Zhang Sanfeng | 94 |
242| 19 | Xue Baochai | 18 | 3 | Miejue Shitai | 77 |
243| 19 | Xue Baochai | 18 | 4 | Lin Chaoying | 93 |
244| 20 | Diao Chan | 19 | 1 | Song Jiang | 45 |
245| 20 | Diao Chan | 19 | 2 | Zhang Sanfeng | 94 |
246| 20 | Diao Chan | 19 | 3 | Miejue Shitai | 77 |
247| 20 | Diao Chan | 19 | 4 | Lin Chaoying | 93 |
248| 21 | Huang Yueying | 22 | 1 | Song Jiang | 45 |
249| 21 | Huang Yueying | 22 | 2 | Zhang Sanfeng | 94 |
250| 21 | Huang Yueying | 22 | 3 | Miejue Shitai | 77 |
251| 21 | Huang Yueying | 22 | 4 | Lin Chaoying | 93 |
252| 22 | Xiao Qiao | 20 | 1 | Song Jiang | 45 |
253| 22 | Xiao Qiao | 20 | 2 | Zhang Sanfeng | 94 |
254| 22 | Xiao Qiao | 20 | 3 | Miejue Shitai | 77 |
255| 22 | Xiao Qiao | 20 | 4 | Lin Chaoying | 93 |
256| 23 | Ma Chao | 23 | 1 | Song Jiang | 45 |
257| 23 | Ma Chao | 23 | 2 | Zhang Sanfeng | 94 |
258| 23 | Ma Chao | 23 | 3 | Miejue Shitai | 77 |
259| 23 | Ma Chao | 23 | 4 | Lin Chaoying | 93 |
260| 24 | Xu Xian | 27 | 1 | Song Jiang | 45 |
261| 24 | Xu Xian | 27 | 2 | Zhang Sanfeng | 94 |
262| 24 | Xu Xian | 27 | 3 | Miejue Shitai | 77 |
263| 24 | Xu Xian | 27 | 4 | Lin Chaoying | 93 |
264| 25 | Sun Dasheng | 100 | 1 | Song Jiang | 45 |
265| 25 | Sun Dasheng | 100 | 2 | Zhang Sanfeng | 94 |
266| 25 | Sun Dasheng | 100 | 3 | Miejue Shitai | 77 |
267| 25 | Sun Dasheng | 100 | 4 | Lin Chaoying | 93 |
268+-------+---------------+-----+-----+---------------+-----+
269100 rows in set (0.00 sec)
270
271
272##再次修改:
273MariaDB [hellodb]> select stuid,s.name 学生姓名,s.age 学生年龄,tid,t.name 老师姓名,t.age 老师年龄 from students s cross join teachers t;
274+-------+---------------+--------------+-----+---------------+--------------+
275| stuid | 学生姓名 | 学生年龄 | tid | 老师姓名 | 老师年龄 |
276+-------+---------------+--------------+-----+---------------+--------------+
277| 1 | Shi Zhongyu | 22 | 1 | Song Jiang | 45 |
278| 1 | Shi Zhongyu | 22 | 2 | Zhang Sanfeng | 94 |
279| 1 | Shi Zhongyu | 22 | 3 | Miejue Shitai | 77 |
280| 1 | Shi Zhongyu | 22 | 4 | Lin Chaoying | 93 |
281| 2 | Shi Potian | 22 | 1 | Song Jiang | 45 |
282| 2 | Shi Potian | 22 | 2 | Zhang Sanfeng | 94 |
283| 2 | Shi Potian | 22 | 3 | Miejue Shitai | 77 |
284| 2 | Shi Potian | 22 | 4 | Lin Chaoying | 93 |
285| 3 | Xie Yanke | 53 | 1 | Song Jiang | 45 |
286| 3 | Xie Yanke | 53 | 2 | Zhang Sanfeng | 94 |
287| 3 | Xie Yanke | 53 | 3 | Miejue Shitai | 77 |
288| 3 | Xie Yanke | 53 | 4 | Lin Chaoying | 93 |
289| 4 | Ding Dian | 32 | 1 | Song Jiang | 45 |
290| 4 | Ding Dian | 32 | 2 | Zhang Sanfeng | 94 |
291| 4 | Ding Dian | 32 | 3 | Miejue Shitai | 77 |
292| 4 | Ding Dian | 32 | 4 | Lin Chaoying | 93 |
293| 5 | Yu Yutong | 26 | 1 | Song Jiang | 45 |
294| 5 | Yu Yutong | 26 | 2 | Zhang Sanfeng | 94 |
295| 5 | Yu Yutong | 26 | 3 | Miejue Shitai | 77 |
296| 5 | Yu Yutong | 26 | 4 | Lin Chaoying | 93 |
297| 6 | Shi Qing | 46 | 1 | Song Jiang | 45 |
298| 6 | Shi Qing | 46 | 2 | Zhang Sanfeng | 94 |
299| 6 | Shi Qing | 46 | 3 | Miejue Shitai | 77 |
300| 6 | Shi Qing | 46 | 4 | Lin Chaoying | 93 |
301| 7 | Xi Ren | 19 | 1 | Song Jiang | 45 |
302| 7 | Xi Ren | 19 | 2 | Zhang Sanfeng | 94 |
303| 7 | Xi Ren | 19 | 3 | Miejue Shitai | 77 |
304| 7 | Xi Ren | 19 | 4 | Lin Chaoying | 93 |
305| 8 | Lin Daiyu | 17 | 1 | Song Jiang | 45 |
306| 8 | Lin Daiyu | 17 | 2 | Zhang Sanfeng | 94 |
307| 8 | Lin Daiyu | 17 | 3 | Miejue Shitai | 77 |
308| 8 | Lin Daiyu | 17 | 4 | Lin Chaoying | 93 |
309| 9 | Ren Yingying | 20 | 1 | Song Jiang | 45 |
310| 9 | Ren Yingying | 20 | 2 | Zhang Sanfeng | 94 |
311| 9 | Ren Yingying | 20 | 3 | Miejue Shitai | 77 |
312| 9 | Ren Yingying | 20 | 4 | Lin Chaoying | 93 |
313| 10 | Yue Lingshan | 19 | 1 | Song Jiang | 45 |
314| 10 | Yue Lingshan | 19 | 2 | Zhang Sanfeng | 94 |
315| 10 | Yue Lingshan | 19 | 3 | Miejue Shitai | 77 |
316| 10 | Yue Lingshan | 19 | 4 | Lin Chaoying | 93 |
317| 11 | Yuan Chengzhi | 23 | 1 | Song Jiang | 45 |
318| 11 | Yuan Chengzhi | 23 | 2 | Zhang Sanfeng | 94 |
319| 11 | Yuan Chengzhi | 23 | 3 | Miejue Shitai | 77 |
320| 11 | Yuan Chengzhi | 23 | 4 | Lin Chaoying | 93 |
321| 12 | Wen Qingqing | 19 | 1 | Song Jiang | 45 |
322| 12 | Wen Qingqing | 19 | 2 | Zhang Sanfeng | 94 |
323| 12 | Wen Qingqing | 19 | 3 | Miejue Shitai | 77 |
324| 12 | Wen Qingqing | 19 | 4 | Lin Chaoying | 93 |
325| 13 | Tian Boguang | 33 | 1 | Song Jiang | 45 |
326| 13 | Tian Boguang | 33 | 2 | Zhang Sanfeng | 94 |
327| 13 | Tian Boguang | 33 | 3 | Miejue Shitai | 77 |
328| 13 | Tian Boguang | 33 | 4 | Lin Chaoying | 93 |
329| 14 | Lu Wushuang | 17 | 1 | Song Jiang | 45 |
330| 14 | Lu Wushuang | 17 | 2 | Zhang Sanfeng | 94 |
331| 14 | Lu Wushuang | 17 | 3 | Miejue Shitai | 77 |
332| 14 | Lu Wushuang | 17 | 4 | Lin Chaoying | 93 |
333| 15 | Duan Yu | 19 | 1 | Song Jiang | 45 |
334| 15 | Duan Yu | 19 | 2 | Zhang Sanfeng | 94 |
335| 15 | Duan Yu | 19 | 3 | Miejue Shitai | 77 |
336| 15 | Duan Yu | 19 | 4 | Lin Chaoying | 93 |
337| 16 | Xu Zhu | 21 | 1 | Song Jiang | 45 |
338| 16 | Xu Zhu | 21 | 2 | Zhang Sanfeng | 94 |
339| 16 | Xu Zhu | 21 | 3 | Miejue Shitai | 77 |
340| 16 | Xu Zhu | 21 | 4 | Lin Chaoying | 93 |
341| 17 | Lin Chong | 25 | 1 | Song Jiang | 45 |
342| 17 | Lin Chong | 25 | 2 | Zhang Sanfeng | 94 |
343| 17 | Lin Chong | 25 | 3 | Miejue Shitai | 77 |
344| 17 | Lin Chong | 25 | 4 | Lin Chaoying | 93 |
345| 18 | Hua Rong | 23 | 1 | Song Jiang | 45 |
346| 18 | Hua Rong | 23 | 2 | Zhang Sanfeng | 94 |
347| 18 | Hua Rong | 23 | 3 | Miejue Shitai | 77 |
348| 18 | Hua Rong | 23 | 4 | Lin Chaoying | 93 |
349| 19 | Xue Baochai | 18 | 1 | Song Jiang | 45 |
350| 19 | Xue Baochai | 18 | 2 | Zhang Sanfeng | 94 |
351| 19 | Xue Baochai | 18 | 3 | Miejue Shitai | 77 |
352| 19 | Xue Baochai | 18 | 4 | Lin Chaoying | 93 |
353| 20 | Diao Chan | 19 | 1 | Song Jiang | 45 |
354| 20 | Diao Chan | 19 | 2 | Zhang Sanfeng | 94 |
355| 20 | Diao Chan | 19 | 3 | Miejue Shitai | 77 |
356| 20 | Diao Chan | 19 | 4 | Lin Chaoying | 93 |
357| 21 | Huang Yueying | 22 | 1 | Song Jiang | 45 |
358| 21 | Huang Yueying | 22 | 2 | Zhang Sanfeng | 94 |
359| 21 | Huang Yueying | 22 | 3 | Miejue Shitai | 77 |
360| 21 | Huang Yueying | 22 | 4 | Lin Chaoying | 93 |
361| 22 | Xiao Qiao | 20 | 1 | Song Jiang | 45 |
362| 22 | Xiao Qiao | 20 | 2 | Zhang Sanfeng | 94 |
363| 22 | Xiao Qiao | 20 | 3 | Miejue Shitai | 77 |
364| 22 | Xiao Qiao | 20 | 4 | Lin Chaoying | 93 |
365| 23 | Ma Chao | 23 | 1 | Song Jiang | 45 |
366| 23 | Ma Chao | 23 | 2 | Zhang Sanfeng | 94 |
367| 23 | Ma Chao | 23 | 3 | Miejue Shitai | 77 |
368| 23 | Ma Chao | 23 | 4 | Lin Chaoying | 93 |
369| 24 | Xu Xian | 27 | 1 | Song Jiang | 45 |
370| 24 | Xu Xian | 27 | 2 | Zhang Sanfeng | 94 |
371| 24 | Xu Xian | 27 | 3 | Miejue Shitai | 77 |
372| 24 | Xu Xian | 27 | 4 | Lin Chaoying | 93 |
373| 25 | Sun Dasheng | 100 | 1 | Song Jiang | 45 |
374| 25 | Sun Dasheng | 100 | 2 | Zhang Sanfeng | 94 |
375| 25 | Sun Dasheng | 100 | 3 | Miejue Shitai | 77 |
376| 25 | Sun Dasheng | 100 | 4 | Lin Chaoying | 93 |
377+-------+---------------+--------------+-----+---------------+--------------+
378100 rows in set (0.00 sec)
内连接
两张表交叉连接之后,符合条件的信息。
内连接不分谁在前,谁在后。但左、右外连接,得分左右了。

- 范例:内连接
1#内连接inner join
2MariaDB [hellodb]> select *from students inner join teachers on students.teacherid=teachers.tid;
3+-------+-------------+-----+--------+---------+-----------+-----+---------------+-----+--------+
4| StuID | Name | Age | Gender | ClassID | TeacherID | TID | Name | Age | Gender |
5+-------+-------------+-----+--------+---------+-----------+-----+---------------+-----+--------+
6| 5 | Yu Yutong | 26 | M | 3 | 1 | 1 | Song Jiang | 45 | M |
7| 1 | Shi Zhongyu | 22 | M | 2 | 3 | 3 | Miejue Shitai | 77 | F |
8| 4 | Ding Dian | 32 | M | 4 | 4 | 4 | Lin Chaoying | 93 | F |
9+-------+-------------+-----+--------+---------+-----------+-----+---------------+-----+--------+
103 rows in set (0.00 sec)
11MariaDB [hellodb]> select *from students s inner join teachers t on s.teacherid=t.tid;
12+-------+-------------+-----+--------+---------+-----------+-----+---------------+-----+--------+
13| StuID | Name | Age | Gender | ClassID | TeacherID | TID | Name | Age | Gender |
14+-------+-------------+-----+--------+---------+-----------+-----+---------------+-----+--------+
15| 5 | Yu Yutong | 26 | M | 3 | 1 | 1 | Song Jiang | 45 | M |
16| 1 | Shi Zhongyu | 22 | M | 2 | 3 | 3 | Miejue Shitai | 77 | F |
17| 4 | Ding Dian | 32 | M | 4 | 4 | 4 | Lin Chaoying | 93 | F |
18+-------+-------------+-----+--------+---------+-----------+-----+---------------+-----+--------+
193 rows in set (0.00 sec)
20
21
22
23##另一个逻辑:哈哈(男女搭配,干活不累)
24MariaDB [hellodb]> select *from students s inner join teachers t on s.gender != t.gender;
25MariaDB [hellodb]> select *from students s inner join teachers t on s.gender='m' and t.gender='F' or s.gender='F' and t.gender='M' ;
26+-------+---------------+-----+--------+---------+-----------+-----+---------------+-----+--------+
27| StuID | Name | Age | Gender | ClassID | TeacherID | TID | Name | Age | Gender |
28+-------+---------------+-----+--------+---------+-----------+-----+---------------+-----+--------+
29| 1 | Shi Zhongyu | 22 | M | 2 | 3 | 3 | Miejue Shitai | 77 | F |
30| 1 | Shi Zhongyu | 22 | M | 2 | 3 | 4 | Lin Chaoying | 93 | F |
31| 2 | Shi Potian | 22 | M | 1 | 7 | 3 | Miejue Shitai | 77 | F |
32| 2 | Shi Potian | 22 | M | 1 | 7 | 4 | Lin Chaoying | 93 | F |
33| 3 | Xie Yanke | 53 | M | 2 | 16 | 3 | Miejue Shitai | 77 | F |
34| 3 | Xie Yanke | 53 | M | 2 | 16 | 4 | Lin Chaoying | 93 | F |
35| 4 | Ding Dian | 32 | M | 4 | 4 | 3 | Miejue Shitai | 77 | F |
36| 4 | Ding Dian | 32 | M | 4 | 4 | 4 | Lin Chaoying | 93 | F |
37| 5 | Yu Yutong | 26 | M | 3 | 1 | 3 | Miejue Shitai | 77 | F |
38| 5 | Yu Yutong | 26 | M | 3 | 1 | 4 | Lin Chaoying | 93 | F |
39| 6 | Shi Qing | 46 | M | 5 | NULL | 3 | Miejue Shitai | 77 | F |
40| 6 | Shi Qing | 46 | M | 5 | NULL | 4 | Lin Chaoying | 93 | F |
41| 7 | Xi Ren | 19 | F | 3 | NULL | 1 | Song Jiang | 45 | M |
42| 7 | Xi Ren | 19 | F | 3 | NULL | 2 | Zhang Sanfeng | 94 | M |
43| 8 | Lin Daiyu | 17 | F | 7 | NULL | 1 | Song Jiang | 45 | M |
44| 8 | Lin Daiyu | 17 | F | 7 | NULL | 2 | Zhang Sanfeng | 94 | M |
45| 9 | Ren Yingying | 20 | F | 6 | NULL | 1 | Song Jiang | 45 | M |
46| 9 | Ren Yingying | 20 | F | 6 | NULL | 2 | Zhang Sanfeng | 94 | M |
47| 10 | Yue Lingshan | 19 | F | 3 | NULL | 1 | Song Jiang | 45 | M |
48| 10 | Yue Lingshan | 19 | F | 3 | NULL | 2 | Zhang Sanfeng | 94 | M |
49| 11 | Yuan Chengzhi | 23 | M | 6 | NULL | 3 | Miejue Shitai | 77 | F |
50| 11 | Yuan Chengzhi | 23 | M | 6 | NULL | 4 | Lin Chaoying | 93 | F |
51| 12 | Wen Qingqing | 19 | F | 1 | NULL | 1 | Song Jiang | 45 | M |
52| 12 | Wen Qingqing | 19 | F | 1 | NULL | 2 | Zhang Sanfeng | 94 | M |
53| 13 | Tian Boguang | 33 | M | 2 | NULL | 3 | Miejue Shitai | 77 | F |
54| 13 | Tian Boguang | 33 | M | 2 | NULL | 4 | Lin Chaoying | 93 | F |
55| 14 | Lu Wushuang | 17 | F | 3 | NULL | 1 | Song Jiang | 45 | M |
56| 14 | Lu Wushuang | 17 | F | 3 | NULL | 2 | Zhang Sanfeng | 94 | M |
57| 15 | Duan Yu | 19 | M | 4 | NULL | 3 | Miejue Shitai | 77 | F |
58| 15 | Duan Yu | 19 | M | 4 | NULL | 4 | Lin Chaoying | 93 | F |
59| 16 | Xu Zhu | 21 | M | 1 | NULL | 3 | Miejue Shitai | 77 | F |
60| 16 | Xu Zhu | 21 | M | 1 | NULL | 4 | Lin Chaoying | 93 | F |
61| 17 | Lin Chong | 25 | M | 4 | NULL | 3 | Miejue Shitai | 77 | F |
62| 17 | Lin Chong | 25 | M | 4 | NULL | 4 | Lin Chaoying | 93 | F |
63| 18 | Hua Rong | 23 | M | 7 | NULL | 3 | Miejue Shitai | 77 | F |
64| 18 | Hua Rong | 23 | M | 7 | NULL | 4 | Lin Chaoying | 93 | F |
65| 19 | Xue Baochai | 18 | F | 6 | NULL | 1 | Song Jiang | 45 | M |
66| 19 | Xue Baochai | 18 | F | 6 | NULL | 2 | Zhang Sanfeng | 94 | M |
67| 20 | Diao Chan | 19 | F | 7 | NULL | 1 | Song Jiang | 45 | M |
68| 20 | Diao Chan | 19 | F | 7 | NULL | 2 | Zhang Sanfeng | 94 | M |
69| 21 | Huang Yueying | 22 | F | 6 | NULL | 1 | Song Jiang | 45 | M |
70| 21 | Huang Yueying | 22 | F | 6 | NULL | 2 | Zhang Sanfeng | 94 | M |
71| 22 | Xiao Qiao | 20 | F | 1 | NULL | 1 | Song Jiang | 45 | M |
72| 22 | Xiao Qiao | 20 | F | 1 | NULL | 2 | Zhang Sanfeng | 94 | M |
73| 23 | Ma Chao | 23 | M | 4 | NULL | 3 | Miejue Shitai | 77 | F |
74| 23 | Ma Chao | 23 | M | 4 | NULL | 4 | Lin Chaoying | 93 | F |
75| 24 | Xu Xian | 27 | M | NULL | NULL | 3 | Miejue Shitai | 77 | F |
76| 24 | Xu Xian | 27 | M | NULL | NULL | 4 | Lin Chaoying | 93 | F |
77| 25 | Sun Dasheng | 100 | M | NULL | NULL | 3 | Miejue Shitai | 77 | F |
78| 25 | Sun Dasheng | 100 | M | NULL | NULL | 4 | Lin Chaoying | 93 | F |
79+-------+---------------+-----+--------+---------+-----------+-----+---------------+-----+--------+
8050 rows in set (0.00 sec)
81
82
83
84##过滤部分字段
85MariaDB [hellodb]> select s.name 学生姓名,s.age 学生年龄,s.gender 学生性别,t.name 老师姓名,t.age 老师年龄, t.gender 老师性别 from students s inner join teachers t on s.gender <> t.gender;
86+---------------+--------------+--------------+---------------+--------------+--------------+
87| 学生姓名 | 学生年龄 | 学生性别 | 老师姓名 | 老师年龄 | 老师性别 |
88+---------------+--------------+--------------+---------------+--------------+--------------+
89| Shi Zhongyu | 22 | M | Miejue Shitai | 77 | F |
90| Shi Zhongyu | 22 | M | Lin Chaoying | 93 | F |
91| Shi Potian | 22 | M | Miejue Shitai | 77 | F |
92| Shi Potian | 22 | M | Lin Chaoying | 93 | F |
93| Xie Yanke | 53 | M | Miejue Shitai | 77 | F |
94| Xie Yanke | 53 | M | Lin Chaoying | 93 | F |
95| Ding Dian | 32 | M | Miejue Shitai | 77 | F |
96| Ding Dian | 32 | M | Lin Chaoying | 93 | F |
97| Yu Yutong | 26 | M | Miejue Shitai | 77 | F |
98| Yu Yutong | 26 | M | Lin Chaoying | 93 | F |
99| Shi Qing | 46 | M | Miejue Shitai | 77 | F |
100| Shi Qing | 46 | M | Lin Chaoying | 93 | F |
101| Xi Ren | 19 | F | Song Jiang | 45 | M |
102| Xi Ren | 19 | F | Zhang Sanfeng | 94 | M |
103| Lin Daiyu | 17 | F | Song Jiang | 45 | M |
104| Lin Daiyu | 17 | F | Zhang Sanfeng | 94 | M |
105| Ren Yingying | 20 | F | Song Jiang | 45 | M |
106| Ren Yingying | 20 | F | Zhang Sanfeng | 94 | M |
107| Yue Lingshan | 19 | F | Song Jiang | 45 | M |
108| Yue Lingshan | 19 | F | Zhang Sanfeng | 94 | M |
109| Yuan Chengzhi | 23 | M | Miejue Shitai | 77 | F |
110| Yuan Chengzhi | 23 | M | Lin Chaoying | 93 | F |
111| Wen Qingqing | 19 | F | Song Jiang | 45 | M |
112| Wen Qingqing | 19 | F | Zhang Sanfeng | 94 | M |
113| Tian Boguang | 33 | M | Miejue Shitai | 77 | F |
114| Tian Boguang | 33 | M | Lin Chaoying | 93 | F |
115| Lu Wushuang | 17 | F | Song Jiang | 45 | M |
116| Lu Wushuang | 17 | F | Zhang Sanfeng | 94 | M |
117| Duan Yu | 19 | M | Miejue Shitai | 77 | F |
118| Duan Yu | 19 | M | Lin Chaoying | 93 | F |
119| Xu Zhu | 21 | M | Miejue Shitai | 77 | F |
120| Xu Zhu | 21 | M | Lin Chaoying | 93 | F |
121| Lin Chong | 25 | M | Miejue Shitai | 77 | F |
122| Lin Chong | 25 | M | Lin Chaoying | 93 | F |
123| Hua Rong | 23 | M | Miejue Shitai | 77 | F |
124| Hua Rong | 23 | M | Lin Chaoying | 93 | F |
125| Xue Baochai | 18 | F | Song Jiang | 45 | M |
126| Xue Baochai | 18 | F | Zhang Sanfeng | 94 | M |
127| Diao Chan | 19 | F | Song Jiang | 45 | M |
128| Diao Chan | 19 | F | Zhang Sanfeng | 94 | M |
129| Huang Yueying | 22 | F | Song Jiang | 45 | M |
130| Huang Yueying | 22 | F | Zhang Sanfeng | 94 | M |
131| Xiao Qiao | 20 | F | Song Jiang | 45 | M |
132| Xiao Qiao | 20 | F | Zhang Sanfeng | 94 | M |
133| Ma Chao | 23 | M | Miejue Shitai | 77 | F |
134| Ma Chao | 23 | M | Lin Chaoying | 93 | F |
135| Xu Xian | 27 | M | Miejue Shitai | 77 | F |
136| Xu Xian | 27 | M | Lin Chaoying | 93 | F |
137| Sun Dasheng | 100 | M | Miejue Shitai | 77 | F |
138| Sun Dasheng | 100 | M | Lin Chaoying | 93 | F |
139+---------------+--------------+--------------+---------------+--------------+--------------+
14050 rows in set (0.00 sec)
141
142
143
144##范例:另一种古老的写法(这个写法也是可以的)
145MariaDB [hellodb]> select s.name 学生姓名,s.age 学生年龄,s.gender 学生性别,t.name 老师姓名,t.age 老师年龄, t.gender 老师性别 from students s, teachers t where s.gender <> t.gender;
146
147
148##进一步再去过滤
149select s.name 学生姓名,s.age 学生年龄,s.gender 学生性别,t.name 老师姓名,t.age 老师年龄, t.gender 老师性别 from students s inner join teachers t on s.gender <> t.gender where t.age<=50;
150
151select s.name 学生姓名,s.age 学生年龄,s.gender 学生性别,t.name 老师姓名,t.age 老师年龄, t.gender 老师性别 from students s inner join teachers t on s.gender <> t.gender and t.age<=50;
左和右外连接


- 范例:左,右外连接
1MariaDB [hellodb]> select *from students inner join teachers on students.teacherid=teachers.tid;
2+-------+-------------+-----+--------+---------+-----------+-----+---------------+-----+--------+
3| StuID | Name | Age | Gender | ClassID | TeacherID | TID | Name | Age | Gender |
4+-------+-------------+-----+--------+---------+-----------+-----+---------------+-----+--------+
5| 5 | Yu Yutong | 26 | M | 3 | 1 | 1 | Song Jiang | 45 | M |
6| 1 | Shi Zhongyu | 22 | M | 2 | 3 | 3 | Miejue Shitai | 77 | F |
7| 4 | Ding Dian | 32 | M | 4 | 4 | 4 | Lin Chaoying | 93 | F |
8+-------+-------------+-----+--------+---------+-----------+-----+---------------+-----+--------+
93 rows in set (0.00 sec)
10
11MariaDB [hellodb]> select *from students left join teachers on students.teacherid=teachers.tid;
12+-------+---------------+-----+--------+---------+-----------+------+---------------+------+--------+
13| StuID | Name | Age | Gender | ClassID | TeacherID | TID | Name | Age | Gender |
14+-------+---------------+-----+--------+---------+-----------+------+---------------+------+--------+
15| 1 | Shi Zhongyu | 22 | M | 2 | 3 | 3 | Miejue Shitai | 77 | F |
16| 2 | Shi Potian | 22 | M | 1 | 7 | NULL | NULL | NULL | NULL |
17| 3 | Xie Yanke | 53 | M | 2 | 16 | NULL | NULL | NULL | NULL |
18| 4 | Ding Dian | 32 | M | 4 | 4 | 4 | Lin Chaoying | 93 | F |
19| 5 | Yu Yutong | 26 | M | 3 | 1 | 1 | Song Jiang | 45 | M |
20| 6 | Shi Qing | 46 | M | 5 | NULL | NULL | NULL | NULL | NULL |
21| 7 | Xi Ren | 19 | F | 3 | NULL | NULL | NULL | NULL | NULL |
22| 8 | Lin Daiyu | 17 | F | 7 | NULL | NULL | NULL | NULL | NULL |
23| 9 | Ren Yingying | 20 | F | 6 | NULL | NULL | NULL | NULL | NULL |
24| 10 | Yue Lingshan | 19 | F | 3 | NULL | NULL | NULL | NULL | NULL |
25| 11 | Yuan Chengzhi | 23 | M | 6 | NULL | NULL | NULL | NULL | NULL |
26| 12 | Wen Qingqing | 19 | F | 1 | NULL | NULL | NULL | NULL | NULL |
27| 13 | Tian Boguang | 33 | M | 2 | NULL | NULL | NULL | NULL | NULL |
28| 14 | Lu Wushuang | 17 | F | 3 | NULL | NULL | NULL | NULL | NULL |
29| 15 | Duan Yu | 19 | M | 4 | NULL | NULL | NULL | NULL | NULL |
30| 16 | Xu Zhu | 21 | M | 1 | NULL | NULL | NULL | NULL | NULL |
31| 17 | Lin Chong | 25 | M | 4 | NULL | NULL | NULL | NULL | NULL |
32| 18 | Hua Rong | 23 | M | 7 | NULL | NULL | NULL | NULL | NULL |
33| 19 | Xue Baochai | 18 | F | 6 | NULL | NULL | NULL | NULL | NULL |
34| 20 | Diao Chan | 19 | F | 7 | NULL | NULL | NULL | NULL | NULL |
35| 21 | Huang Yueying | 22 | F | 6 | NULL | NULL | NULL | NULL | NULL |
36| 22 | Xiao Qiao | 20 | F | 1 | NULL | NULL | NULL | NULL | NULL |
37| 23 | Ma Chao | 23 | M | 4 | NULL | NULL | NULL | NULL | NULL |
38| 24 | Xu Xian | 27 | M | NULL | NULL | NULL | NULL | NULL | NULL |
39| 25 | Sun Dasheng | 100 | M | NULL | NULL | NULL | NULL | NULL | NULL |
40+-------+---------------+-----+--------+---------+-----------+------+---------------+------+--------+
4125 rows in set (0.00 sec)
42
43
44
45
46#谁左谁右很关键。
47MariaDB [hellodb]> select *from teachers left join students on students.teacherid=teachers.tid;
48+-----+---------------+-----+--------+-------+-------------+------+--------+---------+-----------+
49| TID | Name | Age | Gender | StuID | Name | Age | Gender | ClassID | TeacherID |
50+-----+---------------+-----+--------+-------+-------------+------+--------+---------+-----------+
51| 3 | Miejue Shitai | 77 | F | 1 | Shi Zhongyu | 22 | M | 2 | 3 |
52| 4 | Lin Chaoying | 93 | F | 4 | Ding Dian | 32 | M | 4 | 4 |
53| 1 | Song Jiang | 45 | M | 5 | Yu Yutong | 26 | M | 3 | 1 |
54| 2 | Zhang Sanfeng | 94 | M | NULL | NULL | NULL | NULL | NULL | NULL |
55+-----+---------------+-----+--------+-------+-------------+------+--------+---------+-----------+
564 rows in set (0.00 sec)
57
58
59
60
61
62##右外连接
63MariaDB [hellodb]> select *from teachers right join students on students.teacherid=teachers.tid;
64+------+---------------+------+--------+-------+---------------+-----+--------+---------+-----------+
65| TID | Name | Age | Gender | StuID | Name | Age | Gender | ClassID | TeacherID |
66+------+---------------+------+--------+-------+---------------+-----+--------+---------+-----------+
67| 3 | Miejue Shitai | 77 | F | 1 | Shi Zhongyu | 22 | M | 2 | 3 |
68| NULL | NULL | NULL | NULL | 2 | Shi Potian | 22 | M | 1 | 7 |
69| NULL | NULL | NULL | NULL | 3 | Xie Yanke | 53 | M | 2 | 16 |
70| 4 | Lin Chaoying | 93 | F | 4 | Ding Dian | 32 | M | 4 | 4 |
71| 1 | Song Jiang | 45 | M | 5 | Yu Yutong | 26 | M | 3 | 1 |
72| NULL | NULL | NULL | NULL | 6 | Shi Qing | 46 | M | 5 | NULL |
73| NULL | NULL | NULL | NULL | 7 | Xi Ren | 19 | F | 3 | NULL |
74| NULL | NULL | NULL | NULL | 8 | Lin Daiyu | 17 | F | 7 | NULL |
75| NULL | NULL | NULL | NULL | 9 | Ren Yingying | 20 | F | 6 | NULL |
76| NULL | NULL | NULL | NULL | 10 | Yue Lingshan | 19 | F | 3 | NULL |
77| NULL | NULL | NULL | NULL | 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
78| NULL | NULL | NULL | NULL | 12 | Wen Qingqing | 19 | F | 1 | NULL |
79| NULL | NULL | NULL | NULL | 13 | Tian Boguang | 33 | M | 2 | NULL |
80| NULL | NULL | NULL | NULL | 14 | Lu Wushuang | 17 | F | 3 | NULL |
81| NULL | NULL | NULL | NULL | 15 | Duan Yu | 19 | M | 4 | NULL |
82| NULL | NULL | NULL | NULL | 16 | Xu Zhu | 21 | M | 1 | NULL |
83| NULL | NULL | NULL | NULL | 17 | Lin Chong | 25 | M | 4 | NULL |
84| NULL | NULL | NULL | NULL | 18 | Hua Rong | 23 | M | 7 | NULL |
85| NULL | NULL | NULL | NULL | 19 | Xue Baochai | 18 | F | 6 | NULL |
86| NULL | NULL | NULL | NULL | 20 | Diao Chan | 19 | F | 7 | NULL |
87| NULL | NULL | NULL | NULL | 21 | Huang Yueying | 22 | F | 6 | NULL |
88| NULL | NULL | NULL | NULL | 22 | Xiao Qiao | 20 | F | 1 | NULL |
89| NULL | NULL | NULL | NULL | 23 | Ma Chao | 23 | M | 4 | NULL |
90| NULL | NULL | NULL | NULL | 24 | Xu Xian | 27 | M | NULL | NULL |
91| NULL | NULL | NULL | NULL | 25 | Sun Dasheng | 100 | M | NULL | NULL |
92+------+---------------+------+--------+-------+---------------+-----+--------+---------+-----------+
9325 rows in set (0.00 sec)
- 范例:左外连接的扩展用法

1MariaDB [hellodb]> select *from students left join teachers on students.teacherid=teachers.tid where tid is null;
2+-------+---------------+-----+--------+---------+-----------+------+------+------+--------+
3| StuID | Name | Age | Gender | ClassID | TeacherID | TID | Name | Age | Gender |
4+-------+---------------+-----+--------+---------+-----------+------+------+------+--------+
5| 2 | Shi Potian | 22 | M | 1 | 7 | NULL | NULL | NULL | NULL |
6| 3 | Xie Yanke | 53 | M | 2 | 16 | NULL | NULL | NULL | NULL |
7| 6 | Shi Qing | 46 | M | 5 | NULL | NULL | NULL | NULL | NULL |
8| 7 | Xi Ren | 19 | F | 3 | NULL | NULL | NULL | NULL | NULL |
9| 8 | Lin Daiyu | 17 | F | 7 | NULL | NULL | NULL | NULL | NULL |
10| 9 | Ren Yingying | 20 | F | 6 | NULL | NULL | NULL | NULL | NULL |
11| 10 | Yue Lingshan | 19 | F | 3 | NULL | NULL | NULL | NULL | NULL |
12| 11 | Yuan Chengzhi | 23 | M | 6 | NULL | NULL | NULL | NULL | NULL |
13| 12 | Wen Qingqing | 19 | F | 1 | NULL | NULL | NULL | NULL | NULL |
14| 13 | Tian Boguang | 33 | M | 2 | NULL | NULL | NULL | NULL | NULL |
15| 14 | Lu Wushuang | 17 | F | 3 | NULL | NULL | NULL | NULL | NULL |
16| 15 | Duan Yu | 19 | M | 4 | NULL | NULL | NULL | NULL | NULL |
17| 16 | Xu Zhu | 21 | M | 1 | NULL | NULL | NULL | NULL | NULL |
18| 17 | Lin Chong | 25 | M | 4 | NULL | NULL | NULL | NULL | NULL |
19| 18 | Hua Rong | 23 | M | 7 | NULL | NULL | NULL | NULL | NULL |
20| 19 | Xue Baochai | 18 | F | 6 | NULL | NULL | NULL | NULL | NULL |
21| 20 | Diao Chan | 19 | F | 7 | NULL | NULL | NULL | NULL | NULL |
22| 21 | Huang Yueying | 22 | F | 6 | NULL | NULL | NULL | NULL | NULL |
23| 22 | Xiao Qiao | 20 | F | 1 | NULL | NULL | NULL | NULL | NULL |
24| 23 | Ma Chao | 23 | M | 4 | NULL | NULL | NULL | NULL | NULL |
25| 24 | Xu Xian | 27 | M | NULL | NULL | NULL | NULL | NULL | NULL |
26| 25 | Sun Dasheng | 100 | M | NULL | NULL | NULL | NULL | NULL | NULL |
27+-------+---------------+-----+--------+---------+-----------+------+------+------+--------+
2822 rows in set (0.00 sec)
完全外连接
可惜,mysql里不支持完全外连接这种语法!

- 范例:完全外连接
1#可惜,mysql里不支持完全外连接这种语法!
2MariaDB [hellodb]> select *from students full outer join teachers on students.teacherid=teachers.tid;
3ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'outer join teachers on students.teacherid=teachers.tid' at line 1
4MariaDB [hellodb]> select *from students full join teachers on students.teacherid=teachers.tid;
5ERROR 1054 (42S22): Unknown column 'students.teacherid' in 'on clause'
- 范例:我们可以通过其它方式来实现:
对这2种表union,且union可以去重。

注意:这个不是交叉连接哦。
1MariaDB [hellodb]> select *from students left join teachers on students.teacherid=teachers.tid;
2+-------+---------------+-----+--------+---------+-----------+------+---------------+------+--------+
3| StuID | Name | Age | Gender | ClassID | TeacherID | TID | Name | Age | Gender |
4+-------+---------------+-----+--------+---------+-----------+------+---------------+------+--------+
5| 1 | Shi Zhongyu | 22 | M | 2 | 3 | 3 | Miejue Shitai | 77 | F |
6| 2 | Shi Potian | 22 | M | 1 | 7 | NULL | NULL | NULL | NULL |
7| 3 | Xie Yanke | 53 | M | 2 | 16 | NULL | NULL | NULL | NULL |
8| 4 | Ding Dian | 32 | M | 4 | 4 | 4 | Lin Chaoying | 93 | F |
9| 5 | Yu Yutong | 26 | M | 3 | 1 | 1 | Song Jiang | 45 | M |
10| 6 | Shi Qing | 46 | M | 5 | NULL | NULL | NULL | NULL | NULL |
11| 7 | Xi Ren | 19 | F | 3 | NULL | NULL | NULL | NULL | NULL |
12| 8 | Lin Daiyu | 17 | F | 7 | NULL | NULL | NULL | NULL | NULL |
13| 9 | Ren Yingying | 20 | F | 6 | NULL | NULL | NULL | NULL | NULL |
14| 10 | Yue Lingshan | 19 | F | 3 | NULL | NULL | NULL | NULL | NULL |
15| 11 | Yuan Chengzhi | 23 | M | 6 | NULL | NULL | NULL | NULL | NULL |
16| 12 | Wen Qingqing | 19 | F | 1 | NULL | NULL | NULL | NULL | NULL |
17| 13 | Tian Boguang | 33 | M | 2 | NULL | NULL | NULL | NULL | NULL |
18| 14 | Lu Wushuang | 17 | F | 3 | NULL | NULL | NULL | NULL | NULL |
19| 15 | Duan Yu | 19 | M | 4 | NULL | NULL | NULL | NULL | NULL |
20| 16 | Xu Zhu | 21 | M | 1 | NULL | NULL | NULL | NULL | NULL |
21| 17 | Lin Chong | 25 | M | 4 | NULL | NULL | NULL | NULL | NULL |
22| 18 | Hua Rong | 23 | M | 7 | NULL | NULL | NULL | NULL | NULL |
23| 19 | Xue Baochai | 18 | F | 6 | NULL | NULL | NULL | NULL | NULL |
24| 20 | Diao Chan | 19 | F | 7 | NULL | NULL | NULL | NULL | NULL |
25| 21 | Huang Yueying | 22 | F | 6 | NULL | NULL | NULL | NULL | NULL |
26| 22 | Xiao Qiao | 20 | F | 1 | NULL | NULL | NULL | NULL | NULL |
27| 23 | Ma Chao | 23 | M | 4 | NULL | NULL | NULL | NULL | NULL |
28| 24 | Xu Xian | 27 | M | NULL | NULL | NULL | NULL | NULL | NULL |
29| 25 | Sun Dasheng | 100 | M | NULL | NULL | NULL | NULL | NULL | NULL |
30+-------+---------------+-----+--------+---------+-----------+------+---------------+------+--------+
3125 rows in set (0.00 sec)
32
33MariaDB [hellodb]> select *from students right join teachers on students.teacherid=teachers.tid;
34+-------+-------------+------+--------+---------+-----------+-----+---------------+-----+--------+
35| StuID | Name | Age | Gender | ClassID | TeacherID | TID | Name | Age | Gender |
36+-------+-------------+------+--------+---------+-----------+-----+---------------+-----+--------+
37| 1 | Shi Zhongyu | 22 | M | 2 | 3 | 3 | Miejue Shitai | 77 | F |
38| 4 | Ding Dian | 32 | M | 4 | 4 | 4 | Lin Chaoying | 93 | F |
39| 5 | Yu Yutong | 26 | M | 3 | 1 | 1 | Song Jiang | 45 | M |
40| NULL | NULL | NULL | NULL | NULL | NULL | 2 | Zhang Sanfeng | 94 | M |
41+-------+-------------+------+--------+---------+-----------+-----+---------------+-----+--------+
424 rows in set (0.00 sec)
43
44MariaDB [hellodb]> select *from students left join teachers on students.teacherid=teachers.tid
45 -> union
46 -> select *from students right join teachers on students.teacherid=teachers.tid;
47+-------+---------------+------+--------+---------+-----------+------+---------------+------+--------+
48| StuID | Name | Age | Gender | ClassID | TeacherID | TID | Name | Age | Gender |
49+-------+---------------+------+--------+---------+-----------+------+---------------+------+--------+
50| 1 | Shi Zhongyu | 22 | M | 2 | 3 | 3 | Miejue Shitai | 77 | F |
51| 2 | Shi Potian | 22 | M | 1 | 7 | NULL | NULL | NULL | NULL |
52| 3 | Xie Yanke | 53 | M | 2 | 16 | NULL | NULL | NULL | NULL |
53| 4 | Ding Dian | 32 | M | 4 | 4 | 4 | Lin Chaoying | 93 | F |
54| 5 | Yu Yutong | 26 | M | 3 | 1 | 1 | Song Jiang | 45 | M |
55| 6 | Shi Qing | 46 | M | 5 | NULL | NULL | NULL | NULL | NULL |
56| 7 | Xi Ren | 19 | F | 3 | NULL | NULL | NULL | NULL | NULL |
57| 8 | Lin Daiyu | 17 | F | 7 | NULL | NULL | NULL | NULL | NULL |
58| 9 | Ren Yingying | 20 | F | 6 | NULL | NULL | NULL | NULL | NULL |
59| 10 | Yue Lingshan | 19 | F | 3 | NULL | NULL | NULL | NULL | NULL |
60| 11 | Yuan Chengzhi | 23 | M | 6 | NULL | NULL | NULL | NULL | NULL |
61| 12 | Wen Qingqing | 19 | F | 1 | NULL | NULL | NULL | NULL | NULL |
62| 13 | Tian Boguang | 33 | M | 2 | NULL | NULL | NULL | NULL | NULL |
63| 14 | Lu Wushuang | 17 | F | 3 | NULL | NULL | NULL | NULL | NULL |
64| 15 | Duan Yu | 19 | M | 4 | NULL | NULL | NULL | NULL | NULL |
65| 16 | Xu Zhu | 21 | M | 1 | NULL | NULL | NULL | NULL | NULL |
66| 17 | Lin Chong | 25 | M | 4 | NULL | NULL | NULL | NULL | NULL |
67| 18 | Hua Rong | 23 | M | 7 | NULL | NULL | NULL | NULL | NULL |
68| 19 | Xue Baochai | 18 | F | 6 | NULL | NULL | NULL | NULL | NULL |
69| 20 | Diao Chan | 19 | F | 7 | NULL | NULL | NULL | NULL | NULL |
70| 21 | Huang Yueying | 22 | F | 6 | NULL | NULL | NULL | NULL | NULL |
71| 22 | Xiao Qiao | 20 | F | 1 | NULL | NULL | NULL | NULL | NULL |
72| 23 | Ma Chao | 23 | M | 4 | NULL | NULL | NULL | NULL | NULL |
73| 24 | Xu Xian | 27 | M | NULL | NULL | NULL | NULL | NULL | NULL |
74| 25 | Sun Dasheng | 100 | M | NULL | NULL | NULL | NULL | NULL | NULL |
75| NULL | NULL | NULL | NULL | NULL | NULL | 2 | Zhang Sanfeng | 94 | M |
76+-------+---------------+------+--------+---------+-----------+------+---------------+------+--------+
7726 rows in set (0.00 sec)
78
79MariaDB [hellodb]>
通过这个方式就实现了
完全外连接这个功能了。先
左外连接,再右外连接,然后中间union。

- 范例:这个如何实现呢?
2个变种+union

1MariaDB [hellodb]> select *from students left join teachers on students.teacherid=teachers.tid where tid is null;
2+-------+---------------+-----+--------+---------+-----------+------+------+------+--------+
3| StuID | Name | Age | Gender | ClassID | TeacherID | TID | Name | Age | Gender |
4+-------+---------------+-----+--------+---------+-----------+------+------+------+--------+
5| 2 | Shi Potian | 22 | M | 1 | 7 | NULL | NULL | NULL | NULL |
6| 3 | Xie Yanke | 53 | M | 2 | 16 | NULL | NULL | NULL | NULL |
7| 6 | Shi Qing | 46 | M | 5 | NULL | NULL | NULL | NULL | NULL |
8| 7 | Xi Ren | 19 | F | 3 | NULL | NULL | NULL | NULL | NULL |
9| 8 | Lin Daiyu | 17 | F | 7 | NULL | NULL | NULL | NULL | NULL |
10| 9 | Ren Yingying | 20 | F | 6 | NULL | NULL | NULL | NULL | NULL |
11| 10 | Yue Lingshan | 19 | F | 3 | NULL | NULL | NULL | NULL | NULL |
12| 11 | Yuan Chengzhi | 23 | M | 6 | NULL | NULL | NULL | NULL | NULL |
13| 12 | Wen Qingqing | 19 | F | 1 | NULL | NULL | NULL | NULL | NULL |
14| 13 | Tian Boguang | 33 | M | 2 | NULL | NULL | NULL | NULL | NULL |
15| 14 | Lu Wushuang | 17 | F | 3 | NULL | NULL | NULL | NULL | NULL |
16| 15 | Duan Yu | 19 | M | 4 | NULL | NULL | NULL | NULL | NULL |
17| 16 | Xu Zhu | 21 | M | 1 | NULL | NULL | NULL | NULL | NULL |
18| 17 | Lin Chong | 25 | M | 4 | NULL | NULL | NULL | NULL | NULL |
19| 18 | Hua Rong | 23 | M | 7 | NULL | NULL | NULL | NULL | NULL |
20| 19 | Xue Baochai | 18 | F | 6 | NULL | NULL | NULL | NULL | NULL |
21| 20 | Diao Chan | 19 | F | 7 | NULL | NULL | NULL | NULL | NULL |
22| 21 | Huang Yueying | 22 | F | 6 | NULL | NULL | NULL | NULL | NULL |
23| 22 | Xiao Qiao | 20 | F | 1 | NULL | NULL | NULL | NULL | NULL |
24| 23 | Ma Chao | 23 | M | 4 | NULL | NULL | NULL | NULL | NULL |
25| 24 | Xu Xian | 27 | M | NULL | NULL | NULL | NULL | NULL | NULL |
26| 25 | Sun Dasheng | 100 | M | NULL | NULL | NULL | NULL | NULL | NULL |
27+-------+---------------+-----+--------+---------+-----------+------+------+------+--------+
2822 rows in set (0.00 sec)
29
30
31
32MariaDB [hellodb]> select *from students right join teachers on students.teacherid=teachers.tid where teacherid is null;
33+-------+------+------+--------+---------+-----------+-----+---------------+-----+--------+
34| StuID | Name | Age | Gender | ClassID | TeacherID | TID | Name | Age | Gender |
35+-------+------+------+--------+---------+-----------+-----+---------------+-----+--------+
36| NULL | NULL | NULL | NULL | NULL | NULL | 2 | Zhang Sanfeng | 94 | M |
37+-------+------+------+--------+---------+-----------+-----+---------------+-----+--------+
381 row in set (0.00 sec)
39
40
41MariaDB [hellodb]> select *from students left join teachers on students.teacherid=teachers.tid where tid is null
42 -> union
43 -> select *from students right join teachers on students.teacherid=teachers.tid where teacherid is null;
44+-------+---------------+------+--------+---------+-----------+------+---------------+------+--------+
45| StuID | Name | Age | Gender | ClassID | TeacherID | TID | Name | Age | Gender |
46+-------+---------------+------+--------+---------+-----------+------+---------------+------+--------+
47| 2 | Shi Potian | 22 | M | 1 | 7 | NULL | NULL | NULL | NULL |
48| 3 | Xie Yanke | 53 | M | 2 | 16 | NULL | NULL | NULL | NULL |
49| 6 | Shi Qing | 46 | M | 5 | NULL | NULL | NULL | NULL | NULL |
50| 7 | Xi Ren | 19 | F | 3 | NULL | NULL | NULL | NULL | NULL |
51| 8 | Lin Daiyu | 17 | F | 7 | NULL | NULL | NULL | NULL | NULL |
52| 9 | Ren Yingying | 20 | F | 6 | NULL | NULL | NULL | NULL | NULL |
53| 10 | Yue Lingshan | 19 | F | 3 | NULL | NULL | NULL | NULL | NULL |
54| 11 | Yuan Chengzhi | 23 | M | 6 | NULL | NULL | NULL | NULL | NULL |
55| 12 | Wen Qingqing | 19 | F | 1 | NULL | NULL | NULL | NULL | NULL |
56| 13 | Tian Boguang | 33 | M | 2 | NULL | NULL | NULL | NULL | NULL |
57| 14 | Lu Wushuang | 17 | F | 3 | NULL | NULL | NULL | NULL | NULL |
58| 15 | Duan Yu | 19 | M | 4 | NULL | NULL | NULL | NULL | NULL |
59| 16 | Xu Zhu | 21 | M | 1 | NULL | NULL | NULL | NULL | NULL |
60| 17 | Lin Chong | 25 | M | 4 | NULL | NULL | NULL | NULL | NULL |
61| 18 | Hua Rong | 23 | M | 7 | NULL | NULL | NULL | NULL | NULL |
62| 19 | Xue Baochai | 18 | F | 6 | NULL | NULL | NULL | NULL | NULL |
63| 20 | Diao Chan | 19 | F | 7 | NULL | NULL | NULL | NULL | NULL |
64| 21 | Huang Yueying | 22 | F | 6 | NULL | NULL | NULL | NULL | NULL |
65| 22 | Xiao Qiao | 20 | F | 1 | NULL | NULL | NULL | NULL | NULL |
66| 23 | Ma Chao | 23 | M | 4 | NULL | NULL | NULL | NULL | NULL |
67| 24 | Xu Xian | 27 | M | NULL | NULL | NULL | NULL | NULL | NULL |
68| 25 | Sun Dasheng | 100 | M | NULL | NULL | NULL | NULL | NULL | NULL |
69| NULL | NULL | NULL | NULL | NULL | NULL | 2 | Zhang Sanfeng | 94 | M |
70+-------+---------------+------+--------+---------+-----------+------+---------------+------+--------+
7123 rows in set (0.00 sec)
自连接
即:表自身连接自身。
把一张表当2张表来用。
- 范例:自连接测试
案例背景:想要查询公司里所有员工的姓名,及对应直属领导姓名。

创建表:
1MariaDB [hellodb]> create table emp (id int auto_increment primary key,name varchar(20),leader_id int);
2Query OK, 0 rows affected (0.01 sec)
3
4MariaDB [hellodb]> desc emp;
5+-----------+-------------+------+-----+---------+----------------+
6| Field | Type | Null | Key | Default | Extra |
7+-----------+-------------+------+-----+---------+----------------+
8| id | int(11) | NO | PRI | NULL | auto_increment |
9| name | varchar(20) | YES | | NULL | |
10| leader_id | int(11) | YES | | NULL | |
11+-----------+-------------+------+-----+---------+----------------+
123 rows in set (0.00 sec)
13
14
15##插入数据
16MariaDB [hellodb]> insert emp (name,leader_id)value('mage',null),('zhangsir',1),('wang',2),('zhang',3);
17Query OK, 4 rows affected (0.00 sec)
18Records: 4 Duplicates: 0 Warnings: 0
19
20MariaDB [hellodb]> select *from emp;
21+----+----------+-----------+
22| id | name | leader_id |
23+----+----------+-----------+
24| 1 | mage | NULL |
25| 2 | zhangsir | 1 |
26| 3 | wang | 2 |
27| 4 | zhang | 3 |
28+----+----------+-----------+
294 rows in set (0.00 sec)
如果使用内连接+表别名呢?
1MariaDB [hellodb]> select e.name,l.name from emp e inner join emp l on e.leader_id=l.id;
2+----------+----------+
3| name | name |
4+----------+----------+
5| zhangsir | mage |
6| wang | zhangsir |
7| zhang | wang |
8+----------+----------+
93 rows in set (0.00 sec)
10
11
12##存在的问题
13把mage给丢了……
最后,选择使用左外连接+表别名
1MariaDB [hellodb]> select e.name,l.name from emp e left join emp l on e.leader_id=l.id;
2+----------+----------+
3| name | name |
4+----------+----------+
5| mage | NULL |
6| zhangsir | mage |
7| wang | zhangsir |
8| zhang | wang |
9+----------+----------+
104 rows in set (0.00 sec)
再次更新:
1MariaDB [hellodb]> select e.name,IFNULL(l.name,'无上级') from emp e left join emp l on e.leader_id=l.id;
2+----------+----------------------------+
3| name | IFNULL(l.name,'无上级') |
4+----------+----------------------------+
5| mage | 无上级 |
6| zhangsir | mage |
7| wang | zhangsir |
8| zhang | wang |
9+----------+----------------------------+
104 rows in set (0.00 sec)
测试结束。
三表连接😊
- 范例:
2张表在什么情况下需要构建出第三张表?

1MariaDB [hellodb]> show tables;
2+-------------------+
3| Tables_in_hellodb |
4+-------------------+
5| classes |
6| coc |
7| courses |
8| emp |
9| scores |
10| students |
11| teachers |
12| teachers2 |
13| teachers3 |
14| toc |
15+-------------------+
1610 rows in set (0.00 sec)
17
18MariaDB [hellodb]> select *from students;
19+-------+---------------+-----+--------+---------+-----------+
20| StuID | Name | Age | Gender | ClassID | TeacherID |
21+-------+---------------+-----+--------+---------+-----------+
22| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
23| 2 | Shi Potian | 22 | M | 1 | 7 |
24| 3 | Xie Yanke | 53 | M | 2 | 16 |
25| 4 | Ding Dian | 32 | M | 4 | 4 |
26| 5 | Yu Yutong | 26 | M | 3 | 1 |
27| 6 | Shi Qing | 46 | M | 5 | NULL |
28| 7 | Xi Ren | 19 | F | 3 | NULL |
29| 8 | Lin Daiyu | 17 | F | 7 | NULL |
30| 9 | Ren Yingying | 20 | F | 6 | NULL |
31| 10 | Yue Lingshan | 19 | F | 3 | NULL |
32| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
33| 12 | Wen Qingqing | 19 | F | 1 | NULL |
34| 13 | Tian Boguang | 33 | M | 2 | NULL |
35| 14 | Lu Wushuang | 17 | F | 3 | NULL |
36| 15 | Duan Yu | 19 | M | 4 | NULL |
37| 16 | Xu Zhu | 21 | M | 1 | NULL |
38| 17 | Lin Chong | 25 | M | 4 | NULL |
39| 18 | Hua Rong | 23 | M | 7 | NULL |
40| 19 | Xue Baochai | 18 | F | 6 | NULL |
41| 20 | Diao Chan | 19 | F | 7 | NULL |
42| 21 | Huang Yueying | 22 | F | 6 | NULL |
43| 22 | Xiao Qiao | 20 | F | 1 | NULL |
44| 23 | Ma Chao | 23 | M | 4 | NULL |
45| 24 | Xu Xian | 27 | M | NULL | NULL |
46| 25 | Sun Dasheng | 100 | M | NULL | NULL |
47+-------+---------------+-----+--------+---------+-----------+
4825 rows in set (0.00 sec)
49
50MariaDB [hellodb]> select *from courses;
51+----------+----------------+
52| CourseID | Course |
53+----------+----------------+
54| 1 | Hamo Gong |
55| 2 | Kuihua Baodian |
56| 3 | Jinshe Jianfa |
57| 4 | Taiji Quan |
58| 5 | Daiyu Zanghua |
59| 6 | Weituo Zhang |
60| 7 | Dagou Bangfa |
61+----------+----------------+
627 rows in set (0.00 sec)
63
64MariaDB [hellodb]> select *from scores;
65+----+-------+----------+-------+
66| ID | StuID | CourseID | Score |
67+----+-------+----------+-------+
68| 1 | 1 | 2 | 77 |
69| 2 | 1 | 6 | 93 |
70| 3 | 2 | 2 | 47 |
71| 4 | 2 | 5 | 97 |
72| 5 | 3 | 2 | 88 |
73| 6 | 3 | 6 | 75 |
74| 7 | 4 | 5 | 71 |
75| 8 | 4 | 2 | 89 |
76| 9 | 5 | 1 | 39 |
77| 10 | 5 | 7 | 63 |
78| 11 | 6 | 1 | 96 |
79| 12 | 7 | 1 | 86 |
80| 13 | 7 | 7 | 83 |
81| 14 | 8 | 4 | 57 |
82| 15 | 8 | 3 | 93 |
83+----+-------+----------+-------+
8415 rows in set (0.00 sec)
需求:如何查询学生的姓名-报的课程姓名-考试成绩?
学生成绩表-学生姓名
1MariaDB [hellodb]> select st.name 学生姓名,sc.CourseID,sc.Score 考试成绩 from students st inner join scores sc on st.StuID=sc.StuID;
2+--------------+----------+--------------+
3| 学生姓名 | CourseID | 考试成绩 |
4+--------------+----------+--------------+
5| Shi Zhongyu | 2 | 77 |
6| Shi Zhongyu | 6 | 93 |
7| Shi Potian | 2 | 47 |
8| Shi Potian | 5 | 97 |
9| Xie Yanke | 2 | 88 |
10| Xie Yanke | 6 | 75 |
11| Ding Dian | 5 | 71 |
12| Ding Dian | 2 | 89 |
13| Yu Yutong | 1 | 39 |
14| Yu Yutong | 7 | 63 |
15| Shi Qing | 1 | 96 |
16| Xi Ren | 1 | 86 |
17| Xi Ren | 7 | 83 |
18| Lin Daiyu | 4 | 57 |
19| Lin Daiyu | 3 | 93 |
20+--------------+----------+--------------+
2115 rows in set (0.00 sec)
再与课程表进行内连接:
1MariaDB [hellodb]> select st.name 学生姓名,co.Course 课程名称,sc.Score 考试成绩 from students st inner join scores sc on st.StuID=sc.StuID
2 -> inner join
3 -> courses co where sc.CourseID=co. CourseID;
4
5 select st.name 学生姓名,co.Course 课程名称,sc.Score 考试成绩 from students st inner join scores sc on st.StuID=sc.StuID inner join courses co where sc.CourseID=co. CourseID;
6+--------------+----------------+--------------+
7| 学生姓名 | 课程名称 | 考试成绩 |
8+--------------+----------------+--------------+
9| Shi Zhongyu | Kuihua Baodian | 77 |
10| Shi Zhongyu | Weituo Zhang | 93 |
11| Shi Potian | Kuihua Baodian | 47 |
12| Shi Potian | Daiyu Zanghua | 97 |
13| Xie Yanke | Kuihua Baodian | 88 |
14| Xie Yanke | Weituo Zhang | 75 |
15| Ding Dian | Daiyu Zanghua | 71 |
16| Ding Dian | Kuihua Baodian | 89 |
17| Yu Yutong | Hamo Gong | 39 |
18| Yu Yutong | Dagou Bangfa | 63 |
19| Shi Qing | Hamo Gong | 96 |
20| Xi Ren | Hamo Gong | 86 |
21| Xi Ren | Dagou Bangfa | 83 |
22| Lin Daiyu | Taiji Quan | 57 |
23| Lin Daiyu | Jinshe Jianfa | 93 |
24+--------------+----------------+--------------+
2515 rows in set (0.00 sec)
测试结束。😍
SELECT语句处理的顺序

查询执行路径中的组件:查询缓存、解析器、预处理器、优化器、查询执行引擎、存储引擎
SELECT语句的执行流程:
1FROM Clause --> WHERE Clause --> GROUP BY --> HAVING Clause -->SELECT --> ORDER BY --> LIMIT
练习
导入hellodb.sql生成数据库
- 在students表中,查询年龄大于25岁,且为男性的同学的名字和年龄
- 以ClassID为分组依据,显示每组的平均年龄
- 显示第2题中平均年龄大于30的分组及平均年龄
- 显示以L开头的名字的同学的信息
- 显示TeacherID非空的同学的相关信息
- 以年龄排序后,显示年龄最大的前10位同学的信息
- 查询年龄大于等于20岁,小于等于25岁的同学的信息
- 以ClassID分组,显示每班的同学的人数
- 以Gender分组,显示其年龄之和
- 以ClassID分组,显示其平均年龄大于25的班级
- 以Gender分组,显示各组中年龄大于25的学员的年龄之和
- 显示前5位同学的姓名、课程及成绩
- 显示其成绩高于80的同学的名称及课程
- 取每位同学各门课的平均成绩,显示成绩前三名的同学的姓名和平均成绩
- 显示每门课程课程名称及学习了这门课的同学的个数
- 显示其年龄大于平均年龄的同学的名字
- 显示其学习的课程为第1、2,4或第7门课的同学的名字
- 显示其成员数最少为3个的班级的同学中年龄大于同班同学平均年龄的同学
- 统计各班级中年龄大于全校同学平均年龄的同学
VIEW 视图
视图:虚拟表,保存有实表的查询结果,相当于别名。
试图,通常都是供查,改的会少一些;
通过视图可以隐藏数据库结构,起到安全防护作用;
但好多企业生产环境里是不推荐使用视图的;
视图本身不存放数据;
创建方法:
1CREATE VIEW view_name [(column_list)]
2 AS select_statement
3 [WITH [CASCADED | LOCAL] CHECK OPTION]
查看视图定义:
1SHOW CREATE VIEW view_name #只能看视图定义
2SHOW CREATE TABLE view_name # 可以查看表和视图
删除视图:
1DROP VIEW [IF EXISTS]
2 view_name [, view_name] ...
3 [RESTRICT | CASCADE]
注意:视图中的数据事实上存储于“基表”中,因此,其修改操作也会针对基表实现;其修改操作受基表限制
- 范例:
1MariaDB [hellodb]> select st.name 学生姓名,co.Course 课程名称,sc.Score 考试成绩 from students st inner join scores sc on st.StuID=sc.StuID inner join courses co where sc.CourseID=co. CourseID;
2+--------------+----------------+--------------+
3| 学生姓名 | 课程名称 | 考试成绩 |
4+--------------+----------------+--------------+
5| Shi Zhongyu | Kuihua Baodian | 77 |
6| Shi Zhongyu | Weituo Zhang | 93 |
7| Shi Potian | Kuihua Baodian | 47 |
8| Shi Potian | Daiyu Zanghua | 97 |
9| Xie Yanke | Kuihua Baodian | 88 |
10| Xie Yanke | Weituo Zhang | 75 |
11| Ding Dian | Daiyu Zanghua | 71 |
12| Ding Dian | Kuihua Baodian | 89 |
13| Yu Yutong | Hamo Gong | 39 |
14| Yu Yutong | Dagou Bangfa | 63 |
15| Shi Qing | Hamo Gong | 96 |
16| Xi Ren | Hamo Gong | 86 |
17| Xi Ren | Dagou Bangfa | 83 |
18| Lin Daiyu | Taiji Quan | 57 |
19| Lin Daiyu | Jinshe Jianfa | 93 |
20+--------------+----------------+--------------+
2115 rows in set (0.01 sec)
22
23
24##创建视图:(其实,就是相当于给一大串select语句起了一个别名)
25MariaDB [hellodb]> create view v_score as select st.name 学生姓名,co.Course 课程名称,sc.Score 考试成绩 from students st inner join scores sc on st.StuID=sc.StuID inner join courses co where sc.CourseID=co. CourseID;
26Query OK, 0 rows affected (0.00 sec)
27
28MariaDB [hellodb]> show tables;
29+-------------------+
30| Tables_in_hellodb |
31+-------------------+
32| classes |
33| coc |
34| courses |
35| emp |
36| scores |
37| students |
38| teachers |
39| teachers2 |
40| teachers3 |
41| toc |
42| v_score |##可以看到,这里出现了一个v_score表;
43+-------------------+
4411 rows in set (0.01 sec)
45
46
47##问题:如果我更改了原来某张表信息,那么刚才创建的视图里的表信息会变化吗?(会的)
48MariaDB [hellodb]> select *from scores;
49+----+-------+----------+-------+
50| ID | StuID | CourseID | Score |
51+----+-------+----------+-------+
52| 1 | 1 | 2 | 77 |
53| 2 | 1 | 6 | 93 |
54| 3 | 2 | 2 | 47 |
55| 4 | 2 | 5 | 97 |
56| 5 | 3 | 2 | 88 |
57| 6 | 3 | 6 | 75 |
58| 7 | 4 | 5 | 71 |
59| 8 | 4 | 2 | 89 |
60| 9 | 5 | 1 | 39 |
61| 10 | 5 | 7 | 63 |
62| 11 | 6 | 1 | 96 |
63| 12 | 7 | 1 | 86 |
64| 13 | 7 | 7 | 83 |
65| 14 | 8 | 4 | 57 |
66| 15 | 8 | 3 | 93 |
67+----+-------+----------+-------+
6815 rows in set (0.00 sec)
69
70MariaDB [hellodb]> update scores set score=88 where id=1;
71Query OK, 1 row affected (0.00 sec)
72Rows matched: 1 Changed: 1 Warnings: 0
73
74MariaDB [hellodb]> select *from scores;
75+----+-------+----------+-------+
76| ID | StuID | CourseID | Score |
77+----+-------+----------+-------+
78| 1 | 1 | 2 | 88 |
79| 2 | 1 | 6 | 93 |
80| 3 | 2 | 2 | 47 |
81| 4 | 2 | 5 | 97 |
82| 5 | 3 | 2 | 88 |
83| 6 | 3 | 6 | 75 |
84| 7 | 4 | 5 | 71 |
85| 8 | 4 | 2 | 89 |
86| 9 | 5 | 1 | 39 |
87| 10 | 5 | 7 | 63 |
88| 11 | 6 | 1 | 96 |
89| 12 | 7 | 1 | 86 |
90| 13 | 7 | 7 | 83 |
91| 14 | 8 | 4 | 57 |
92| 15 | 8 | 3 | 93 |
93+----+-------+----------+-------+
9415 rows in set (0.00 sec)
95
96MariaDB [hellodb]> select *from v_score;
97+--------------+----------------+--------------+
98| 学生姓名 | 课程名称 | 考试成绩 |
99+--------------+----------------+--------------+
100| Shi Zhongyu | Kuihua Baodian | 88 |
101| Shi Zhongyu | Weituo Zhang | 93 |
102| Shi Potian | Kuihua Baodian | 47 |
103| Shi Potian | Daiyu Zanghua | 97 |
104| Xie Yanke | Kuihua Baodian | 88 |
105| Xie Yanke | Weituo Zhang | 75 |
106| Ding Dian | Daiyu Zanghua | 71 |
107| Ding Dian | Kuihua Baodian | 89 |
108| Yu Yutong | Hamo Gong | 39 |
109| Yu Yutong | Dagou Bangfa | 63 |
110| Shi Qing | Hamo Gong | 96 |
111| Xi Ren | Hamo Gong | 86 |
112| Xi Ren | Dagou Bangfa | 83 |
113| Lin Daiyu | Taiji Quan | 57 |
114| Lin Daiyu | Jinshe Jianfa | 93 |
115+--------------+----------------+--------------+
11615 rows in set (0.00 sec)
117
118
119
120
121##问题:如果我更改了视图里某条信息,那么原来表里的信息会变化吗?(会的)
122MariaDB [hellodb]> select *from v_score;
123+--------------+----------------+--------------+
124| 学生姓名 | 课程名称 | 考试成绩 |
125+--------------+----------------+--------------+
126| Shi Zhongyu | Kuihua Baodian | 88 |
127| Shi Zhongyu | Weituo Zhang | 93 |
128| Shi Potian | Kuihua Baodian | 47 |
129| Shi Potian | Daiyu Zanghua | 97 |
130| Xie Yanke | Kuihua Baodian | 88 |
131| Xie Yanke | Weituo Zhang | 75 |
132| Ding Dian | Daiyu Zanghua | 71 |
133| Ding Dian | Kuihua Baodian | 89 |
134| Yu Yutong | Hamo Gong | 39 |
135| Yu Yutong | Dagou Bangfa | 63 |
136| Shi Qing | Hamo Gong | 96 |
137| Xi Ren | Hamo Gong | 86 |
138| Xi Ren | Dagou Bangfa | 83 |
139| Lin Daiyu | Taiji Quan | 57 |
140| Lin Daiyu | Jinshe Jianfa | 93 |
141+--------------+----------------+--------------+
14215 rows in set (0.00 sec)
143
144MariaDB [hellodb]> update v_score set 考试成绩=99 where 考试成绩=88;
145Query OK, 2 rows affected (0.01 sec)
146Rows matched: 2 Changed: 2 Warnings: 0
147
148MariaDB [hellodb]> select *from v_score;
149+--------------+----------------+--------------+
150| 学生姓名 | 课程名称 | 考试成绩 |
151+--------------+----------------+--------------+
152| Shi Zhongyu | Kuihua Baodian | 99 |
153| Shi Zhongyu | Weituo Zhang | 93 |
154| Shi Potian | Kuihua Baodian | 47 |
155| Shi Potian | Daiyu Zanghua | 97 |
156| Xie Yanke | Kuihua Baodian | 99 |
157| Xie Yanke | Weituo Zhang | 75 |
158| Ding Dian | Daiyu Zanghua | 71 |
159| Ding Dian | Kuihua Baodian | 89 |
160| Yu Yutong | Hamo Gong | 39 |
161| Yu Yutong | Dagou Bangfa | 63 |
162| Shi Qing | Hamo Gong | 96 |
163| Xi Ren | Hamo Gong | 86 |
164| Xi Ren | Dagou Bangfa | 83 |
165| Lin Daiyu | Taiji Quan | 57 |
166| Lin Daiyu | Jinshe Jianfa | 93 |
167+--------------+----------------+--------------+
16815 rows in set (0.00 sec)
169
170MariaDB [hellodb]> select *from scores;
171+----+-------+----------+-------+
172| ID | StuID | CourseID | Score |
173+----+-------+----------+-------+
174| 1 | 1 | 2 | 99 |
175| 2 | 1 | 6 | 93 |
176| 3 | 2 | 2 | 47 |
177| 4 | 2 | 5 | 97 |
178| 5 | 3 | 2 | 99 |
179| 6 | 3 | 6 | 75 |
180| 7 | 4 | 5 | 71 |
181| 8 | 4 | 2 | 89 |
182| 9 | 5 | 1 | 39 |
183| 10 | 5 | 7 | 63 |
184| 11 | 6 | 1 | 96 |
185| 12 | 7 | 1 | 86 |
186| 13 | 7 | 7 | 83 |
187| 14 | 8 | 4 | 57 |
188| 15 | 8 | 3 | 93 |
189+----+-------+----------+-------+
19015 rows in set (0.00 sec)
191
192
193
194##注意:创建视图时,原来表的查询结果字段一定要不同,否则会导致创建视图失败的。
195MariaDB [hellodb]> select s.name,t.name from students s inner join teachers t on s.teacherid=t.tid;
196+-------------+---------------+
197| name | name |
198+-------------+---------------+
199| Yu Yutong | Song Jiang |
200| Shi Zhongyu | Miejue Shitai |
201| Ding Dian | Lin Chaoying |
202+-------------+---------------+
2033 rows in set (0.00 sec)
204
205MariaDB [hellodb]> create view v_testview as select s.name,t.name from students s inner join teachers t on s.teacherid=t.tid;
206ERROR 1060 (42S21): Duplicate column name 'name' ##报错了
207MariaDB [hellodb]>
208
209
210##因此,这里通过创建别名来实现
211MariaDB [hellodb]> select s.name stu_name,t.name tea_name from students s inner join teachers t on s.teacherid=t.tid;
212+-------------+---------------+
213| stu_name | tea_name |
214+-------------+---------------+
215| Yu Yutong | Song Jiang |
216| Shi Zhongyu | Miejue Shitai |
217| Ding Dian | Lin Chaoying |
218+-------------+---------------+
2193 rows in set (0.00 sec)
220
221MariaDB [hellodb]> create view v_stu_tea_view as select s.name stu_name,t.name tea_name from students s inner join teachers t on s.teacherid=t.tid;
222Query OK, 0 rows affected (0.00 sec)
223
224MariaDB [hellodb]> select *from v_stu_tea_view;
225+-------------+---------------+
226| stu_name | tea_name |
227+-------------+---------------+
228| Yu Yutong | Song Jiang |
229| Shi Zhongyu | Miejue Shitai |
230| Ding Dian | Lin Chaoying |
231+-------------+---------------+
2323 rows in set (0.00 sec)
233
234
235
236
237##视图本身不存放数据;
238MariaDB [hellodb]> show tables;
239+-------------------+
240| Tables_in_hellodb |
241+-------------------+
242| classes |
243| coc |
244| courses |
245| emp |
246| scores |
247| students |
248| teachers |
249| teachers2 |
250| teachers3 |
251| toc |
252| v_score |
253| v_stu_tea_view |
254+-------------------+
25512 rows in set (0.00 sec)
256MariaDB [hellodb]> desc v_stu_tea_view;
257+----------+--------------+------+-----+---------+-------+
258| Field | Type | Null | Key | Default | Extra |
259+----------+--------------+------+-----+---------+-------+
260| stu_name | varchar(50) | NO | | NULL | |
261| tea_name | varchar(100) | NO | | NULL | |
262+----------+--------------+------+-----+---------+-------+
2632 rows in set (0.00 sec)

- 范例:如何查看某张表是否是view呢?
1MariaDB [hellodb]> show table status like 'v_stu_tea_view'\G
2*************************** 1. row ***************************
3 Name: v_stu_tea_view
4 Engine: NULL
5 Version: NULL
6 Row_format: NULL
7 Rows: NULL
8 Avg_row_length: NULL
9 Data_length: NULL
10Max_data_length: NULL
11 Index_length: NULL
12 Data_free: NULL
13 Auto_increment: NULL
14 Create_time: NULL
15 Update_time: NULL
16 Check_time: NULL
17 Collation: NULL
18 Checksum: NULL
19 Create_options: NULL
20 Comment: VIEW ##look here 😜
211 row in set (0.00 sec)
22
23MariaDB [hellodb]> show table status like 'students'\G
24*************************** 1. row ***************************
25 Name: students
26 Engine: InnoDB
27 Version: 10
28 Row_format: Compact
29 Rows: 25
30 Avg_row_length: 655
31 Data_length: 16384
32Max_data_length: 0
33 Index_length: 0
34 Data_free: 9437184
35 Auto_increment: 26
36 Create_time: 2024-05-03 07:16:29
37 Update_time: NULL
38 Check_time: NULL
39 Collation: utf8_general_ci
40 Checksum: NULL
41 Create_options:
42 Comment:
431 row in set (0.00 sec)
- 范例:查看数据库下所有表/视图的状态
1MariaDB [hellodb]> show table status from hellodb\G
2……
3*************************** 10. row ***************************
4 Name: toc
5 Engine: InnoDB
6 Version: 10
7 Row_format: Compact
8 Rows: 0
9 Avg_row_length: 0
10 Data_length: 16384
11Max_data_length: 0
12 Index_length: 0
13 Data_free: 9437184
14 Auto_increment: 1
15 Create_time: 2024-05-03 07:16:29
16 Update_time: NULL
17 Check_time: NULL
18 Collation: utf8_general_ci
19 Checksum: NULL
20 Create_options:
21 Comment:
22*************************** 11. row ***************************
23 Name: v_score
24 Engine: NULL
25 Version: NULL
26 Row_format: NULL
27 Rows: NULL
28 Avg_row_length: NULL
29 Data_length: NULL
30Max_data_length: NULL
31 Index_length: NULL
32 Data_free: NULL
33 Auto_increment: NULL
34 Create_time: NULL
35 Update_time: NULL
36 Check_time: NULL
37 Collation: NULL
38 Checksum: NULL
39 Create_options: NULL
40 Comment: VIEW
41*************************** 12. row ***************************
42 Name: v_stu_tea_view
43 Engine: NULL
44 Version: NULL
45 Row_format: NULL
46 Rows: NULL
47 Avg_row_length: NULL
48 Data_length: NULL
49Max_data_length: NULL
50 Index_length: NULL
51 Data_free: NULL
52 Auto_increment: NULL
53 Create_time: NULL
54 Update_time: NULL
55 Check_time: NULL
56 Collation: NULL
57 Checksum: NULL
58 Create_options: NULL
59 Comment: VIEW
6012 rows in set (0.00 sec)
FUNCTION 函数
测试环境里可以使用函数,但生产力不推荐使用函数来实现这么长的sql功能。
所以,在淘宝、阿里巴巴手册里,规定禁止使用函数、存储过程、视图等功能。
函数:分为系统内置函数和自定义函数
- 系统内置函数参考:https://dev.mysql.com/doc/refman/5.7/en/func-op-summary-ref.html
- 自定义函数:user-defined function UDF,保存在mysql.proc表中
注意:是mysql数据库里的proc表。
创建UDF语法:
1CREATE [AGGREGATE] FUNCTION function_name(parameter_name type,[parameter_name
2type,...])
3 RETURNS {STRING|INTEGER|REAL}
4 runtime_body
说明:
- 参数可以有多个,也可以没有参数;
- 无论有无参数,小括号()是必须的;
- 必须有且只有一个返回值;
查看函数列表:
1SHOW FUNCTION STATUS;
查看函数定义:
1SHOW CREATE FUNCTION function_name
删除删除UDF:
1DROP FUNCTION function_name
调用自定义函数语法:
1SELECT function_name(parameter_value,...)
- 范例:统计一张表有多少条记录,
count()函数(内置函数)
1MariaDB [hellodb]> select *from students;
2+-------+---------------+-----+--------+---------+-----------+
3| StuID | Name | Age | Gender | ClassID | TeacherID |
4+-------+---------------+-----+--------+---------+-----------+
5| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
6| 2 | Shi Potian | 22 | M | 1 | 7 |
7| 3 | Xie Yanke | 53 | M | 2 | 16 |
8| 4 | Ding Dian | 32 | M | 4 | 4 |
9| 5 | Yu Yutong | 26 | M | 3 | 1 |
10| 6 | Shi Qing | 46 | M | 5 | NULL |
11| 7 | Xi Ren | 19 | F | 3 | NULL |
12| 8 | Lin Daiyu | 17 | F | 7 | NULL |
13| 9 | Ren Yingying | 20 | F | 6 | NULL |
14| 10 | Yue Lingshan | 19 | F | 3 | NULL |
15| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
16| 12 | Wen Qingqing | 19 | F | 1 | NULL |
17| 13 | Tian Boguang | 33 | M | 2 | NULL |
18| 14 | Lu Wushuang | 17 | F | 3 | NULL |
19| 15 | Duan Yu | 19 | M | 4 | NULL |
20| 16 | Xu Zhu | 21 | M | 1 | NULL |
21| 17 | Lin Chong | 25 | M | 4 | NULL |
22| 18 | Hua Rong | 23 | M | 7 | NULL |
23| 19 | Xue Baochai | 18 | F | 6 | NULL |
24| 20 | Diao Chan | 19 | F | 7 | NULL |
25| 21 | Huang Yueying | 22 | F | 6 | NULL |
26| 22 | Xiao Qiao | 20 | F | 1 | NULL |
27| 23 | Ma Chao | 23 | M | 4 | NULL |
28| 24 | Xu Xian | 27 | M | NULL | NULL |
29| 25 | Sun Dasheng | 100 | M | NULL | NULL |
30+-------+---------------+-----+--------+---------+-----------+
3125 rows in set (0.00 sec)
32##或者加上主键,因为主键不允许为空。
33MariaDB [hellodb]> select count(stuid) from students;
34+--------------+
35| count(stuid) |
36+--------------+
37| 25 |
38+--------------+
391 row in set (0.00 sec)
40
41
42##查询某张表有多少条记录
43MariaDB [hellodb]> select count(*) from students;
44+----------+
45| count(*) |
46+----------+
47| 25 |
48+----------+
491 row in set (0.00 sec)
50
51
52##也可以查询表里面的某个字段
53MariaDB [hellodb]> select count(stuid) from students;
54+--------------+
55| count(stuid) |
56+--------------+
57| 25 |
58+--------------+
591 row in set (0.00 sec)
60
61MariaDB [hellodb]> select count(classid) from students; ##注意:count函数这个是返回非空数据,空是不计数的。
62+----------------+
63| count(classid) |
64+----------------+
65| 23 |
66+----------------+
671 row in set (0.00 sec)
68
69MariaDB [hellodb]> select count(teacherid) from students;
70+------------------+
71| count(teacherid) |
72+------------------+
73| 5 |
74+------------------+
751 row in set (0.00 sec)
- 范例:无参UDF
1MariaDB [hellodb]> SHOW FUNCTION STATUS;
2Empty set (0.00 sec)
3
4MariaDB [hellodb]> CREATE FUNCTION simpleFun() RETURNS VARCHAR(20) RETURN "Hello World";
5Query OK, 0 rows affected (0.00 sec)
6
7MariaDB [hellodb]> SHOW FUNCTION STATUS\G
8*************************** 1. row ***************************
9 Db: hellodb
10 Name: simpleFun
11 Type: FUNCTION
12 Definer: root@localhost
13 Modified: 2024-05-07 07:33:53
14 Created: 2024-05-07 07:33:53
15 Security_type: DEFINER
16 Comment:
17character_set_client: utf8
18collation_connection: utf8_general_ci
19 Database Collation: utf8_general_ci
201 row in set (0.00 sec)
21
22
23MariaDB [hellodb]> select simpleFun();
24+-------------+
25| simpleFun() |
26+-------------+
27| Hello World |
28+-------------+
291 row in set (0.00 sec)
30
31
32##函数是存放在mysql数据库的proc表里的
33[root@test mysql]# pwd
34/var/lib/mysql/mysql
35[root@test mysql]# ll -t
36total 1000
37-rw-rw---- 1 mysql mysql 292 May 7 07:27 proc.MYD
38-rw-rw---- 1 mysql mysql 4096 May 7 07:27 proc.MYI
39MariaDB [mysql]> select *from mysql.proc\G
40*************************** 1. row ***************************
41 db: mysql
42 name: simpleFun
43 type: FUNCTION
44 specific_name: simpleFun
45 language: SQL
46 sql_data_access: CONTAINS_SQL
47 is_deterministic: NO
48 security_type: DEFINER
49 param_list:
50 returns: varchar(20) CHARSET latin1
51 body: RETURN "Hello World"
52 definer: root@localhost
53 created: 2024-05-07 07:27:59
54 modified: 2024-05-07 07:27:59
55 sql_mode:
56 comment:
57character_set_client: utf8
58collation_connection: utf8_general_ci
59 db_collation: latin1_swedish_ci
60 body_utf8: RETURN "Hello World"
611 row in set (0.00 sec)
62
63
64##注意:函数是有归属区分的
65MariaDB [hellodb]> use mysql;
66Reading table information for completion of table and column names
67You can turn off this feature to get a quicker startup with -A
68
69Database changed
70MariaDB [mysql]> select simpleFun();
71ERROR 1305 (42000): FUNCTION mysql.simpleFun does not exist
72MariaDB [mysql]> select hellodb.simpleFun();
73+---------------------+
74| hellodb.simpleFun() |
75+---------------------+
76| Hello World |
77+---------------------+
781 row in set (0.00 sec)
79
80
81##删除函数
82MariaDB [hellodb]> d
83Query OK, 0 rows aff
84
85
86MariaDB [hellodb]> s
87Empty set (0.00 sec)
- 范例:有参UDF
1#有参数UDF
2DELIMITER //
3CREATE FUNCTION deleteById(id SMALLINT UNSIGNED) RETURNS VARCHAR(20)
4BEGIN
5 DELETE FROM students WHERE stuid = id;
6 RETURN (SELECT COUNT(*) FROM students);
7END//
8DELIMITER ;
9
10##说明:DELIMITER // 是用来修改数据库分隔符的;
1DELIMITER //
2CREATE FUNCTION deleteById(id SMALLINT UNSIGNED) RETURNS VARCHAR(20)
3BEGIN
4 DELETE FROM students WHERE stuid = id;
5 RETURN (SELECT COUNT(*) FROM students);
6END//
7DELIMITER ;
8
9
10MariaDB [hellodb]> show function status\G
11*************************** 1. row ***************************
12 Db: hellodb
13 Name: deleteById
14 Type: FUNCTION
15 Definer: root@localhost
16 Modified: 2024-05-07 07:50:35
17 Created: 2024-05-07 07:50:35
18 Security_type: DEFINER
19 Comment:
20character_set_client: utf8
21collation_connection: utf8_general_ci
22 Database Collation: utf8_general_ci
231 row in set (0.00 sec)
24
25
26##删除第25个同学
27MariaDB [hellodb]> select deleteById(25);
28+----------------+
29| deleteById(25) |
30+----------------+
31| 24 |
32+----------------+
331 row in set (0.00 sec)
34
35MariaDB [hellodb]> select *from students;
36+-------+---------------+-----+--------+---------+-----------+
37| StuID | Name | Age | Gender | ClassID | TeacherID |
38+-------+---------------+-----+--------+---------+-----------+
39| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
40| 2 | Shi Potian | 22 | M | 1 | 7 |
41| 3 | Xie Yanke | 53 | M | 2 | 16 |
42| 4 | Ding Dian | 32 | M | 4 | 4 |
43| 5 | Yu Yutong | 26 | M | 3 | 1 |
44| 6 | Shi Qing | 46 | M | 5 | NULL |
45| 7 | Xi Ren | 19 | F | 3 | NULL |
46| 8 | Lin Daiyu | 17 | F | 7 | NULL |
47| 9 | Ren Yingying | 20 | F | 6 | NULL |
48| 10 | Yue Lingshan | 19 | F | 3 | NULL |
49| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
50| 12 | Wen Qingqing | 19 | F | 1 | NULL |
51| 13 | Tian Boguang | 33 | M | 2 | NULL |
52| 14 | Lu Wushuang | 17 | F | 3 | NULL |
53| 15 | Duan Yu | 19 | M | 4 | NULL |
54| 16 | Xu Zhu | 21 | M | 1 | NULL |
55| 17 | Lin Chong | 25 | M | 4 | NULL |
56| 18 | Hua Rong | 23 | M | 7 | NULL |
57| 19 | Xue Baochai | 18 | F | 6 | NULL |
58| 20 | Diao Chan | 19 | F | 7 | NULL |
59| 21 | Huang Yueying | 22 | F | 6 | NULL |
60| 22 | Xiao Qiao | 20 | F | 1 | NULL |
61| 23 | Ma Chao | 23 | M | 4 | NULL |
62| 24 | Xu Xian | 27 | M | NULL | NULL |
63+-------+---------------+-----+--------+---------+-----------+
6424 rows in set (0.00 sec)
65
66
67##删除第10号同学
68MariaDB [hellodb]> select deleteById(10);
69+----------------+
70| deleteById(10) |
71+----------------+
72| 23 |
73+----------------+
741 row in set (0.01 sec)
75
76MariaDB [hellodb]> select *from students;
77+-------+---------------+-----+--------+---------+-----------+
78| StuID | Name | Age | Gender | ClassID | TeacherID |
79+-------+---------------+-----+--------+---------+-----------+
80| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
81| 2 | Shi Potian | 22 | M | 1 | 7 |
82| 3 | Xie Yanke | 53 | M | 2 | 16 |
83| 4 | Ding Dian | 32 | M | 4 | 4 |
84| 5 | Yu Yutong | 26 | M | 3 | 1 |
85| 6 | Shi Qing | 46 | M | 5 | NULL |
86| 7 | Xi Ren | 19 | F | 3 | NULL |
87| 8 | Lin Daiyu | 17 | F | 7 | NULL |
88| 9 | Ren Yingying | 20 | F | 6 | NULL |
89| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
90| 12 | Wen Qingqing | 19 | F | 1 | NULL |
91| 13 | Tian Boguang | 33 | M | 2 | NULL |
92| 14 | Lu Wushuang | 17 | F | 3 | NULL |
93| 15 | Duan Yu | 19 | M | 4 | NULL |
94| 16 | Xu Zhu | 21 | M | 1 | NULL |
95| 17 | Lin Chong | 25 | M | 4 | NULL |
96| 18 | Hua Rong | 23 | M | 7 | NULL |
97| 19 | Xue Baochai | 18 | F | 6 | NULL |
98| 20 | Diao Chan | 19 | F | 7 | NULL |
99| 21 | Huang Yueying | 22 | F | 6 | NULL |
100| 22 | Xiao Qiao | 20 | F | 1 | NULL |
101| 23 | Ma Chao | 23 | M | 4 | NULL |
102| 24 | Xu Xian | 27 | M | NULL | NULL |
103+-------+---------------+-----+--------+---------+-----------+
10423 rows in set (0.00 sec)
MySQL中的变量
两种变量:系统内置变量和用户自定义变量
系统变量:MySQL数据库中内置的变量,可用@@var_name引用
用户自定义变量分为以下两种
- 普通变量:在当前会话中有效,可用@var_name引用
- 局部变量:在函数或存储过程内才有效,需要用DECLARE 声明,之后直接用 var_name引用
范例:查看所有系统变量
1MariaDB [hellodb]> show variables\G
2……
3*************************** 431. row ***************************
4Variable_name: version_compile_os
5 Value: Linux
6*************************** 432. row ***************************
7Variable_name: wait_timeout
8 Value: 28800
9*************************** 433. row ***************************
10Variable_name: warning_count
11 Value: 0
12433 rows in set (0.01 sec)
- 范例:查询系统变量值
1MariaDB [hellodb]> select @@port;
2+--------+
3| @@port |
4+--------+
5| 3306 |
6+--------+
71 row in set (0.00 sec)
8
9MariaDB [hellodb]> select @@hostname;
10+-------------------------+
11| @@hostname |
12+-------------------------+
13| iZbp1in7y9nitzcajdv0ufZ |
14+-------------------------+
151 row in set (0.00 sec)
- 范例:concat函数(用于连接2个字符串)
1MariaDB [hellodb]> select concat('wang',100);
2+--------------------+
3| concat('wang',100) |
4+--------------------+
5| wang100 |
6+--------------------+
71 row in set (0.00 sec)
8
9MariaDB [hellodb]> select concat('wang',100,'xyy');
10+--------------------------+
11| concat('wang',100,'xyy') |
12+--------------------------+
13| wang100xyy |
14+--------------------------+
151 row in set (0.00 sec)
自定义函数中定义局部变量语法
1DECLARE 变量1[,变量2,... ]变量类型 [DEFAULT 默认值]
说明:局部变量的作用范围是在BEGIN…END程序中,而且定义局部变量语句必须在BEGIN…END的第一行定义。
- 范例:自定义函数中定义局部变量语法
1DELIMITER //
2CREATE FUNCTION addTwoNumber(x SMALLINT UNSIGNED, y SMALLINT UNSIGNED)
3RETURNS SMALLINT
4BEGIN
5 DECLARE a, b SMALLINT UNSIGNED;
6 SET a = x, b = y;
7 RETURN a+b;
8END//
9DELIMITER ;
10
11
12#测试过程
13MariaDB [hellodb]> DELIMITER //
14MariaDB [hellodb]> CREATE FUNCTION addTwoNumber(x SMALLINT UNSIGNED, y SMALLINT UNSIGNED)
15 -> RETURNS SMALLINT
16 -> BEGIN
17 -> DECLARE a, b SMALLINT UNSIGNED;
18 -> SET a = x, b = y;
19 -> RETURN a+b;
20 -> END//
21Query OK, 0 rows affected (0.00 sec)
22
23MariaDB [hellodb]> DELIMITER ;
24MariaDB [hellodb]>
25MariaDB [hellodb]> select addTwoNumber(10,20);
26+---------------------+
27| addTwoNumber(10,20) |
28+---------------------+
29| 30 |
30+---------------------+
311 row in set (0.00 sec)
32
33MariaDB [hellodb]> select @@a;
34ERROR 1193 (HY000): Unknown system variable 'a'
35MariaDB [hellodb]> select @a;
36+------+
37| @a |
38+------+
39| NULL |
40+------+
411 row in set (0.00 sec)
42
43MariaDB [hellodb]>
为变量赋值语法
1SET parameter_name = value[,parameter_name = value...]
2SELECT INTO parameter_name
范例:
1.....
2DECLARE x int;
3SELECT COUNT(*) FROM tdb_name INTO x;
4RETURN x;
5END//
- 范例:自定义的普通变量
1MariaDB [hellodb]> select @a;
2+------+
3| @a |
4+------+
5| NULL |
6+------+
71 row in set (0.00 sec)
8
9MariaDB [hellodb]> set @var1='hello';
10Query OK, 0 rows affected (0.00 sec)
11
12MariaDB [hellodb]> select @var1;
13+-------+
14| @var1 |
15+-------+
16| hello |
17+-------+
181 row in set (0.00 sec)
19
20##另开一个终端:
21MariaDB [hellodb]> select @var1;
22+-------+
23| @var1 |
24+-------+
25| NULL |
26+-------+
271 row in set (0.00 sec)
28
29
30
31MariaDB [hellodb]> select max(age) from students into @age;
32Query OK, 1 row affected (0.00 sec)
33
34MariaDB [hellodb]> select @age;
35+------+
36| @age |
37+------+
38| 53 |
39+------+
401 row in set (0.00 sec)
41MariaDB [hellodb]> set @age=100;
42Query OK, 0 rows affected (0.00 sec)
43
44MariaDB [hellodb]> select @age;
45+------+
46| @age |
47+------+
48| 100 |
49+------+
501 row in set (0.00 sec)
PROCEDURE 存储过程
存储过程:多表SQL的语句的集合,可以独立执行,存储过程保存在mysql.proc表中
存储过程优势:
存储过程把经常使用的SQL语句或业务逻辑封装起来,预编译保存在数据库中,当需要时从数据库中直接调用,省去了编译的过程,提高了运行速度,同时降低网络数据传输量
存储过程与自定义函数的区别
存储过程实现的过程要复杂一些,而函数的针对性较强
存储过程可以有多个返回值,而自定义函数只有一个返回值
存储过程一般可独立执行,而函数往往是作为其他SQL语句的一部分来使用
创建存储过程
1CREATE PROCEDURE sp_name ([ proc_parameter [,proc_parameter ...]])
2routime_body
3proc_parameter : [IN|OUT|INOUT] parameter_name type
说明:其中IN表示输入参数,OUT表示输出参数,INOUT表示既可以输入也可以输出;param_name表示参数名称;type表示参数的类型
查看存储过程列表
1SHOW PROCEDURE STATUS;
查看存储过程定义
1SHOW CREATE PROCEDURE sp_name
调用存储过程
1CALL sp_name ([ proc_parameter [,proc_parameter ...]])
说明:当无参时,可以省略"()",当有参数时,不可省略"()”
存储过程修改
ALTER语句修改存储过程只能修改存储过程的注释等无关紧要的东西,不能修改存储过程体,所以要修改
存储过程,方法就是删除重建
1DROP PROCEDURE [IF EXISTS] sp_name
- 范例:PROCEDURE 存储过程(创建无参存储过程)
1# 创建无参存储过程
2delimiter //
3CREATE PROCEDURE showTime()
4BEGIN
5 SELECT now();
6END//
7delimiter ;
8
9CALL showTime;
10
11
12##测试过程
13MariaDB [hellodb]> delimiter //
14MariaDB [hellodb]> CREATE PROCEDURE showTime()
15 -> BEGIN
16 -> SELECT now();
17 -> END//
18Query OK, 0 rows affected (0.00 sec)
19
20MariaDB [hellodb]> delimiter ;
21
22MariaDB [hellodb]> call showtime;
23+---------------------+
24| now() |
25+---------------------+
26| 2024-05-10 05:35:20 |
27+---------------------+
281 row in set (0.00 sec)
29
30Query OK, 0 rows affected (0.00 sec)
- 范例:PROCEDURE 存储过程(创建含参存储过程:只有一个IN参数)
1#创建含参存储过程:只有一个IN参数
2delimiter //
3CREATE PROCEDURE selectById(IN id SMALLINT UNSIGNED)
4BEGIN
5 SELECT * FROM students WHERE stuid = id;
6END//
7delimiter ;
8
9call selectById(2);
10
11
12##测试过程
13MariaDB [hellodb]> delimiter //
14MariaDB [hellodb]> CREATE PROCEDURE selectById(IN id SMALLINT UNSIGNED)
15 -> BEGIN
16 -> SELECT * FROM students WHERE stuid = id;
17 -> END//
18Query OK, 0 rows affected (0.00 sec)
19
20MariaDB [hellodb]> delimiter ;
21MariaDB [hellodb]>
22MariaDB [hellodb]> call selectById(3);
23+-------+-----------+-----+--------+---------+-----------+
24| StuID | Name | Age | Gender | ClassID | TeacherID |
25+-------+-----------+-----+--------+---------+-----------+
26| 3 | Xie Yanke | 53 | M | 2 | 16 |
27+-------+-----------+-----+--------+---------+-----------+
281 row in set (0.00 sec)
29
30Query OK, 0 rows affected (0.00 sec)
- 范例:
1delimiter //
2CREATE PROCEDURE dorepeat(n INT)
3BEGIN
4 SET @i = 0;
5 SET @sum = 0;
6 REPEAT SET @sum = @sum+@i;
7 SET @i = @i + 1;
8 UNTIL @i > n END REPEAT;
9END//
10delimiter ;
11CALL dorepeat(100);
12
13SELECT @sum;
14
15##测试过程
16MariaDB [hellodb]> delimiter //
17MariaDB [hellodb]> CREATE PROCEDURE dorepeat(n INT)
18 -> BEGIN
19 -> SET @i = 0;
20 -> SET @sum = 0;
21 -> REPEAT SET @sum = @sum+@i;
22 -> SET @i = @i + 1;
23 -> UNTIL @i > n END REPEAT;
24 -> END//
25Query OK, 0 rows affected (0.00 sec)
26
27MariaDB [hellodb]> delimiter ;
28MariaDB [hellodb]> CALL dorepeat(100);
29Query OK, 0 rows affected (0.00 sec)
30
31MariaDB [hellodb]>
32MariaDB [hellodb]> select @sum;
33+------+
34| @sum |
35+------+
36| 5050 |
37+------+
381 row in set (0.00 sec)
39
40MariaDB [hellodb]> set @sum=200;
41Query OK, 0 rows affected (0.00 sec)
42
43MariaDB [hellodb]> select @sum;
44+------+
45| @sum |
46+------+
47| 200 |
48+------+
491 row in set (0.00 sec)
- 范例
1#创建含参存储过程:包含IN参数和OUT参数
2delimiter //
3CREATE PROCEDURE deleteById(IN id SMALLINT UNSIGNED, OUT num SMALLINT UNSIGNED)
4BEGIN
5DELETE FROM students WHERE stuid >= id;
6SELECT row_count() into num;
7END//
8delimiter ;
9call deleteById(2,@Line);
10SELECT @Line;
11
12#说明:创建存储过程deleteById,包含一个IN参数和一个OUT参数.调用时,传入删除的ID和保存被修改的行
13数值的用户变量@Line,select @Line;输出被影响行数
14#row_count() 系统内置函数,用于存放前一条SQL修改过的表的记录数
测试过程:
1MariaDB [hellodb]> delimiter //
2MariaDB [hellodb]> CREATE PROCEDURE deleteById(IN id SMALLINT UNSIGNED, OUT num SMALLINT UNSIGNED)
3 -> BEGIN
4 -> DELETE FROM students WHERE stuid >= id;
5 -> SELECT row_count() into num;
6 -> END//
7Query OK, 0 rows affected (0.00 sec)
8
9MariaDB [hellodb]> delimiter ;
10MariaDB [hellodb]> call deleteById(2,@Line);
11Query OK, 1 row affected (0.00 sec)
12
13MariaDB [hellodb]> SELECT @Line;
14+-------+
15| @Line |
16+-------+
17| 22 |
18+-------+
191 row in set (0.00 sec)
20
21MariaDB [hellodb]>
流程控制
存储过程和函数中可以使用流程控制来控制语句的执行
- IF:用来进行条件判断。根据是否满足条件,执行不同语句
- CASE:用来进行条件判断,可实现比IF语句更复杂的条件判断
- LOOP:重复执行特定的语句,实现一个简单的循环
- LEAVE:用于跳出循环控制,相当于SHELL中break
- ITERATE:跳出本次循环,然后直接进入下一次循环,相当于SHELL中continue
- REPEAT:有条件控制的循环语句。当满足特定条件时,就会跳出循环语句
- WHILE:有条件控制的循环语句
TRIGGER触发器
触发器的执行不是由程序调用,也不是由手工启动,而是由事件来触发、激活从而实现执行。
创建触发器
1CREATE [DEFINER = { user | CURRENT_USER }]
2 TRIGGER trigger_name
3 trigger_time trigger_event
4 ON tbl_name FOR EACH ROW
5 trigger_body
说明:
1trigger_name:触发器的名称
2
3trigger_time:{ BEFORE | AFTER },表示在事件之前或之后触发
4
5trigger_event::{ INSERT |UPDATE | DELETE },触发的具体事件
6
7tbl_name:该触发器作用在表名
查看触发器
1#在当前数据库对应的目录下,可以查看到新生成的相关文件:trigger_name.TRN,table_name.TRG
2SHOW TRIGGERS;
3#查询系统表information_schema.triggers的方式指定查询条件,查看指定的触发器信息。
4USE information_schema;
5SELECT * FROM triggers WHERE trigger_name='trigger_student_count_insert';
删除触发器
1DROP TRIGGER trigger_name;
- 范例
1#创建触发器,在向学生表INSERT数据时,学生数增加,DELETE学生时,学生数减少
2CREATE TABLE student_info (
3 stu_id INT(11) NOT NULL AUTO_INCREMENT ,
4 stu_name VARCHAR(255) DEFAULT NULL,
5 PRIMARY KEY (stu_id)
6);
7CREATE TABLE student_count (
8 student_count INT(11) DEFAULT 0
9);
10
11INSERT INTO student_count VALUES(0);
12
13
14
15CREATE TRIGGER trigger_student_count_insert
16AFTER INSERT
17ON student_info FOR EACH ROW
18UPDATE student_count SET student_count=student_count+1;
19
20CREATE TRIGGER trigger_student_count_delete
21AFTER DELETE
22ON student_info FOR EACH ROW
23UPDATE student_count SET student_count=student_count-1;
测试过程:
1MariaDB [hellodb]> CREATE TABLE student_info (
2 -> stu_id INT(11) NOT NULL AUTO_INCREMENT ,
3 -> stu_name VARCHAR(255) DEFAULT NULL,
4 -> PRIMARY KEY (stu_id)
5 -> );
6Query OK, 0 rows affected (0.00 sec)
7
8MariaDB [hellodb]> CREATE TABLE student_count (
9 -> student_count INT(11) DEFAULT 0
10 -> );
11Query OK, 0 rows affected (0.01 sec)
12
13MariaDB [hellodb]> select *from student_info;
14Empty set (0.00 sec)
15
16MariaDB [hellodb]> select *from student_count;
17Empty set (0.00 sec)
18
19
20
21MariaDB [hellodb]> INSERT INTO student_count VALUES(0);
22Query OK, 1 row affected (0.00 sec)
23
24
25
26##创建trigger
27MariaDB [hellodb]>
28MariaDB [hellodb]> CREATE TRIGGER trigger_student_count_insert
29 -> AFTER INSERT
30 -> ON student_info FOR EACH ROW
31 -> UPDATE student_count SET student_count=student_count+1;
32Query OK, 0 rows affected (0.00 sec)
33
34MariaDB [hellodb]>
35MariaDB [hellodb]> CREATE TRIGGER trigger_student_count_delete
36 -> AFTER DELETE
37 -> ON student_info FOR EACH ROW
38 -> UPDATE student_count SET student_count=student_count-1;
39Query OK, 0 rows affected (0.00 sec)
40
41
42
43##更新表
44MariaDB [hellodb]> insert student_info (stu_name)values('hg');
45Query OK, 1 row affected (0.00 sec)
46
47MariaDB [hellodb]> select *from student_info;
48+--------+----------+
49| stu_id | stu_name |
50+--------+----------+
51| 1 | hg |
52+--------+----------+
531 row in set (0.00 sec)
54
55MariaDB [hellodb]> select *from student_count;
56+---------------+
57| student_count |
58+---------------+
59| 1 |
60+---------------+
611 row in set (0.00 sec)
62MariaDB [hellodb]> insert student_info (stu_name)values('hg');
63Query OK, 1 row affected (0.00 sec)
64
65MariaDB [hellodb]> select *from student_info;
66+--------+----------+
67| stu_id | stu_name |
68+--------+----------+
69| 1 | hg |
70+--------+----------+
711 row in set (0.00 sec)
72
73MariaDB [hellodb]> select *from student_count;
74+---------------+
75| student_count |
76+---------------+
77| 1 |
78+---------------+
791 row in set (0.00 sec)
80
81
82
83MariaDB [hellodb]> delete from student_info where stu_id>=3;
84Query OK, 3 rows affected (0.00 sec)
85
86MariaDB [hellodb]> select *from student_info;
87+--------+----------+
88| stu_id | stu_name |
89+--------+----------+
90| 1 | hg |
91| 2 | xyy |
92+--------+----------+
932 rows in set (0.00 sec)
94
95MariaDB [hellodb]> select *from student_count;
96+---------------+
97| student_count |
98+---------------+
99| 2 |
100+---------------+
1011 row in set (0.00 sec)
102
103
104##底层存储位置:
105[root@test hellodb]# ll
106total 168
107-rw-rw---- 1 mysql mysql 8636 May 3 07:16 classes.frm
108-rw-rw---- 1 mysql mysql 8630 May 3 07:16 coc.frm
109-rw-rw---- 1 mysql mysql 8602 May 3 07:16 courses.frm
110-rw-rw---- 1 mysql mysql 61 May 3 07:16 db.opt
111-rw-rw---- 1 mysql mysql 8626 May 6 06:55 emp.frm
112-rw-rw---- 1 mysql mysql 8658 May 3 07:16 scores.frm
113-rw-rw---- 1 mysql mysql 8578 May 10 07:47 student_count.frm
114-rw-rw---- 1 mysql mysql 8602 May 10 07:47 student_info.frm
115-rw-rw---- 1 mysql mysql 560 May 10 07:47 student_info.TRG ##warning
116-rw-rw---- 1 mysql mysql 8736 May 3 07:16 students.frm
117-rw-rw---- 1 mysql mysql 8656 May 3 07:24 teachers2.frm
118-rw-rw---- 1 mysql mysql 8650 May 3 07:32 teachers3.frm
119-rw-rw---- 1 mysql mysql 8656 May 3 07:16 teachers.frm
120-rw-rw---- 1 mysql mysql 8622 May 3 07:16 toc.frm
121-rw-rw---- 1 mysql mysql 44 May 10 07:47 trigger_student_count_delete.TRN ##warning
122-rw-rw---- 1 mysql mysql 44 May 10 07:47 trigger_student_count_insert.TRN ##warning
123-rw-rw---- 1 mysql mysql 1016 May 7 06:09 v_score.frm
124-rw-rw---- 1 mysql mysql 695 May 7 06:31 v_stu_tea_view.frm
125
126[root@test hellodb]# cat student_info.TRG
127TYPE=TRIGGERS
128triggers='CREATE DEFINER=`root`@`localhost` TRIGGER trigger_student_count_insert\nAFTER INSERT\nON student_info FOR EACH ROW\nUPDATE student_count SET student_count=student_count+1' 'CREATE DEFINER=`root`@`localhost` TRIGGER trigger_student_count_delete\nAFTER DELETE\nON student_info FOR EACH ROW\nUPDATE student_count SET student_count=student_count-1'
129sql_modes=0 0
130definers='root@localhost' 'root@localhost'
131client_cs_names='utf8' 'utf8'
132connection_cl_names='utf8_general_ci' 'utf8_general_ci'
133db_cl_names='utf8_general_ci' 'utf8_general_ci'
134[root@test hellodb]# cat trigger_student_count_delete.TRN
135TYPE=TRIGGERNAME
136trigger_table=student_info
137[root@test hellodb]# cat trigger_student_count_insert.TRN
138TYPE=TRIGGERNAME
139trigger_table=student_info
Event 事件
类似于shell里的crontab。
Event 事件介绍
事件(event)是MySQL在相应的时刻调用的过程式数据库对象。一个事件可调用一次,也可周期性的启动,它由一个特定的线程来管理的,也就是所谓的“事件调度器”。
事件和触发器类似,都是在某些事情发生的时候启动。当数据库上启动一条语句的时候,触发器就启动了,而事件是根据调度事件来启动的。由于它们彼此相似,所以事件也称为临时性触发器。
事件取代了原先只能由操作系统的计划任务来执行的工作,而且MySQL的事件调度器可以精确到每秒钟执行一个任务,而操作系统的计划任务(如:Linux下的CRON或Windows下的任务计划)只能精确到每分钟执行一次。
事件的优缺点
优点:一些对数据定时性操作不再依赖外部程序,而直接使用数据库本身提供的功能,可以实现每秒钟执行一个任务,这在一些对实时性要求较高的环境下就非常实用
缺点:定时触发,不可以直接调用
Event 管理
相关变量和服务器选项
MySQL事件调度器event_scheduler负责调用事件,它默认是关闭的。这个调度器不断地监视一个事件是否要调用, 要创建事件,必须打开调度器
服务器系统变量和服务器选项:
event_scheduler:默认值为OFF,设置为ON才支持Event,并且系统自动打开专用的线程。
🍊 范例:开启和关闭event_scheduler
1#默认事件调度功能是关闭的
2MariaDB [hellodb]> select @@event_scheduler;
3+-------------------+
4| @@event_scheduler |
5+-------------------+
6| OFF |
7+-------------------+
81 row in set (0.00 sec)
9
10
11#临时开启事件调度功能
12MariaDB [hellodb]> set global event_scheduler=1;
13Query OK, 0 rows affected (0.00 sec)
14MariaDB [hellodb]> show processlist;
15+-----+-----------------+-----------+---------+---------+------+------------------------+------------------+----------+
16| Id | User | Host | db | Command | Time | State | Info | Progress |
17+-----+-----------------+-----------+---------+---------+------+------------------------+------------------+----------+
18| 402 | root | localhost | hellodb | Query | 0 | NULL | show processlist | 0.000 |
19| 403 | event_scheduler | localhost | NULL | Daemon | 13 | Waiting on empty queue | NULL | 0.000 |
20+-----+-----------------+-----------+---------+---------+------+------------------------+------------------+----------+
212 rows in set (0.00 sec)
22
23
24#临时关闭事件调度功能
25MariaDB [hellodb]> set global event_scheduler=0;
26Query OK, 0 rows affected (0.00 sec)
27
28MariaDB [hellodb]> show processlist;
29+-----+------+-----------+---------+---------+------+-------+------------------+----------+
30| Id | User | Host | db | Command | Time | State | Info | Progress |
31+-----+------+-----------+---------+---------+------+-------+------------------+----------+
32| 402 | root | localhost | hellodb | Query | 0 | NULL | show processlist | 0.000 |
33+-----+------+-----------+---------+---------+------+-------+------------------+----------+
341 row in set (0.00 sec)
35
36
37#持久开启事件调度
38#持久开启事件调度
39[root@centos8 ~]#vim /etc/my.cnf.d/mariadb-server.cnf
40[mysqld]
41event_scheduler=ON
42[root@centos8 ~]#systemctl restart mariadb
管理事件
create event 语句创建一个事件。每个事件由两个主要部分组成,第一部分是事件调度(event schedule),表示事件何时启动以及按什么频率启动,第二部分是事件动作(event action ),这是事件启动时执行的代码,事件的动作包含一条SQL语句,它可能是一个简单地insert或者update语句,也可以使一个存储过程或者 benin…end语句块,这两种情况允许我们执行多条SQL
一个事件可以是活动(打开)的或停止(关闭)的,活动意味着事件调度器检查事件动作是否必须调用,停止意味着事件的声明存储在目录中,但调度器不会检查它是否应该调用。在一个事件创建之后,它立即变为活动的,一个活动的事件可以执行一次或者多次。
范例
🍊 范例:创建立即启动事件
1#创建数据库
2MariaDB [hellodb]> create database testdb;
3Query OK, 1 row affected (0.01 sec)
4
5MariaDB [hellodb]> use testdb;
6Database changed
7
8
9#创建一个表记录每次事件调度的名字和事件戳
10MariaDB [testdb]> create table events_list(event_name varchar(20) not null, event_started timestamp not null);
11Query OK, 0 rows affected (0.00 sec)
12
13MariaDB [testdb]> select *from events_list;
14Empty set (0.00 sec)
15
16
17#临时关闭事件调度功能
18MariaDB [testdb]> set global event_scheduler=0;
19Query OK, 0 rows affected (0.00 sec)
20
21MariaDB [testdb]> show variables like 'event_scheduler';
22+-----------------+-------+
23| Variable_name | Value |
24+-----------------+-------+
25| event_scheduler | OFF |
26+-----------------+-------+
271 row in set (0.00 sec)
28
29
30#创建一次性事件
31MariaDB [testdb]> create event event_now on schedule at now() do insert into events_list values('event_now', now());
32Query OK, 0 rows affected (0.00 sec)
33
34
35#因为事件调度功能禁用,所有表中无记录
36MariaDB [testdb]> select *from events_list;
37Empty set (0.00 sec)
38
39
40#查看事件
41MariaDB [testdb]> show events\G
42*************************** 1. row ***************************
43 Db: testdb
44 Name: event_now
45 Definer: root@localhost
46 Time zone: SYSTEM
47 Type: ONE TIME
48 Execute at: 2024-05-12 07:38:12
49 Interval value: NULL
50 Interval field: NULL
51 Starts: NULL
52 Ends: NULL
53 Status: ENABLED
54 Originator: 0
55character_set_client: utf8
56collation_connection: utf8_general_ci
57 Database Collation: latin1_swedish_ci
581 row in set (0.00 sec)
59#任务计划存放在mysql.event表中
60MariaDB [testdb]> select *from mysql.event\G
61*************************** 1. row ***************************
62 db: testdb
63 name: event_now
64 body: insert into events_list values('event_now', now())
65 definer: root@localhost
66 execute_at: 2024-05-11 23:38:12
67 interval_value: NULL
68 interval_field: NULL
69 created: 2024-05-12 07:38:12
70 modified: 2024-05-12 07:38:12
71 last_executed: NULL
72 starts: NULL
73 ends: NULL
74 status: ENABLED
75 on_completion: DROP
76 sql_mode:
77 comment:
78 originator: 0
79 time_zone: SYSTEM
80character_set_client: utf8
81collation_connection: utf8_general_ci
82 db_collation: latin1_swedish_ci
83 body_utf8: insert into events_list values('event_now', now())
841 row in set (0.00 sec)
85#查看mysql数据库下对应event文件
86[root@test mysql]# ll -t
87total 1004
88-rw-rw---- 1 mysql mysql 216 May 12 07:38 event.MYD
89-rw-rw---- 1 mysql mysql 4096 May 12 07:38 event.MYI
90……
91
92
93#开启事件调度功能
94MariaDB [testdb]> set global event_scheduler=1;
95Query OK, 0 rows affected (0.00 sec)
96#事件立即执行,每秒插入一条记录
97MariaDB [testdb]> select *from events_list;
98+------------+---------------------+
99| event_name | event_started |
100+------------+---------------------+
101| event_now | 2024-05-12 07:41:42 |
102+------------+---------------------+
1031 row in set (0.00 sec)
104
105
106#事件执行完成后自动删除
107MariaDB [testdb]> show events;
108Empty set (0.00 sec)
🍊 范例:创建每秒启动的事件
1#创建事件
2MariaDB [testdb]> CREATE EVENT event_every_second ON SCHEDULE EVERY 1 SECOND DO INSERT INTO events_list VALUES('event_now', now());
3Query OK, 0 rows affected (0.00 sec)
4
5
6#查看事件
7MariaDB [testdb]> SHOW EVENTS\G
8*************************** 1. row ***************************
9 Db: testdb
10 Name: event_every_second
11 Definer: root@localhost
12 Time zone: SYSTEM
13 Type: RECURRING
14 Execute at: NULL
15 Interval value: 1
16 Interval field: SECOND
17 Starts: 2024-05-12 07:47:44
18 Ends: NULL
19 Status: ENABLED
20 Originator: 0
21character_set_client: utf8
22collation_connection: utf8_general_ci
23 Database Collation: latin1_swedish_ci
241 row in set (0.01 sec)
25
26MariaDB [testdb]> select *from mysql.event\G
27*************************** 1. row ***************************
28 db: testdb
29 name: event_every_second
30 body: INSERT INTO events_list VALUES('event_now', now())
31 definer: root@localhost
32 execute_at: NULL
33 interval_value: 1
34 interval_field: SECOND
35 created: 2024-05-12 07:47:44
36 modified: 2024-05-12 07:47:44
37 last_executed: 2024-05-11 23:48:08
38 starts: 2024-05-11 23:47:44
39 ends: NULL
40 status: ENABLED
41 on_completion: DROP
42 sql_mode:
43 comment:
44 originator: 0
45 time_zone: SYSTEM
46character_set_client: utf8
47collation_connection: utf8_general_ci
48 db_collation: latin1_swedish_ci
49 body_utf8: INSERT INTO events_list VALUES('event_now', now())
501 row in set (0.00 sec)
51
52MariaDB [testdb]> select *from events_list;
53+------------+---------------------+
54| event_name | event_started |
55+------------+---------------------+
56| event_now | 2024-05-12 07:41:42 |
57| event_now | 2024-05-12 07:47:44 |
58| event_now | 2024-05-12 07:47:45 |
59| event_now | 2024-05-12 07:47:46 |
60| event_now | 2024-05-12 07:47:47 |
61| event_now | 2024-05-12 07:47:48 |
62| event_now | 2024-05-12 07:47:49 |
63| event_now | 2024-05-12 07:47:50 |
64| event_now | 2024-05-12 07:47:51 |
65| event_now | 2024-05-12 07:47:52 |
66| event_now | 2024-05-12 07:47:53 |
67| event_now | 2024-05-12 07:47:54 |
68| event_now | 2024-05-12 07:47:55 |
69| event_now | 2024-05-12 07:47:56 |
70| event_now | 2024-05-12 07:47:57 |
71| event_now | 2024-05-12 07:47:58 |
72| event_now | 2024-05-12 07:47:59 |
73| event_now | 2024-05-12 07:48:00 |
74| event_now | 2024-05-12 07:48:01 |
75| event_now | 2024-05-12 07:48:02 |
76| event_now | 2024-05-12 07:48:03 |
77| event_now | 2024-05-12 07:48:04 |
78| event_now | 2024-05-12 07:48:05 |
79| event_now | 2024-05-12 07:48:06 |
80| event_now | 2024-05-12 07:48:07 |
81| event_now | 2024-05-12 07:48:08 |
82| event_now | 2024-05-12 07:48:09 |
83| event_now | 2024-05-12 07:48:10 |
84| event_now | 2024-05-12 07:48:11 |
85| event_now | 2024-05-12 07:48:12 |
86| event_now | 2024-05-12 07:48:13 |
87| event_now | 2024-05-12 07:48:14 |
88+------------+---------------------+
8932 rows in set (0.00 sec)
90
91
92#删除事件
93MariaDB [testdb]> drop event event_every_second;
94Query OK, 0 rows affected (0.00 sec)
95
96
97#删除后确认事件是否为空
98MariaDB [testdb]> SHOW EVENTS\G
99Empty set (0.00 sec)
100MariaDB [testdb]> select *from mysql.event\G
101Empty set (0.00 sec)
🍊 范例:创建每分钟启动的事件
1MariaDB [testdb]> show variables like 'event_scheduler';
2+-----------------+-------+
3| Variable_name | Value |
4+-----------------+-------+
5| event_scheduler | ON |
6+-----------------+-------+
71 row in set (0.001 sec)
8
9
10MariaDB [testdb]> create event testdb.event_every_minute on schedule every
111 minute do insert into events_list values('event_now', now());
12Query OK, 0 rows affected (0.001 sec)
13
14
15MariaDB [testdb]> select now();
16+---------------------+
17| now() |
18+---------------------+
19| 2019-12-02 22:39:12 |
20+---------------------+
211 row in set (0.000 sec)
22MariaDB [testdb]> select *from events_list;
23+------------+---------------------+
24| event_name | event_started |
25+------------+---------------------+
26| event_now | 2019-12-02 22:39:10 |
27+------------+---------------------+
28MariaDB [testdb]> SHOW EVENTS\G
29*************************** 1. row ***************************
30 Db: testdb
31 Name: event_every_minute
32 Definer: root@localhost
33 Time zone: SYSTEM
34 Type: RECURRING
35 Execute at: NULL
36 Interval value: 1
37 Interval field: MINUTE
38 Starts: 2019-12-02 22:35:57
39 Ends: NULL
40 Status: ENABLED
41 Originator: 1
42character_set_client: utf8
43collation_connection: utf8_general_ci
44 Database Collation: latin1_swedish_ci
451 row in set (0.001 sec)
46MariaDB [testdb]> select *from events_list;
47+------------+---------------------+
48| event_name | event_started |
49+------------+---------------------+
50| event_now | 2019-12-02 22:39:10 |
51| event_now | 2019-12-02 22:40:10 |
52| event_now | 2019-12-02 22:41:10 |
53| event_now | 2019-12-02 22:42:10 |
54| event_now | 2019-12-02 22:43:10 |
55| event_now | 2019-12-02 22:44:10 |
56| event_now | 2019-12-02 22:45:10 |
57+------------+---------------------+
587 rows in set (0.000 sec)
🍊 范例:创建定时调用存储过程的事件
1MariaDB [testdb]> drop event event_every_minute;
2Query OK, 0 rows affected (0.000 sec)
3MariaDB [testdb]> truncate table events_list;
4Query OK, 0 rows affected (0.010 sec)
5MariaDB [testdb]> select *from events_list;
6Empty set (0.000 sec)
7
8
9MariaDB [testdb]> delimiter //
10MariaDB [testdb]> create procedure sp_insert()
11 -> begin
12 -> insert into events_list values('event_now', now());
13 -> end//
14Query OK, 0 rows affected (0.001 sec)
15MariaDB [testdb]> delimiter ;
16
17
18MariaDB [testdb]> CREATE DEFINER=`root`@`localhost` EVENT event_test ON SCHEDULE
19EVERY 10 SECOND STARTS '2019-12-02 22:55:00' ON COMPLETION PRESERVE ENABLE DO
20call sp_insert();
21Query OK, 0 rows affected (0.001 sec)
22MariaDB [testdb]> select now();
23+---------------------+
24| now() |
25+---------------------+
26| 2019-12-02 22:51:57 |
27+---------------------+
281 row in set (0.000 sec)
29
30
31MariaDB [testdb]> select *from events_list;
32+------------+---------------------+
33| event_name | event_started |
34+------------+---------------------+
35| event_now | 2019-12-02 22:55:00 |
36| event_now | 2019-12-02 22:55:10 |
37| event_now | 2019-12-02 22:55:20 |
38| event_now | 2019-12-02 22:55:30 |
39+------------+---------------------+
404 rows in set (0.000 sec)
41MariaDB [testdb]>
🍊 范例:修改事件
1MariaDB [testdb]> ALTER DEFINER=`root`@`localhost EVENT event_test ON SCHEDULE
2EVERY 30 SECOND ON COMPLETION PRESERVE ENABLE DO call sp_insert();
3
4MariaDB [testdb]> select *from events_list;
5+------------+---------------------+
6| event_name | event_started |
7+------------+---------------------+
8| event_now | 2019-12-02 22:55:00 |
9| event_now | 2019-12-02 22:55:10 |
10| event_now | 2019-12-02 22:55:20 |
11| event_now | 2019-12-02 22:55:30 |
12| event_now | 2019-12-02 22:55:40 |
13| event_now | 2019-12-02 22:55:50 |
14| event_now | 2019-12-02 22:56:00 |
15| event_now | 2019-12-02 22:56:10 |
16| event_now | 2019-12-02 22:56:20 |
17| event_now | 2019-12-02 22:56:30 |
18| event_now | 2019-12-02 22:56:40 |
19| event_now | 2019-12-02 22:56:50 |
20| event_now | 2019-12-02 22:57:00 |
21| event_now | 2019-12-02 22:57:10 |
22| event_now | 2019-12-02 22:57:20 |
23| event_now | 2019-12-02 22:57:30 |
24| event_now | 2019-12-02 22:57:40 |
25| event_now | 2019-12-02 22:57:50 |
26| event_now | 2019-12-02 22:58:00 |
27| event_now | 2019-12-02 22:58:10 |
28| event_now | 2019-12-02 22:58:20 |
29| event_now | 2019-12-02 22:58:30 |
30| event_now | 2019-12-02 22:58:40 |
31| event_now | 2019-12-02 22:58:50 |
32| event_now | 2019-12-02 22:59:00 |
33| event_now | 2019-12-02 22:59:10 |
34| event_now | 2019-12-02 22:59:18 |
35| event_now | 2019-12-02 22:59:48 |
36| event_now | 2019-12-02 23:00:18 |
37| event_now | 2019-12-02 23:00:48 |
38| event_now | 2019-12-02 23:01:18 |
39| event_now | 2019-12-02 23:01:48 |
40| event_now | 2019-12-02 23:02:18 |
41| event_now | 2019-12-02 23:02:48 |
42+------------+---------------------+
4334 rows in set (0.001 sec)
44
45
46#禁用事件
47MariaDB [testdb]> alter event testdb.event_test disable;
48MariaDB [testdb]> show events\G
49*************************** 1. row ***************************
50 Db: testdb
51 Name: event_test
52 Definer: root@localhost
53 Time zone: SYSTEM
54 Type: RECURRING
55 Execute at: NULL
56 Interval value: 30
57 Interval field: SECOND
58 Starts: 2019-12-02 22:59:18
59 Ends: NULL
60 Status: DISABLED
61 Originator: 1
62character_set_client: utf8
63collation_connection: utf8_general_ci
64 Database Collation: latin1_swedish_ci
651 row in set (0.001 sec)
66MariaDB [testdb]> select now();
67+---------------------+
68| now() |
69+---------------------+
70| 2019-12-02 23:09:02 |
71+---------------------+
721 row in set (0.001 sec)
73MariaDB [testdb]> select *from events_list;
74+------------+---------------------+
75| event_name | event_started |
76+------------+---------------------+
77| event_now | 2019-12-02 22:55:00 |
78| event_now | 2019-12-02 22:55:10 |
79| event_now | 2019-12-02 22:55:20 |
80| event_now | 2019-12-02 22:55:30 |
81| event_now | 2019-12-02 22:55:40 |
82| event_now | 2019-12-02 22:55:50 |
83| event_now | 2019-12-02 22:56:00 |
84| event_now | 2019-12-02 22:56:10 |
85| event_now | 2019-12-02 22:56:20 |
86| event_now | 2019-12-02 22:56:30 |
87| event_now | 2019-12-02 22:56:40 |
88| event_now | 2019-12-02 22:56:50 |
89| event_now | 2019-12-02 22:57:00 |
90| event_now | 2019-12-02 22:57:10 |
91| event_now | 2019-12-02 22:57:20 |
92| event_now | 2019-12-02 22:57:30 |
93| event_now | 2019-12-02 22:57:40 |
94| event_now | 2019-12-02 22:57:50 |
95| event_now | 2019-12-02 22:58:00 |
96| event_now | 2019-12-02 22:58:10 |
97| event_now | 2019-12-02 22:58:20 |
98| event_now | 2019-12-02 22:58:30 |
99| event_now | 2019-12-02 22:58:40 |
100| event_now | 2019-12-02 22:58:50 |
101| event_now | 2019-12-02 22:59:00 |
102| event_now | 2019-12-02 22:59:10 |
103| event_now | 2019-12-02 22:59:18 |
104| event_now | 2019-12-02 22:59:48 |
105| event_now | 2019-12-02 23:00:18 |
106| event_now | 2019-12-02 23:00:48 |
107| event_now | 2019-12-02 23:01:18 |
108| event_now | 2019-12-02 23:01:48 |
109| event_now | 2019-12-02 23:02:18 |
110| event_now | 2019-12-02 23:02:48 |
111+------------+---------------------+
11234 rows in set (0.001 sec)
113
114
115#启用事件
116MariaDB [testdb]> alter event testdb.event_test enable;
117Query OK, 0 rows affected (0.000 sec)
118MariaDB [testdb]> show events\G
119*************************** 1. row ***************************
120 Db: testdb
121 Name: event_test
122 Definer: root@localhost
123 Time zone: SYSTEM
124 Type: RECURRING
125 Execute at: NULL
126 Interval value: 30
127 Interval field: SECOND
128 Starts: 2019-12-02 22:59:18
129 Ends: NULL
130 Status: ENABLED
131 Originator: 1
132character_set_client: utf8
133collation_connection: utf8_general_ci
134 Database Collation: latin1_swedish_ci
1351 row in set (0.001 sec)
136MariaDB [testdb]> select *from events_list;
137+------------+---------------------+
138| event_name | event_started |
139+------------+---------------------+
140| event_now | 2019-12-02 22:55:00 |
141| event_now | 2019-12-02 22:55:10 |
142| event_now | 2019-12-02 22:55:20 |
143| event_now | 2019-12-02 22:55:30 |
144| event_now | 2019-12-02 22:55:40 |
145| event_now | 2019-12-02 22:55:50 |
146| event_now | 2019-12-02 22:56:00 |
147| event_now | 2019-12-02 22:56:10 |
148| event_now | 2019-12-02 22:56:20 |
149| event_now | 2019-12-02 22:56:30 |
150| event_now | 2019-12-02 22:56:40 |
151| event_now | 2019-12-02 22:56:50 |
152| event_now | 2019-12-02 22:57:00 |
153| event_now | 2019-12-02 22:57:10 |
154| event_now | 2019-12-02 22:57:20 |
155| event_now | 2019-12-02 22:57:30 |
156| event_now | 2019-12-02 22:57:40 |
157| event_now | 2019-12-02 22:57:50 |
158| event_now | 2019-12-02 22:58:00 |
159| event_now | 2019-12-02 22:58:10 |
160| event_now | 2019-12-02 22:58:20 |
161| event_now | 2019-12-02 22:58:30 |
162| event_now | 2019-12-02 22:58:40 |
163| event_now | 2019-12-02 22:58:50 |
164| event_now | 2019-12-02 22:59:00 |
165| event_now | 2019-12-02 22:59:10 |
166| event_now | 2019-12-02 22:59:18 |
167| event_now | 2019-12-02 22:59:48 |
168| event_now | 2019-12-02 23:00:18 |
169| event_now | 2019-12-02 23:00:48 |
170| event_now | 2019-12-02 23:01:18 |
171| event_now | 2019-12-02 23:01:48 |
172| event_now | 2019-12-02 23:02:18 |
173| event_now | 2019-12-02 23:02:48 |
174| event_now | 2019-12-02 23:11:48 |
175| event_now | 2019-12-02 23:12:18 |
176+------------+---------------------+
17736 rows in set (0.000 sec)
178
179
180#修改事件名称
181MariaDB [testdb]> alter event testdb.event_test rename to event_test2;
182Query OK, 0 rows affected (0.001 sec)
183MariaDB [testdb]> show events\G
184*************************** 1. row ***************************
185 Db: testdb
186 Name: event_test2
187 Definer: root@localhost
188 Time zone: SYSTEM
189 Type: RECURRING
190 Execute at: NULL
191 Interval value: 30
192 Interval field: SECOND
193 Starts: 2019-12-02 22:59:18
194 Ends: NULL
195 Status: ENABLED
196 Originator: 1
197character_set_client: utf8
198collation_connection: utf8_general_ci
199 Database Collation: latin1_swedish_ci
2001 row in set (0.001 sec)
201MariaDB [testdb]> drop event event_test2;
202Query OK, 0 rows affected (0.000 sec)
203MariaDB [testdb]> show events;
204Empty set (0.001 sec)
MySQL用户管理
相关数据库和表
1元数据数据库:mysql
2系统授权表:db, host, user,columns_priv, tables_priv, procs_priv, proxies_priv
用户帐号
1'USERNAME'@'HOST'
2
3@'HOST':
4 主机名: user1@'web1.magedu.org'
5
6 IP地址或Network
7 通配符: % _
8 示例:172.16.%.% user2@'192.168.1.%'
创建用户
1CREATE USER 'USERNAME'@'HOST' [IDENTIFIED BY 'password'];
新建用户的默认权限:USAGE
用户重命名
1RENAME USER old_user_name TO new_user_name;
删除用户
1DROP USER 'USERNAME'@'HOST‘
🍊 范例:删除默认的空用户
1DROP USER ''@'localhost';
修改密码 🍍
- 新版mysql中用户密码可以保存在mysql.user表的authentication_string字段中
- 如果mysql.user表的authentication_string和password字段都保存密码,authentication_string优先生效;
🍊 范例:修改用户密码
1##方法1:(MySQL 5.7 之前的版本)
2#mysql -u root -p #进入到mysql里
3SET PASSWORD FOR 'root'@'localhost' = PASSWORD('xyy520'); #推荐: #这个命令会直接生效的,如果更新表的话,需要执行`FLUSH PRIVILEGES;`才会生效;
4
5
6##方法2:(MySQL 5.7 及以上版本)
7#mysql -u root -p #进入到mysql里
8ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码';
9FLUSH PRIVILEGES;
10
11
12##方法3:
13#mysql -u root -p #进入到mysql里
14update mysql.user set password=password('xyy520') where user='root';
15FLUSH PRIVILEGES;
16或者
17update mysql.user set authentication_string=password('magedu') where user='root';
18FLUSH PRIVILEGES;
19
20##方法4:
21mysqladmin -u root -p password '新密码'
备注:
1在某些情况下,'localhost' 可能需要被替换为具体的主机名或IP地址,具体取决于 `root` 用户可以从哪里访问数据库。如果 `root` 用户应该能够从任何主机连接,请使用 `'root'@'%'`。
备注:
1#mariadb 10.3
2update mysql.user set authentication_string=password('ubuntu') where user='mage';
3#此方法需要执行下面指令才能生效:
4FLUSH PRIVILEGES;
忘记管理员密码的解决办法🍊
启动mysqld进程时,为其使用如下选项:
1--skip-grant-tables 2--skip-networking使用UPDATE命令修改管理员密码
关闭mysqld进程,移除上述两个选项,重启mysqld
🍊 范例:破解root密码
1[root@centos8 ~]#vim /etc/my.cnf
2[mysqld]
3skip-grant-tables
4skip-networking
5
6[root@centos8 ~]#systemctl restart mariadb
7[root@centos8 ~]#mysql
8
9#mariadb 新版
10MariaDB [(none)]> update mysql.user set authentication_string=password('ubuntu') where user='root';
11#mariadb 旧版
12MariaDB [(none)]> update mysql.user set password=password('ubuntu') where user='root';
13
14
15[root@centos8 ~]#systemctl restart mariadb
16[root@centos8 ~]#vim /etc/my.cnf
17[mysqld]
18#skip-grant-tables
19#skip-networking
20[root@centos8 ~]#systemctl restart mariadb
21[root@centos8 ~]#mysql -uroot -pubuntu
权限管理和DCL语句
权限类别:
- 管理类
- 程序类
- 数据库级别
- 表级别
- 字段级别
管理类:
- CREATE USER
- FILE
- SUPER
- SHOW DATABASES
- RELOAD
- SHUTDOWN
- REPLICATION SLAVE 能实现数据库的复制;
- REPLICATION CLIENT
- LOCK TABLES
- PROCESS
- CREATE TEMPORARY TABLES
程序类:针对 FUNCTION、PROCEDURE、TRIGGER
- CREATE
- ALTER
- DROP
- EXCUTE
库和表级别:针对 DATABASE、TABLE
- ALTER
- CREATE
- CREATE VIEW
- DROP INDEX
- SHOW VIEW
- WITH GRANT OPTION:能将自己获得的权限转赠给其他用户
数据操作
- SELECT
- INSERT
- DELETE
- UPDATE
字段级别
- SELECT(col1,col2,…)
- UPDATE(col1,col2,…)
- INSERT(col1,col2,…)
所有权限
- ALL PRIVILEGES 或 ALL
授权:GRANT
1GRANT priv_type [(column_list)],... ON [object_type] priv_level TO 'user'@'host'
2[IDENTIFIED BY 'password'] [WITH GRANT OPTION];
3priv_type: ALL [PRIVILEGES]
4object_type:TABLE | FUNCTION | PROCEDURE
5priv_level: *(所有库) |*.* | db_name.* | db_name.tbl_name | tbl_name(当前库
6的表) | db_name.routine_name(指定库的函数,存储过程,触发器)
7with_option: GRANT OPTION
8 | MAX_QUERIES_PER_HOUR count
9 | MAX_UPDATES_PER_HOUR count
10 | MAX_CONNECTIONS_PER_HOUR count
11 | MAX_USER_CONNECTIONS count
参考:https://dev.mysql.com/doc/refman/5.7/en/grant.html
🍊 范例:
1GRANT SELECT (col1), INSERT (col1,col2) ON mydb.mytbl TO 'someuser'@'somehost‘;
2GRANT ALL ON wordpress.* TO wordpress@'192.168.8.%' IDENTIFIED BY 'magedu';
3
4GRANT ALL PRIVILEGES ON *.* TO 'root'@'192.168.8.%' IDENTIFIED BY 'magedu' WITH GRANT OPTION;
5
6
7GRANT ALL ON hellodb.* TO test@'192.168.8.%';
8
9
10
11#生产里推荐,一条命令完成创建用户+赋予用户权限事项。
12GRANT ALL PRIVILEGES ON *.* TO 'admin'@'172.29.9.%' IDENTIFIED BY 'magedu' WITH GRANT OPTION;
查看指定用户获得的授权
1Help SHOW GRANTS
2
3SHOW GRANTS FOR 'user'@'host';
4SHOW GRANTS FOR CURRENT_USER[()];
取消授权:REVOKE
1REVOKE priv_type [(column_list)] [, priv_type [(column_list)]] ... ON
2[object_type] priv_level FROM user [, user] ...
参考:https://dev.mysql.com/doc/refman/5.7/en/revoke.html
范例:
1REVOKE DELETE ON testdb.* FROM 'testuser'@‘172.16.0.%’;
注意:MariaDB服务进程启动时会读取mysql库中所有授权表至内存
(1) GRANT或REVOKE等执行权限操作会保存于系统表中,MariaDB的服务进程通常会自动重读授权表,使之生效
(2) 对于不能够或不能及时重读授权表的命令,可手动让MariaDB的服务进程重读授权表:mysql> FLUSH PRIVILEGES;
MySQL的图形化的远程管理工具
在MySQL数据库中创建用户并授权后,可以使用相关图形化工具进行远程的管理。
常见的图形化管理工具:
- Navicat
- SQLyog
Navicat 工具


SQLyog 工具


4、MySQL架构和性能优化

1thread reuse 线程复用
2optimizer 优化器
MySQL是C/S 架构的,connectors是连接器;可供Native C API、JDBC、ODBC、NET、PHP、Perl、Python、Ruby、Cobol等连接mysql;ODBC叫开放数据库(系统)互联,open database connection;JDBC是主要用于java语言利用较为底层的驱动连接数据库;
以上这些,站在编程角度可以理解为连入数据库管理系统的驱动,站在mysql角度称作专用语言对应的链接器。任何链接器连入mysql以后,mysql是单进程多线程模型的,因此,每个用户连接,都会创建一个单独的连接线程;其实mysql连接也有长短连接两种方式,使用mysql客户端连入数据库后,直到使用quit命令才退出,可认为是长连接;使用mysql中的-e选项,在mysql客户端向服务器端申请运行一个命令后则立即退出,也就意味着连接会立即断开;所以,mysql也支持长短连接类似于两种类型;
所以,用户连入mysql后,创建一个连接线程,完成之后,能够通过这个链接线程完成接收客户端发来的请求,为其处理请求,构建响应报文并发给客户端;由于是单进程模型,就意味着必须要维持一个线程池,跟之前介绍过的varnish很接近,需要一个线程池来管理这众多线程是如何对众多客户端的并发请求,完成并发响应的,组件connection pool就是实现样功能;
connection pool对于mysql而言,它所实现的功能,包括authentication认证,用户发来的账号密码是否正确要完成认证功能;thread reuse线程重用功能,一般当一个用户连接进来以后要用一个线程来响应它,而后当用户退出这个线程有可能并非被销毁,而是把它清理完以后,重新收归到线程池当中的空闲线程中去,以完成所谓的线程重用;connection limit 线程池的大小决定了连接并发数量的上限,例如,最多容纳100线程,一旦到达此上限后续到达的连接请求则只能排队或拒绝连接;check memory用来检测内存,caches实现线程缓存;整个都属于线程池的功能.当用户请求之后,通过线程池建立一个用户连接,这个线程一直存在,然后用户就通过这个会话,发送对应的SQL语句到服务器端.
服务器收到SQL语句后,要对语句完成执行,首先要能理解sql语句需要有sql解释器或叫sql接口sql interface就可理解为是整个mysql的外壳,就像shell是linux操作系统的外壳一样道理;用户无论通过哪种链接器发来的基本的SQL请求,当然,事实上通过native C API也有发过来的不是SQL 请求,而仅仅是对API中的传递参数后的调用;不是SQL语句不过都统统理解为sql语句罢了;对SQL而言分为DDL 和DML两种类型,但是无论哪种类型,提交以后必须交给内核,让内核来运行,在这之前必须要告诉内核哪个是命令,哪个是选项,哪些是参数,是否存在语法错误等等;因此,这个整个SQL 接口就是一个完完整整的sql命令的解释器,并且这个sql接口还有提供完整的sql接口应该具备的功能,比如支持所谓过程式编程,支持代码块的实现像存储过程、存储函数,触发器、必要时还要实现部署一个关系型数据库应该具备的基本组件例如视图等等,其实都在sql interface这个接口实现的;SQL接口做完词法分析、句法分析后,要分析语句如何执行让parser解析器或分析器实现,parser是专门的分析器,这个分析器并不是分析语法问题的,语法问题在sql接口时就能发现是否有错误了,一个语句没有问题,就要做执行分析,所谓叫查询翻译,把一个查询语句给它转换成对应的能够在本地执行的特定操作;比如说看上去是语句而背后可能是执行的一段二进制指令,这个时候就完成对应的指令,还要根据用户请求的对象,比如某一字段查询内容是否有对应数据的访问权限,或叫对象访问权限;在数据库中库、表、字段、字段中的数据有时都称为object,叫一个数据库的对象,用户认证的通过,并不意味着就能一定能访问数据库上的所有数据,所以说,mysql的认证大概分为两过程都要完成,第一是连入时需要认证账号密码是否正确这是authentication,然后,验证成功后用户发来sql语句还要验证用户是否有权限获取它期望请求获取的数据;这个称为object privilege,这一切都是有parser分析器进行的。
分析器分析完成之后,可能会生成多个执行树,这意味着为了能够达到访问期望访问到的目的,可能有多条路径都可实现,就像文件系统一样可以使用相对路径也可使用绝对路径;它有多种方式,在多种路径当中一定有一个是最优的,类似路由选择,因此,优化器就要去衡量多个访问路径中哪一个代价或开销是最小的,这个开销的计算要依赖于索引等各种内部组件来进行评估;而且这个评估的只是近似值,同时还要考虑到当前mysql内部在实现资源访问时统计数据,比如,根据判断认为是1号路径的开销最小的,但是众多统计数据表明发往1号路径的访问的资源开销并不小,并且比3号路径大的多,因此,可能会依据3号路径访问;这就是所谓的优化器它负责检查多条路径,每条路径的开销,然后评估开销,这个评估根据内部的静态数据,索引,根域根据动态生成的统计数据来判定每条路径的开销大小,因此这里还有statics;一旦优化完成之后,还要生成统计数据,这就是优化器的作用;如果没有优化器mysql执行语句是最慢的,其实优化还包括一种功能,一旦选择完一条路径后,例如用户给的这个命令执行起来,大概需要100个开销,如果通过改写语句能够达到同样目的可能只需要30个开销;于是,优化器还要试图改写sql语句;所以优化本身还包括查询语句的改写;一旦优化完成,接下来就交给存储引擎完成.
mysql是插件式存储引擎,它就能够替换使用选择多种不同的引擎,MyISAM是MySQL 经典的存储引擎之一,InnoDB是由Innobase Oy公司所开发,2006年五月由甲骨文公司并购提供给MySQL的,NDB主要用于MySQL Cluster 分布式集群环境,archive做归档的等等,还有许多第三方开发的存储引擎;存储引擎负责把具体分析的结果完成对磁盘上文件路径访问的转换,数据库中的行数据都是存储在磁盘块上的,因此存储引擎要把数据库数据映射为磁盘块,并把磁盘块加载至内存中;进程实现数据处理时,是不可能直接访问磁盘上的数据的,因为它没有权限,只有让内核来把它所访问的数据加载至内存中以后,进程在内存中完成修改,由内核再负责把数据存回磁盘;对于文件系统而言,数据的存储都是以磁盘块方式存储的,但是,mysql在实现数据组织时,不完全依赖于磁盘,而是把磁盘块再次组织成更大一级的逻辑单位,类似于lvm中的PE或LE的形式;其实,MySQL的存储引擎在实现数据管理时,也是在文件系统之上布设文件格式,对于文件而言在逻辑层上还会再次组织成一个逻辑单位,这个逻辑单位称为mysql的数据块datablock 一般为16k ,对于关系型数据库,数据是按行存储的;一般一行数据都是存储在一起的,因此,MySQL 在内部有一个数据块datablock,在datablock就存储一行数据,一个数据块里可能存放了n行数据;将来在查询加载一行数据时,内核会把整个一个数据数据块加载至内存中,而mysql存储引擎,就从中挑出来某一行返回给查询者,是这样实现的;所以整个存储是以datablock在底层为其最终级别的.
事实上,整个存取过程,尤其是访问比较热点的数据,也不可能每一次当用户访问时或当某SQL语句用到时再临时从磁盘加载到内存中,因此,为了能够加上整个性能,mysql的有些存储引擎可以实现,把频繁访问到的热点数据,统统装入内存,用户访问、修改时直接在内存中操作,只不过周期性的写入磁盘上而已,比如像InnoDB,所以caches和buffers组件就是实现此功能的;MySQL为了执行加速,因为它会不断访问数据,而随计算机来说io是最慢的一环,尤其是磁盘io,所以为了加速都载入内存中管理;这就需要MySQL 维护cache和buffer缓存或缓冲;这是由MySQL 服务器自己维护的;有很多存储引擎自己也有cache和buffer;一个数据库提供了3种视图,物理视图就是看到的对应的文件系统存储为一个个的文件,MySQL的数据文件类型,常见的有redo log重做日志,undo log撤销日志,data是真正的数据文件,index是索引文件,binary log是二进制日志文件,error log错误日志,query log查询日志,slow query log慢查询日志,在复制架构中还存在中继日志文件,跟二进制属于同种格式;这是mysql数据文件类型,也就是物理视图;逻辑视图这是在mysql接口上通过存储引擎把mysql文件尤其是data文件,给它映射为一个个关系型数据库应该具备组成部分,比如表,一张表在底层是一个数据文件而已,里面组织的就是datablock,最终映射为磁盘上文件系统的block,然后再次映射为本地扇区的存储,但是整个mysql需要把他们映射成一个二维关系表的形式,需要依赖sql接口以及存储引擎共同实现;所以,把底层数据文件映射成关系型数据库的组件就是逻辑视图;DBA 就是关注内部组件是如何运作的,并且定义、配置其运作模式,而链接器都是终端用户通过链接器的模式进入数据库来访问数据;数据集可能非常大,每一类用户可能只有一部分数据的访问权限,这个时候,最终的终端用户所能访问到的数据集合称作用户视图;为了保证MySQL运作还提供了管理和服务工具,例如:备份恢复工具,安全工具,复制工具,集群服务,管理、配置、迁移、元数据等工具。
存储引擎

MySQL中的数据用各种不同的技术存储在文件(或者内存)中。这些技术中的每一种技术都使用不同的存储机制、索引技巧、锁定水平并且最终提供广泛的不同的功能和能力,此种技术称为存储擎,MySQL 支持多种存储引擎其中目前应用最广泛的是InnoDB和MyISAM两种。
官方参考资料:https://docs.oracle.com/cd/E17952_01/mysql-5.7-en/storage-engines.html


1.MyISAM存储引擎
面试:总爱问MyISAM和InnoDB 两种存储引擎的区别。
MyISAM引擎特点
- 不支持事务表级锁定
- 读写相互阻塞,写入不能读,读时不能写
- 只缓存索引
- 不支持外键约束
- 不支持聚簇索引
- 读取数据较快,占用资源较少
- 不支持MVCC(多版本并发控制机制)高并发
- 崩溃恢复性较差
- MySQL5.5.5前默认的数据库引擎
MyISAM****存储引擎适用场景
- 只读(或者写较少)
- 表较小(可以接受长时间进行修复操作)
MyISAM引擎文件
- tbl_name.frm 表格式定义
- tbl_name.MYD 数据文件
- tbl_name.MYI 索引文件

2.InnoDB引擎
InnoDB引擎特点
- 行级锁
- 支持事务,适合处理大量短期事务
- 读写阻塞与事务隔离级别相关
- 可缓存数据和索引
- 支持聚簇索引
- 崩溃恢复性更好
- 支持MVCC高并发
- 从MySQL5.5后支持全文索引
- 从MySQL5.5.5开始为默认的数据库引擎
InnoDB数据库文件

- 所有InnoDB表的数据和索引放置于同一个表空间中
1数据文件:ibdata1, ibdata2,存放在datadir定义的目录下
2表格式定义:tb_name.frm,存放在datadir定义的每个数据库对应的目录下
- 每个表单独使用一个表空间存储表的数据和索引
1两类文件放在对应每个数据库独立目录中
2数据文件(存储数据和索引):tb_name.ibd
3表格式定义:tb_name.frm
启用:innodb_file_per_table=ON (MariaDB 5.5以后版是默认值)
参看:https://mariadb.com/kb/en/library/xtradbinnodb-server-system-variables/#innodb_file_per_table
107:27:05(root@localhost) [(none)]> show variables like 'innodb_file_per_table';
2+-----------------------+-------+
3| Variable_name | Value |
4+-----------------------+-------+
5| innodb_file_per_table | ON |
6+-----------------------+-------+
71 row in set (0.001 sec)
其它存储引擎
Performance_Schema:Performance_Schema数据库使用。
Memory :将所有数据存储在RAM中,以便在需要快速查找参考和其他类似数据的环境中进行快速访问。适用存放临时数据。引擎以前被称为HEAP引擎。
MRG_MyISAM:使MySQL DBA或开发人员能够对一系列相同的MyISAM表进行逻辑分组,并将它们作为一个对象引用。适用于VLDB(Very Large Data Base)环境,如数据仓库。
Archive :为存储和检索大量很少参考的存档或安全审核信息,只支持SELECT和INSERT操作;支持行级锁和专用缓存区
Federated联合:用于访问其它远程MySQL服务器一个代理,它通过创建一个到远程MySQL服务器的客户端连接,并将查询传输到远程服务器执行,而后完成数据存取,提供链接单独MySQL服务器的能力,以便从多个物理服务器创建一个逻辑数据库。非常适合分布式或数据集市环境
BDB:可替代InnoDB的事务引擎,支持COMMIT、ROLLBACK和其他事务特性
Cluster/NDB:MySQL的簇式数据库引擎,尤其适合于具有高性能查找要求的应用程序,这类查找需求还要求具有最高的正常工作时间和可用性
CSV:CSV存储引擎使用逗号分隔值格式将数据存储在文本文件中。可以使用CSV引擎以CSV格式导入和导出其他软件和应用程序之间的数据交换
BLACKHOLE :黑洞存储引擎接受但不存储数据,检索总是返回一个空集。该功能可用于分布式数据库设计,数据自动复制,但不是本地存储
example:“stub”引擎,它什么都不做。可以使用此引擎创建表,但不能将数据存储在其中或从中检索。目的是作为例子来说明如何开始编写新的存储引擎
管理存储引擎
- 查看mysql支持的存储引擎
1SHOW ENGINES;
- 查看当前默认的存储引擎
105:15:56(root@localhost) [(none)]> show variables like '%storage_engine%';
2+----------------------------+--------+
3| Variable_name | Value |
4+----------------------------+--------+
5| default_storage_engine | InnoDB |
6| default_tmp_storage_engine | |
7| enforce_storage_engine | |
8| storage_engine | InnoDB |
9+----------------------------+--------+
104 rows in set (0.001 sec)
- 设置默认的存储引擎
1vim /etc/my.cnf
2[mysqld]
3default_storage_engine= InnoDB
- 查看库中所有表使用的存储引擎
1show table status from mysql\G
2……
3*************************** 30. row ***************************
4 Name: transaction_registry
5 Engine: InnoDB
6 Version: 10
7 Row_format: Dynamic
8 Rows: 0
9 Avg_row_length: 0
10 Data_length: 16384
11 Max_data_length: 0
12 Index_length: 49152
13 Data_free: 0
14 Auto_increment: NULL
15 Create_time: 2024-03-29 06:02:16
16 Update_time: NULL
17 Check_time: NULL
18 Collation: utf8_bin
19 Checksum: NULL
20 Create_options: stats_persistent=0
21 Comment:
22Max_index_length: 0
23 Temporary: N
24……
- 查看库中指定表的存储引擎
1show table status like 'tb_name';
2show create table tb_name;
- 设置表的存储引擎:
1CREATE TABLE tb_name(... ) ENGINE=InnoDB;
2ALTER TABLE tb_name ENGINE=InnoDB;
MySQL中的系统数据库
mysql数据库
是mysql的核心数据库,类似于Sql Server中的master库,主要负责存储数据库的用户、权限设置、关键字等mysql自己需要使用的控制和管理信息
performance_schema数据库
MySQL 5.5开始新增的数据库,主要用于收集数据库服务器性能参数,库里表的存储引擎均为PERFORMANCE_SCHEMA,用户不能创建存储引擎为PERFORMANCE_SCHEMA的表
information_schema数据库
MySQL 5.0之后产生的,一个虚拟数据库,物理上并不存在information_schema数据库,类似与“数据字典”,提供了访问数据库元数据的方式,即数据的数据。比如数据库名或表名,列类型,访问权限(更加细化的访问方式)
sys数据库
MySQL5.7之后新增加的数据库,库中所有数据源来自performance_schema。目标是把performance_schema的把复杂度降低,让DBA能更好的阅读这个库里的内容。让DBA更快的了解DB的运行情况
服务器配置和状态
可以通过mysqld选项,服务器系统变量和服务器状态变量进行MySQL的配置和查看状态
官方帮助:
https://dev.mysql.com/doc/refman/5.7/en/server-option-variable-reference.html
https://mariadb.com/kb/en/library/full-list-of-mariadb-options-system-and-status-variables/
mysql:

mariadb:

注意:
- 其中有些参数支持运行时修改,会立即生效
- 有些参数不支持动态修改,且只能通过修改配置文件,并重启服务器程序生效
- 有些参数作用域是全局的,为所有会话设置
- 有些可以为每个用户提供单独(会话)的设置
1.服务器选项
这2行是yes的就是服务器选项:

获取mysqld的可用选项列表:
1#查看mysqld可用选项列表和及当前值
2mysqld --verbose --help
3
4#获取mysqld当前启动选项
5mysqld --print-defaults
- 范例:
1[root@test ~]# mysqld --verbose --help|grep datadir
2……
3datadir /var/lib/mysql/
4
5
6[root@test ~]# mysqld --verbose --help|grep skip-grant-tables
7skip-grant-tables FALSE
设置服务器选项方法:
在命令行中设置
1shell> /usr/bin/mysqld_safe --skip-name-resolve=1 2shell> /usr/libexec/mysqld --basedir=/usr在配置文件my.cnf中设置
范例:
1#vim /etc/my.cnf 2 3[mysqld] 4skip_name_resolve=1 5skip-grant-tables
- 范例: skip-grant-tables是服务器选项,但不是系统变量
1[root@test ~]# mysqladmin variables |grep skip-grant-tables
2[root@test ~]# mysql
3Welcome to the MariaDB monitor. Commands end with ; or \g.
4Your MariaDB connection id is 270
5Server version: 10.5.24-MariaDB MariaDB Server
6
7Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
8
9Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
10
11MariaDB [(none)]> show variables like 'skip-grant-variables';
12Empty set (0.001 sec)
13
14MariaDB [(none)]>

2.服务器系统变量
服务器系统变量:可以分全局和会话两种
获取系统变量:
1SHOW GLOBAL VARIABLES; #只查看global变量
2SHOW [SESSION] VARIABLES;#查看所有变量(包括global和session)
3
4
5#查看指定的系统变量
6SHOW VARIABLES LIKE 'VAR_NAME';
7SELECT @@VAR_NAME;
8
9
10#查看选项和部分变量
11[root@centos8 ~]#mysqladmin variables
1[root@test ~]# mysql -e 'show variables'|wc -l
2668
3[root@test ~]# mysql -e 'show global variables'|wc -l
4649
5[root@test ~]# mysql -e 'show session variables'|wc -l
6668
修改服务器变量的值:
1help SET
修改全局变量:仅对修改后新创建的会话有效;对已经建立的会话无效
1SET GLOBAL system_var_name=value;
2SET @@global.system_var_name=value;
修改会话变量:
1SET [SESSION] system_var_name=value;
2SET @@[session.]system_var_name=value;
范例:修改变量server_id的值
1[root@test ~]# mysql -e 'show global variables'|grep server_id
2server_id 1
3[root@test ~]# mysql -e 'show session variables'|grep server_id
4server_id 1
5
6
7
8MariaDB [(none)]> set global server_id=200;
9Query OK, 0 rows affected (0.000 sec)
10
11MariaDB [(none)]> select @@server_id;
12+-------------+
13| @@server_id |
14+-------------+
15| 200 |
16+-------------+
171 row in set (0.000 sec)
18
19MariaDB [(none)]> set session server_id=300;
20Query OK, 0 rows affected (0.000 sec)
21
22MariaDB [(none)]> select @@server_id;
23+-------------+
24| @@server_id |
25+-------------+
26| 300 |
27+-------------+
281 row in set (0.000 sec)

范例:查看系统变量的值
1MariaDB [(none)]> show variables like 'datadir'; #这个变量不支持动态修改。
2+---------------+-----------------+
3| Variable_name | Value |
4+---------------+-----------------+
5| datadir | /var/lib/mysql/ |
6+---------------+-----------------+
71 row in set (0.001 sec)
8
9MariaDB [(none)]> set global datadir='/data';
10ERROR 1238 (HY000): Variable 'datadir' is a read only variable

范例:修改mysql的最大并发连接数
1MariaDB [(none)]> show variables like 'max_connections';
2+-----------------+-------+
3| Variable_name | Value |
4+-----------------+-------+
5| max_connections | 151 |
6+-----------------+-------+
71 row in set (0.001 sec)
8
9MariaDB [(none)]> set max_connections=5000;
10ERROR 1229 (HY000): Variable 'max_connections' is a GLOBAL variable and should be set with SET GLOBAL
11MariaDB [(none)]> set global max_connections=5000;
12Query OK, 0 rows affected (0.000 sec)
13
14MariaDB [(none)]> show variables like 'max_connections';
15+-----------------+-------+
16| Variable_name | Value |
17+-----------------+-------+
18| max_connections | 5000 |
19+-----------------+-------+
201 row in set (0.001 sec)

这个max_connections既是服务器选项,又是全局系统变量,因此支持写到系统配置文件的。vim /etc/my.cnf
1#vim /etc/my.cnf
2[mysqld]
3max_connections = 8000
4
5[root@centos8 ~]#systemctl restart mariadb
6[root@centos8 ~]#mysql -uroot -p
7Welcome to the MariaDB monitor. Commands end with ; or \g.
8Your MariaDB connection id is 9
9Server version: 10.3.11-MariaDB-log MariaDB Server
10Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
11Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
12MariaDB [(none)]> select @@max_connections;
13+-------------------+
14| @@max_connections |
15+-------------------+
16| 594 |
17+-------------------+
181 row in set (0.000 sec)
19
20
21##还需要配置如下设置:
22#方法1
23[root@centos8 ~]#vim /usr/lib/systemd/system/mariadb.service
24[Service]
25#加下面一行
26LimitNOFILE=65535
27
28#方法2
29[root@centos8 ~]#mkdir /etc/systemd/system/mariadb.service.d/
30[root@node3 ~]#vim /etc/systemd/system/mariadb.service.d/limits.conf
31[Service]
32LimitNOFILE=65535
33
34[root@centos8 ~]#systemctl daemon-reload
35[root@centos8 ~]#systemctl restart mariadb
36[root@centos8 ~]#mysql -uroot -p -e "select @@max_connections"
37Enter password:
38+-------------------+
39| @@max_connections |
40+-------------------+
41| 8000 |
42+-------------------+
范例: character_set_results是系统变量并非服务器选项
1MariaDB [(none)]> show variables like 'character%';
2+--------------------------+----------------------------+
3| Variable_name | Value |
4+--------------------------+----------------------------+
5| character_set_client | utf8 |
6| character_set_connection | utf8 |
7| character_set_database | latin1 |
8| character_set_filesystem | binary |
9| character_set_results | utf8 |
10| character_set_server | latin1 |
11| character_set_system | utf8 |
12| character_sets_dir | /usr/share/mysql/charsets/ |
13+--------------------------+----------------------------+
148 rows in set (0.001 sec)
15
16MariaDB [(none)]> set character_set_results='utf8mb4';
17Query OK, 0 rows affected (0.000 sec)
18
19MariaDB [(none)]> show variables like 'character%';
20+--------------------------+----------------------------+
21| Variable_name | Value |
22+--------------------------+----------------------------+
23| character_set_client | utf8 |
24| character_set_connection | utf8 |
25| character_set_database | latin1 |
26| character_set_filesystem | binary |
27| character_set_results | utf8mb4 |
28| character_set_server | latin1 |
29| character_set_system | utf8 |
30| character_sets_dir | /usr/share/mysql/charsets/ |
31+--------------------------+----------------------------+
328 rows in set (0.001 sec)
33
34
35#character_set_results不是服务器选项,写入配置文件将导致无法启动
36[root@test ~]# vim /etc/my.cnf
37[mysqld]
38character_set_results=utf8mb4
39
40
41[root@test ~]# systemctl restart mariadb
42Job for mariadb.service failed because the control process exited with error code. See "systemctl status mariadb.service" and "journalctl -xe" for details.
43[root@test ~]# systemctl status mariadb
44● mariadb.service - MariaDB 10.5.24 database server
45 Loaded: loaded (/usr/lib/systemd/system/mariadb.service; enabled; vendor preset: disabled)
46 Drop-In: /etc/systemd/system/mariadb.service.d
47 └─migrated-from-my.cnf-settings.conf
48 Active: failed (Result: exit-code) since Mon 2024-05-20 06:54:43 CST; 5s ago
49 Docs: man:mariadbd(8)
50 https://mariadb.com/kb/en/library/systemd/
51 ……
52 id 1331
53May 20 06:54:42 test mariadbd[29643]: 2024-05-20 6:54:42 0 [Note] Plugin 'FEEDBACK' is disabled.
54May 20 06:54:42 test mariadbd[29643]: 2024-05-20 6:54:42 0 [ERROR] /usr/sbin/mariadbd: unknown variable 'character_set_results=utf8mb4'
55May 20 06:54:42 test mariadbd[29643]: 2024-05-20 6:54:42 0 [ERROR] Aborting
56May 20 06:54:43 test systemd[1]: mariadb.service: main process exited, code=exited, status=7/NOTRUNNING
57May 20 06:54:43 test systemd[1]: Failed to start MariaDB 10.5.24 database server.
58May 20 06:54:43 test systemd[1]: Unit mariadb.service entered failed state.
59May 20 06:54:43 test systemd[1]: mariadb.service failed.
60Hint: Some lines were ellipsized, use -l to show in full.

范例:修改页大小
参看:https://mariadb.com/kb/en/innodb-system-variables/#innodb_page_size
说明:初始化数据目录后,不能更改此系统变量的值。 在MariaDB实例启动时设置InnoDB的页面大小,此后保持不变。
1[root@centos8 ~]#mysqladmin variables |grep innodb_page_size
2| innodb_page_size | 16384
3[root@centos8 ~]#mysql
4MariaDB [(none)]> show variables like "innodb_page_size";
5+------------------+-------+
6| Variable_name | Value |
7+------------------+-------+
8| innodb_page_size | 16384 |
9+------------------+-------+
101 row in set (0.001 sec)
11
12
13[root@centos8 ~]#vim /etc/my.cnf.d/mariadb-server.cnf
14[mysqld]
15innodb_page_size=64k
16[root@centos8 ~]#rm -rf /var/lib/mysql/*
17[root@centos8 ~]#systemctl restart mariadb
18
19
20[root@centos8 ~]#mysql
21Welcome to the MariaDB monitor. Commands end with ; or \g.
22Your MariaDB connection id is 9
23Server version: 10.3.11-MariaDB MariaDB Server
24Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
25Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
26MariaDB [(none)]> show variables like "innodb_page_size";
27+------------------+-------+
28| Variable_name | Value |
29+------------------+-------+
30| innodb_page_size | 65536 |
31+------------------+-------+
321 row in set (0.001 sec)

3.服务器状态变量
服务器状态变量:分全局和会话两种
状态变量(只读):用于保存mysqld运行中的统计数据的变量,不可更改
1SHOW GLOBAL STATUS;
2SHOW [SESSION] STATUS;
范例:
注意:这个系统变量只对本地当前终端会话有效果。
1[root@test2 ~]#mysql -e 'show variables'|grep -i com_select
2[root@test2 ~]#mysql -e 'show status'|grep -i com_select
3Com_select 0
4
5
607:40:55(root@localhost) [(none)]> show global status like 'com_select';
7+---------------+-------+
8| Variable_name | Value |
9+---------------+-------+
10| Com_select | 6 |
11+---------------+-------+
121 row in set (0.000 sec)
13
1407:40:58(root@localhost) [(none)]> select user,host from mysql.user;
15+-------------+-------------+
16| User | Host |
17+-------------+-------------+
18| admin | 172.29.%.% |
19| admin | 172.29.9.% |
20| test | 172.29.9.% |
21| admin | 192.168.8.% |
22| mariadb.sys | localhost |
23| mysql | localhost |
24| root | localhost |
25+-------------+-------------+
267 rows in set (0.018 sec)
27
2807:41:08(root@localhost) [(none)]> show global status like 'com_select';
29+---------------+-------+
30| Variable_name | Value |
31+---------------+-------+
32| Com_select | 7 |
33+---------------+-------+
341 row in set (0.001 sec)
35
3607:41:11(root@localhost) [(none)]>
服务器变量 SQL_MODE
SQL_MODE:对其设置可以完成一些约束检查的工作,可分别进行全局的设置或当前会话的设置
参考:
https://mariadb.com/kb/en/library/sql-mode/
https://dev.mysql.com/doc/refman/5.7/en/server-options.html#option_mysqld_sql-mode
常见MODE:
NO_AUTO_CREATE_USER: 禁止GRANT创建密码为空的用户
NO_ZERO_DATE:在严格模式,不允许使用‘0000-00-00’的时间
ONLY_FULL_GROUP_BY: 对于GROUP BY聚合操作,如果在SELECT中的列,没有在GROUP BY
中出现,那么将认为这个SQL是不合法的
NO_BACKSLASH_ESCAPES: 反斜杠“\”作为普通字符而非转义字符
PIPES_AS_CONCAT: 将"||“视为连接操作符而非“或”运算符
范例:CentOS 7 修改SQL_MODE变量实现分组语句控制
106:30:20(root@localhost) [hellodb]> select @@sql_mode;
2+-------------------------------------------------------------------------------------------+
3| @@sql_mode |
4+-------------------------------------------------------------------------------------------+
5| STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
6+-------------------------------------------------------------------------------------------+
71 row in set (0.000 sec)
8
906:30:42(root@localhost) [hellodb]> select classid,count(*) from students group by classid;
10+---------+----------+
11| classid | count(*) |
12+---------+----------+
13| NULL | 2 |
14| 1 | 4 |
15| 2 | 3 |
16| 3 | 4 |
17| 4 | 4 |
18| 5 | 1 |
19| 6 | 4 |
20| 7 | 3 |
21+---------+----------+
228 rows in set (0.011 sec)
2306:30:42(root@localhost) [hellodb]> select classid,count(*) from students group by classid;
24+---------+----------+
25| classid | count(*) |
26+---------+----------+
27| NULL | 2 |
28| 1 | 4 |
29| 2 | 3 |
30| 3 | 4 |
31| 4 | 4 |
32| 5 | 1 |
33| 6 | 4 |
34| 7 | 3 |
35+---------+----------+
368 rows in set (0.011 sec)
37
38
39#修改SQL_MODE
4006:32:54(root@localhost) [hellodb]> set sql_mode="ONLY_FULL_GROUP_BY";
41Query OK, 0 rows affected (0.000 sec)
42
4306:33:01(root@localhost) [hellodb]> show variables like 'sql_mode';
44+---------------+--------------------+
45| Variable_name | Value |
46+---------------+--------------------+
47| sql_mode | ONLY_FULL_GROUP_BY |
48+---------------+--------------------+
491 row in set (0.001 sec)
50
51
5206:33:10(root@localhost) [hellodb]> select classid,count(*) from students group by classid;^C
5306:33:10(root@localhost) [hellodb]> select stuid,classid,count(*) from students group by classid;
54ERROR 1055 (42000): 'hellodb.students.StuID' isn't in GROUP BY
5506:33:46(root@localhost) [hellodb]> select classid,count(*) from students group by classid;
56+---------+----------+
57| classid | count(*) |
58+---------+----------+
59| NULL | 2 |
60| 1 | 4 |
61| 2 | 3 |
62| 3 | 4 |
63| 4 | 4 |
64| 5 | 1 |
65| 6 | 4 |
66| 7 | 3 |
67+---------+----------+
688 rows in set (0.000 sec)
范例:CentOS 7 修改SQL_MODE变量
106:33:53(root@localhost) [hellodb]> create table test (id int ,name varchar(3));
2Query OK, 0 rows affected (0.016 sec)
3
406:40:59(root@localhost) [hellodb]> insert test values(1,'abcde');
5Query OK, 1 row affected, 1 warning (0.001 sec)
6
706:41:06(root@localhost) [hellodb]> show warnings;
8+---------+------+-------------------------------------------+
9| Level | Code | Message |
10+---------+------+-------------------------------------------+
11| Warning | 1265 | Data truncated for column 'name' at row 1 |
12+---------+------+-------------------------------------------+
131 row in set (0.000 sec)
14
1506:41:11(root@localhost) [hellodb]> select * from test;
16+------+------+
17| id | name |
18+------+------+
19| 1 | abc |
20+------+------+
211 row in set (0.000 sec)
22
2306:41:17(root@localhost) [hellodb]> show variables like 'SQL_MODE';
24+---------------+--------------------+
25| Variable_name | Value |
26+---------------+--------------------+
27| sql_mode | ONLY_FULL_GROUP_BY |
28+---------------+--------------------+
291 row in set (0.001 sec)
30
3106:41:23(root@localhost) [hellodb]> SET SQL_MODE=TRADITIONAL;
32Query OK, 0 rows affected (0.000 sec)
33
3406:41:28(root@localhost) [hellodb]> show variables like 'SQL_MODE';
35+---------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
36| Variable_name | Value |
37+---------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
38| sql_mode | STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
39+---------------+------------------------------------------------------------------------------------------------------------------------------------------------------+
401 row in set (0.001 sec)
41
4206:41:29(root@localhost) [hellodb]> insert test values(2,'magedu');
43ERROR 1406 (22001): Data too long for column 'name' at row 1
Query Cache 查询缓存
查询缓存原理
查询执行路径

查询缓存原理 哈希运算
缓存SELECT操作或预处理查询的结果集和SQL语句,当有新的SELECT语句或预处理查询语句请求,先去查询缓存,判断是否存在可用的记录集,判断标准:与缓存的SQL语句,是否完全一样,区分大小写
优缺点
不需要对SQL语句做任何解析和执行,当然语法解析必须通过在先,直接从Query Cache中获得查询结果,提高查询性能;
查询缓存的判断规则,不够智能,也即提高了查询缓存的使用门槛,降低效率;
查询缓存的使用,会增加检查和清理Query Cache中记录集的开销;
哪些查询可能不会被缓存
- 查询语句中加了SQL_NO_CACHE参数
- 查询语句中含有获得值的函数,包含:自定义函数,如:NOW() ,CURDATE()、GET_LOCK()、RAND()、CONVERT_TZ()等
- 对系统数据库的查询:mysql、information_schema 查询语句中使用SESSION级别变量或存储过程中的局部变量
- 查询语句中使用了LOCK IN SHARE MODE、FOR UPDATE的语句,查询语句中类似SELECT …
- INTO 导出数据的语句
- 对临时表的查询操作
- 存在警告信息的查询语句
- 不涉及任何表或视图的查询语句
- 某用户只有列级别权限的查询语句
- 事务隔离级别为Serializable时,所有查询语句都不能缓存
查询缓存相关的服务器变量
- query_cache_min_res_unit:查询缓存中内存块的最小分配单位,默认4k,较小值会减少浪费,但会导致更频繁的内存分配操作,较大值会带来浪费,会导致碎片过多,内存不足;
- query_cache_limit:单个查询结果能缓存的最大值,单位字节,默认为1M,对于查询结果过大而无法缓存的语句,建议使用SQL_NO_CACHE
- query_cache_size:查询缓存总共可用的内存空间;单位字节,必须是1024的整数倍,最小值40KB,低于此值有警报
- query_cache_wlock_invalidate:如果某表被其它的会话锁定,是否仍然可以从查询缓存中返回结果,默认值为OFF,表示可以在表被其它会话锁定的场景中继续从缓存返回数据;ON则表示不允许
- query_cache_type:是否开启缓存功能,取值为ON, OFF, DEMAND(按需开启,看select语句是否加
sql_cache参数)
范例:配置文件配置服务器选项
106:41:40(root@localhost) [hellodb]> show variables like 'query_cache%';
2+------------------------------+---------+
3| Variable_name | Value |
4+------------------------------+---------+
5| query_cache_limit | 1048576 |
6| query_cache_min_res_unit | 4096 |
7| query_cache_size | 1048576 |
8| query_cache_strip_comments | OFF |
9| query_cache_type | OFF |
10| query_cache_wlock_invalidate | OFF |
11+------------------------------+---------+
126 rows in set (0.001 sec)
13
14
15#vim /etc/my.cnf
16[mysqld]
17query_cache_type=ON
18query_cache_size=200M
19
20systemctl restart mariadb
21
22
23[root@test2 ~]#mysql hellodb
2407:42:09(root@localhost) [hellodb]> show variables like 'query_cache%';
25+------------------------------+-----------+
26| Variable_name | Value |
27+------------------------------+-----------+
28| query_cache_limit | 1048576 |
29| query_cache_min_res_unit | 4096 |
30| query_cache_size | 209715200 |
31| query_cache_strip_comments | OFF |
32| query_cache_type | ON |
33| query_cache_wlock_invalidate | OFF |
34+------------------------------+-----------+
356 rows in set (0.001 sec)
SELECT语句的缓存控制
查询缓存相关的状态变量
107:44:25(root@localhost) [hellodb]> show global status like 'Qcache%%';
2+-------------------------+-----------+
3| Variable_name | Value |
4+-------------------------+-----------+
5| Qcache_free_blocks | 1 |
6| Qcache_free_memory | 209697192 |
7| Qcache_hits | 0 |
8| Qcache_inserts | 0 |
9| Qcache_lowmem_prunes | 0 |
10| Qcache_not_cached | 2 |
11| Qcache_queries_in_cache | 0 |
12| Qcache_total_blocks | 1 |
13+-------------------------+-----------+
148 rows in set (0.001 sec)
- Qcache_free_blocks:处于空闲状态 Query Cache中内存 Block 数
- Qcache_total_blocks:Query Cache 中总Block ,当Qcache_free_blocks相对此值较大时,可能用内存碎片,执行FLUSH QUERY CACHE清理碎片
- Qcache_free_memory:处于空闲状态的 Query Cache 内存总量
- Qcache_hits:Query Cache 命中次数
- Qcache_inserts:向 Query Cache 中插入新的 Query Cache 的次数,即没有命中的次数
- Qcache_lowmem_prunes:记录因为内存不足而被移除出查询缓存的查询数
- Qcache_not_cached:没有被 Cache 的 SQL 数,包括无法被 Cache 的 SQL 以及由于
- query_cache_type 设置的不会被 Cache 的 SQL语句
- Qcache_queries_in_cache:在 Query Cache 中的 SQL 数量
范例:Query Cache测试
107:44:25(root@localhost) [hellodb]> show global status like 'Qcache%%';
2+-------------------------+-----------+
3| Variable_name | Value |
4+-------------------------+-----------+
5| Qcache_free_blocks | 1 |
6| Qcache_free_memory | 209697192 |
7| Qcache_hits | 0 |
8| Qcache_inserts | 0 |
9| Qcache_lowmem_prunes | 0 |
10| Qcache_not_cached | 2 |
11| Qcache_queries_in_cache | 0 |
12| Qcache_total_blocks | 1 |
13+-------------------------+-----------+
148 rows in set (0.001 sec)
15
1607:44:31(root@localhost) [hellodb]> select *from students where stuid=1;
17+-------+-------------+-----+--------+---------+-----------+
18| StuID | Name | Age | Gender | ClassID | TeacherID |
19+-------+-------------+-----+--------+---------+-----------+
20| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
21+-------+-------------+-----+--------+---------+-----------+
221 row in set (0.001 sec)
23
2407:55:49(root@localhost) [hellodb]> show global status like 'Qcache%%';
25+-------------------------+-----------+
26| Variable_name | Value |
27+-------------------------+-----------+
28| Qcache_free_blocks | 1 |
29| Qcache_free_memory | 209695656 |
30| Qcache_hits | 0 |
31| Qcache_inserts | 1 |
32| Qcache_lowmem_prunes | 0 |
33| Qcache_not_cached | 2 |
34| Qcache_queries_in_cache | 1 |
35| Qcache_total_blocks | 4 |
36+-------------------------+-----------+
378 rows in set (0.001 sec)
38
3907:55:53(root@localhost) [hellodb]> select *from students where stuid=2;
40+-------+------------+-----+--------+---------+-----------+
41| StuID | Name | Age | Gender | ClassID | TeacherID |
42+-------+------------+-----+--------+---------+-----------+
43| 2 | Shi Potian | 22 | M | 1 | 7 |
44+-------+------------+-----+--------+---------+-----------+
451 row in set (0.000 sec)
46
4707:56:03(root@localhost) [hellodb]> show global status like 'Qcache%%';
48+-------------------------+-----------+
49| Variable_name | Value |
50+-------------------------+-----------+
51| Qcache_free_blocks | 1 |
52| Qcache_free_memory | 209694632 |
53| Qcache_hits | 0 |
54| Qcache_inserts | 2 |
55| Qcache_lowmem_prunes | 0 |
56| Qcache_not_cached | 2 |
57| Qcache_queries_in_cache | 2 |
58| Qcache_total_blocks | 6 |
59+-------------------------+-----------+
608 rows in set (0.000 sec)
61
62
6307:56:04(root@localhost) [hellodb]> select *from students where stuid=1;
64+-------+-------------+-----+--------+---------+-----------+
65| StuID | Name | Age | Gender | ClassID | TeacherID |
66+-------+-------------+-----+--------+---------+-----------+
67| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
68+-------+-------------+-----+--------+---------+-----------+
691 row in set (0.000 sec)
70
7107:56:28(root@localhost) [hellodb]> show global status like 'Qcache%%';
72+-------------------------+-----------+
73| Variable_name | Value |
74+-------------------------+-----------+
75| Qcache_free_blocks | 1 |
76| Qcache_free_memory | 209694632 |
77| Qcache_hits | 1 |
78| Qcache_inserts | 2 |
79| Qcache_lowmem_prunes | 0 |
80| Qcache_not_cached | 2 |
81| Qcache_queries_in_cache | 2 |
82| Qcache_total_blocks | 6 |
83+-------------------------+-----------+
848 rows in set (0.000 sec)
85
8607:56:30(root@localhost) [hellodb]> select *from students where stuid=1;
87+-------+-------------+-----+--------+---------+-----------+
88| StuID | Name | Age | Gender | ClassID | TeacherID |
89+-------+-------------+-----+--------+---------+-----------+
90| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
91+-------+-------------+-----+--------+---------+-----------+
921 row in set (0.000 sec)
93
9407:56:38(root@localhost) [hellodb]> show global status like 'Qcache%%';
95+-------------------------+-----------+
96| Variable_name | Value |
97+-------------------------+-----------+
98| Qcache_free_blocks | 1 |
99| Qcache_free_memory | 209694632 |
100| Qcache_hits | 2 |
101| Qcache_inserts | 2 |
102| Qcache_lowmem_prunes | 0 |
103| Qcache_not_cached | 2 |
104| Qcache_queries_in_cache | 2 |
105| Qcache_total_blocks | 6 |
106+-------------------------+-----------+
1078 rows in set (0.001 sec)
大小写有区别;
空格在sql语句中间有区别,但在sql语句前面或者最后面是可以的;
查询的优化

命中率和内存使用率估算
查询缓存中内存块的最小分配单位query_cache_min_res_unit :
1(query_cache_size - Qcache_free_memory) / Qcache_queries_in_cache查询缓存命中率 :
1Qcache_hits / ( Qcache_hits + Qcache_inserts ) * 100%查询缓存内存使用率:
1(query_cache_size – qcache_free_memory) / query_cache_size * 100%
MySQL 8.0 变化
MySQL8.0 取消查询缓存的功能
尽管MySQL Query Cache旨在提高性能,但它存在严重的可伸缩性问题,并且很容易成为严重的瓶颈。
自MySQL 5.6(2013)以来,默认情况下已禁用查询缓存,其不能与多核计算机上在高吞吐量工作负载情况下进行扩展。
另外有时因为查询缓存往往弊大于利。比如:查询缓存的失效非常频繁,只要有对一个表的更新,这个表上的所有的查询缓存都会被清空。因此很可能你费劲地把结果存起来,还没使用呢,就被一个更新全清空了。对于更新压力大的数据库来说,查询缓存的命中率会非常低。除非你的业务有一张静态表,很长时间更新一次,比如系统配置表,那么这张表的查询才适合做查询缓存。
目前大多数应用都把缓存做到了应用逻辑层,比如:使用redis或者memcache。
INDEX 索引
很重要。
索引介绍
索引:是排序的快速查找的特殊数据结构,定义作为查找条件的字段上,又称为键key,索引通过存储引擎实现
优点:
- 索引可以降低服务需要扫描的数据量,减少了IO次数
- 索引可以帮助服务器避免排序和使用临时表
- 索引可以帮助将随机I/O转为顺序I/O
缺点:
- 占用额外空间,影响插入速度
索引类型:
- B+ TREE、HASH、R TREE、FULL TEXT
- 聚簇(集)索引、非聚簇索引:数据和索引是否存储在一起
- 主键索引、二级(辅助)索引
- 稠密索引、稀疏索引:是否索引了每一个数据项
- 简单索引、组合索引
- 左前缀索引:取前面的字符做索引
- 覆盖索引:从索引中即可取出要查询的数据,性能高
索引结构
二叉树

红黑树

B Tree 索引

B+Tree索引

B+Tree索引:按顺序存储,每一个叶子节点到根结点的距离是相同的;左前缀索引,适合查询范围类的数据
可以使用B+Tree索引的查询类型:
全值匹配:精确所有索引列,如:姓wang,名xiaochun,年龄30
匹配最左前缀:即只使用索引的第一列,如:姓wang
匹配列前缀:只匹配一列值开头部分,如:姓以w开头的
匹配范围值:如:姓ma和姓wang之间
精确匹配某一列并范围匹配另一列:如:姓wang,名以x开头的
只访问索引的查询
B+Tree索引的限制:
- 如不从最左列开始,则无法使用索引,如:查找名为xiaochun,或姓为g结尾
- 不能跳过索引中的列:如:查找姓wang,年龄30的,只能使用索引第一列
特别提示:
索引列的顺序和查询语句的写法应相匹配,才能更好的利用索引
为优化性能,可能需要针对相同的列但顺序不同创建不同的索引来满足不同类型的查询需求
Hash索引
Hash索引:基于哈希表实现,只有精确匹配索引中的所有列的查询才有效,索引自身只存储索引列对
应的哈希值和数据指针,索引结构紧凑,查询性能好
Memory存储引擎支持显式hash索引,InnoDB和MyISAM存储引擎不支持
适用场景:只支持等值比较查询,包括=, <=>, IN()
不适合使用hash索引的场景
不适用于顺序查询:索引存储顺序的不是值的顺序
不支持模糊匹配
不支持范围查询
不支持部分索引列匹配查找:如A,B列索引,只查询A列索引无效
空间数据索引R-Tree( Geospatial indexing )
MyISAM支持地理空间索引,可使用任意维度组合查询,使用特有的函数访问,常用于做地理数据存
储,使用不多
InnoDB从MySQL5.7之后也开始支持
全文索引(FULLTEXT)
在文本中查找关键词,而不是直接比较索引中的值,类似搜索引擎
InnoDB从MySQL 5.6之后也开始支持
聚簇和非聚簇索引,主键和二级索引


冗余和重复索引:
冗余索引:(A),(A,B)
重复索引:已经有索引,再次建立索引
索引优化
- 独立地使用列:尽量避免其参与运算,独立的列指索引列不能是表达式的一部分,也不能是函数的参数,在where条件中,始终将索引列单独放在比较符号的一侧,尽量不要在列上进行运算(函数操作和表达式操作)
- 左前缀索引:构建指定索引字段的左侧的字符数,要通过索引选择性(不重复的索引值和数据表的
- 记录总数的比值)来评估,尽量使用短索引,如果可以,应该制定一个前缀长度
- 多列索引:AND操作时更适合使用多列索引,而非为每个列创建单独的索引
- 选择合适的索引列顺序:无排序和分组时,将选择性最高放左侧
- 只要列中含有NULL值,就最好不要在此列设置索引,复合索引如果有NULL值,此列在使用时也不会使用索引
- 对于经常在where子句使用的列,最好设置索引
- 对于有多个列where或者order by子句,应该建立复合索引
- 对于like语句,以 % 或者 _ 开头的不会使用索引,以 % 结尾会使用索引
- 尽量不要使用not in和
<>操作,虽然可能使用索引,但性能不高 - 不要使用RLIKE正则表达式会导致索引失效
- 查询时,能不要就不用,尽量写全字段名,比如:select id,name,age from students;
- 大部分情况连接效率远大于子查询
- 在有大量记录的表分页时使用limit
- 对于经常使用的查询,可以开启查询缓存
- 多使用explain和profile分析查询语句
- 查看慢查询日志,找出执行时间长的sql语句优化
管理索引
创建索引:
1CREATE [UNIQUE] INDEX index_name ON tbl_name (index_col_name[(length)],...);
2
3ALTER TABLE tbl_name ADD INDEX index_name(index_col_name[(length)]);
4
5help CREATE INDEX;
删除索引:
1DROP INDEX index_name ON tbl_name;
2
3ALTER TABLE tbl_name DROP INDEX index_name(index_col_name);
查看索引:
1SHOW INDEXES FROM [db_name.]tbl_name;
优化表空间:
1OPTIMIZE TABLE tb_name;
查看索引的使用
1SET GLOBAL userstat=1;
2SHOW INDEX_STATISTICS;
范例
1MariaDB [hellodb]> show index from students\G
2*************************** 1. row ***************************
3 Table: students
4 Non_unique: 0
5 Key_name: PRIMARY
6 Seq_in_index: 1
7 Column_name: StuID
8 Collation: A
9 Cardinality: 25
10 Sub_part: NULL
11 Packed: NULL
12 Null:
13 Index_type: BTREE
14 Comment:
15Index_comment:
161 row in set (0.001 sec)
17
18MariaDB [hellodb]> desc students;
19#这里的key就是索引,建主键的时候同时就自动建立了索引。
20+-----------+---------------------+------+-----+---------+----------------+
21| Field | Type | Null | Key | Default | Extra |
22+-----------+---------------------+------+-----+---------+----------------+
23| StuID | int(10) unsigned | NO | PRI | NULL | auto_increment |
24| Name | varchar(50) | NO | | NULL | |
25| Age | tinyint(3) unsigned | NO | | NULL | |
26| Gender | enum('F','M') | NO | | NULL | |
27| ClassID | tinyint(3) unsigned | YES | | NULL | |
28| TeacherID | int(10) unsigned | YES | | NULL | |
29+-----------+---------------------+------+-----+---------+----------------+
306 rows in set (0.001 sec)
31
32
33#手动建立索引
34MariaDB [hellodb]> create index idx_name on students(name(10));
35Query OK, 0 rows affected (0.007 sec)
36Records: 0 Duplicates: 0 Warnings: 0
37
38MariaDB [hellodb]> show index from students\G
39*************************** 1. row ***************************
40 Table: students
41 Non_unique: 0
42 Key_name: PRIMARY
43 Seq_in_index: 1
44 Column_name: StuID
45 Collation: A
46 Cardinality: 25
47 Sub_part: NULL
48 Packed: NULL
49 Null:
50 Index_type: BTREE
51 Comment:
52Index_comment:
53*************************** 2. row ***************************
54 Table: students
55 Non_unique: 1
56 Key_name: idx_name
57 Seq_in_index: 1
58 Column_name: Name
59 Collation: A
60 Cardinality: 25
61 Sub_part: 10
62 Packed: NULL
63 Null:
64 Index_type: BTREE
65 Comment:
66Index_comment:
672 rows in set (0.001 sec)
68MariaDB [hellodb]> desc students;
69+-----------+---------------------+------+-----+---------+----------------+
70| Field | Type | Null | Key | Default | Extra |
71+-----------+---------------------+------+-----+---------+----------------+
72| StuID | int(10) unsigned | NO | PRI | NULL | auto_increment |
73| Name | varchar(50) | NO | MUL | NULL | |
74| Age | tinyint(3) unsigned | NO | | NULL | |
75| Gender | enum('F','M') | NO | | NULL | |
76| ClassID | tinyint(3) unsigned | YES | | NULL | |
77| TeacherID | int(10) unsigned | YES | | NULL | |
78+-----------+---------------------+------+-----+---------+----------------+
796 rows in set (0.001 sec)
80
81
82
83#删除索引
84MariaDB [hellodb]> drop index idx_name on students;
85Query OK, 0 rows affected (0.004 sec)
86Records: 0 Duplicates: 0 Warnings: 0
87
88MariaDB [hellodb]> desc students;
89+-----------+---------------------+------+-----+---------+----------------+
90| Field | Type | Null | Key | Default | Extra |
91+-----------+---------------------+------+-----+---------+----------------+
92| StuID | int(10) unsigned | NO | PRI | NULL | auto_increment |
93| Name | varchar(50) | NO | | NULL | |
94| Age | tinyint(3) unsigned | NO | | NULL | |
95| Gender | enum('F','M') | NO | | NULL | |
96| ClassID | tinyint(3) unsigned | YES | | NULL | |
97| TeacherID | int(10) unsigned | YES | | NULL | |
98+-----------+---------------------+------+-----+---------+----------------+
996 rows in set (0.001 sec)
100MariaDB [hellodb]> show index from students\G
101*************************** 1. row ***************************
102 Table: students
103 Non_unique: 0
104 Key_name: PRIMARY
105 Seq_in_index: 1
106 Column_name: StuID
107 Collation: A
108 Cardinality: 25
109 Sub_part: NULL
110 Packed: NULL
111 Null:
112 Index_type: BTREE
113 Comment:
114Index_comment:
1151 row in set (0.000 sec)
1MariaDB [hellodb]> select @@userstat;
2+------------+
3| @@userstat |
4+------------+
5| 0 |
6+------------+
71 row in set (0.000 sec)
8
9MariaDB [hellodb]> show variables like 'userstat';
10+---------------+-------+
11| Variable_name | Value |
12+---------------+-------+
13| userstat | OFF |
14+---------------+-------+
151 row in set (0.001 sec)
16
17
18#开启
19MariaDB [hellodb]> set global userstat=1;
20Query OK, 0 rows affected (0.000 sec)
21
22MariaDB [hellodb]> show variables like 'userstat';
23+---------------+-------+
24| Variable_name | Value |
25+---------------+-------+
26| userstat | ON |
27+---------------+-------+
281 row in set (0.001 sec)
29
30
31#再次建立下之前的索引
32MariaDB [hellodb]> create index idx_name on students(name(10));
33Query OK, 0 rows affected (0.004 sec)
34Records: 0 Duplicates: 0 Warnings: 0
35
36MariaDB [hellodb]> desc students;
37+-----------+---------------------+------+-----+---------+----------------+
38| Field | Type | Null | Key | Default | Extra |
39+-----------+---------------------+------+-----+---------+----------------+
40| StuID | int(10) unsigned | NO | PRI | NULL | auto_increment |
41| Name | varchar(50) | NO | MUL | NULL | |
42| Age | tinyint(3) unsigned | NO | | NULL | |
43| Gender | enum('F','M') | NO | | NULL | |
44| ClassID | tinyint(3) unsigned | YES | | NULL | |
45| TeacherID | int(10) unsigned | YES | | NULL | |
46+-----------+---------------------+------+-----+---------+----------------+
476 rows in set (0.001 sec)
48
49
50
51#MariaDB [hellodb]> show index_statistics;
52Empty set (0.000 sec)
53
54
55#直接查,是没有利用索引的
56MariaDB [hellodb]> select *from students;
57+-------+---------------+-----+--------+---------+-----------+
58| StuID | Name | Age | Gender | ClassID | TeacherID |
59+-------+---------------+-----+--------+---------+-----------+
60| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
61| 2 | Shi Potian | 22 | M | 1 | 7 |
62| 3 | Xie Yanke | 53 | M | 2 | 16 |
63| 4 | Ding Dian | 32 | M | 4 | 4 |
64| 5 | Yu Yutong | 26 | M | 3 | 1 |
65| 6 | Shi Qing | 46 | M | 5 | NULL |
66| 7 | Xi Ren | 19 | F | 3 | NULL |
67| 8 | Lin Daiyu | 17 | F | 7 | NULL |
68| 9 | Ren Yingying | 20 | F | 6 | NULL |
69| 10 | Yue Lingshan | 19 | F | 3 | NULL |
70| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
71| 12 | Wen Qingqing | 19 | F | 1 | NULL |
72| 13 | Tian Boguang | 33 | M | 2 | NULL |
73| 14 | Lu Wushuang | 17 | F | 3 | NULL |
74| 15 | Duan Yu | 19 | M | 4 | NULL |
75| 16 | Xu Zhu | 21 | M | 1 | NULL |
76| 17 | Lin Chong | 25 | M | 4 | NULL |
77| 18 | Hua Rong | 23 | M | 7 | NULL |
78| 19 | Xue Baochai | 18 | F | 6 | NULL |
79| 20 | Diao Chan | 19 | F | 7 | NULL |
80| 21 | Huang Yueying | 22 | F | 6 | NULL |
81| 22 | Xiao Qiao | 20 | F | 1 | NULL |
82| 23 | Ma Chao | 23 | M | 4 | NULL |
83| 24 | Xu Xian | 27 | M | NULL | NULL |
84| 25 | Sun Dasheng | 100 | M | NULL | NULL |
85+-------+---------------+-----+--------+---------+-----------+
8625 rows in set (0.001 sec)
87
88MariaDB [hellodb]> show index_statistics;
89Empty set (0.000 sec)
90
91
92
93#模拟使用索引
94MariaDB [hellodb]> select *from students where stuid=10;
95+-------+--------------+-----+--------+---------+-----------+
96| StuID | Name | Age | Gender | ClassID | TeacherID |
97+-------+--------------+-----+--------+---------+-----------+
98| 10 | Yue Lingshan | 19 | F | 3 | NULL |
99+-------+--------------+-----+--------+---------+-----------+
1001 row in set (0.001 sec)
101
102MariaDB [hellodb]> show index_statistics;
103+--------------+------------+------------+-----------+
104| Table_schema | Table_name | Index_name | Rows_read |
105+--------------+------------+------------+-----------+
106| hellodb | students | PRIMARY | 1 |
107+--------------+------------+------------+-----------+
1081 row in set (0.000 sec)
109
110MariaDB [hellodb]> select *from students where stuid=10;
111+-------+--------------+-----+--------+---------+-----------+
112| StuID | Name | Age | Gender | ClassID | TeacherID |
113+-------+--------------+-----+--------+---------+-----------+
114| 10 | Yue Lingshan | 19 | F | 3 | NULL |
115+-------+--------------+-----+--------+---------+-----------+
1161 row in set (0.001 sec)
117
118MariaDB [hellodb]> show index_statistics;
119+--------------+------------+------------+-----------+
120| Table_schema | Table_name | Index_name | Rows_read |
121+--------------+------------+------------+-----------+
122| hellodb | students | PRIMARY | 2 |
123+--------------+------------+------------+-----------+
1241 row in set (0.000 sec)
125
126
127MariaDB [hellodb]> select *from students where name='Yue Lingshan';
128+-------+--------------+-----+--------+---------+-----------+
129| StuID | Name | Age | Gender | ClassID | TeacherID |
130+-------+--------------+-----+--------+---------+-----------+
131| 10 | Yue Lingshan | 19 | F | 3 | NULL |
132+-------+--------------+-----+--------+---------+-----------+
1331 row in set (0.001 sec)
134
135MariaDB [hellodb]> show index_statistics;
136+--------------+------------+------------+-----------+
137| Table_schema | Table_name | Index_name | Rows_read |
138+--------------+------------+------------+-----------+
139| hellodb | students | idx_name | 1 |
140| hellodb | students | PRIMARY | 2 |
141+--------------+------------+------------+-----------+
1422 rows in set (0.000 sec)
143
144MariaDB [hellodb]> select *from students where name='Yue Lingshan';
145+-------+--------------+-----+--------+---------+-----------+
146| StuID | Name | Age | Gender | ClassID | TeacherID |
147+-------+--------------+-----+--------+---------+-----------+
148| 10 | Yue Lingshan | 19 | F | 3 | NULL |
149+-------+--------------+-----+--------+---------+-----------+
1501 row in set (0.001 sec)
151
152MariaDB [hellodb]> show index_statistics;
153+--------------+------------+------------+-----------+
154| Table_schema | Table_name | Index_name | Rows_read |
155+--------------+------------+------------+-----------+
156| hellodb | students | idx_name | 2 |
157| hellodb | students | PRIMARY | 2 |
158+--------------+------------+------------+-----------+
1592 rows in set (0.000 sec)
160#可以通过这个简单的方法来统计索引用没用。
161#以上命令只能粗略地看到是否使用索引,而不能看到她的细节。
EXPLAIN 工具
可以通过EXPLAIN来分析索引的有效性,获取查询执行计划信息,用来查看查询优化器如何执行查询
参考资料: https://dev.mysql.com/doc/refman/5.7/en/explain-output.html
语法:
1EXPLAIN SELECT clause
EXPLAIN输出信息说明:

说明: type显示的是访问类型,是较为重要的一个指标,结果值从好到坏依次是:system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL ,一般来说,得保证查询至少达到range级别,最好能达到ref。

一般,达到range基本算是优化可以的了,如果出现index或者all,就说明这个索引还是有优化的空间。
范例:
1MariaDB [hellodb]> explain select *from students;
2+------+-------------+----------+------+---------------+------+---------+------+------+-------+
3| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
4+------+-------------+----------+------+---------------+------+---------+------+------+-------+
5| 1 | SIMPLE | students | ALL | NULL | NULL | NULL | NULL | 25 | |
6+------+-------------+----------+------+---------------+------+---------+------+------+-------+
71 row in set (0.000 sec)
8
9MariaDB [hellodb]> select *from students where name like 'x%';
10+-------+-------------+-----+--------+---------+-----------+
11| StuID | Name | Age | Gender | ClassID | TeacherID |
12+-------+-------------+-----+--------+---------+-----------+
13| 7 | Xi Ren | 19 | F | 3 | NULL |
14| 22 | Xiao Qiao | 20 | F | 1 | NULL |
15| 3 | Xie Yanke | 53 | M | 2 | 16 |
16| 24 | Xu Xian | 27 | M | NULL | NULL |
17| 16 | Xu Zhu | 21 | M | 1 | NULL |
18| 19 | Xue Baochai | 18 | F | 6 | NULL |
19+-------+-------------+-----+--------+---------+-----------+
206 rows in set (0.001 sec)
21
22
23MariaDB [hellodb]> explain select *from students where name like 's%';
24+------+-------------+----------+-------+---------------+----------+---------+------+------+-------------+
25| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
26+------+-------------+----------+-------+---------------+----------+---------+------+------+-------------+
27| 1 | SIMPLE | students | range | idx_name | idx_name | 32 | NULL | 4 | Using where |
28+------+-------------+----------+-------+---------------+----------+---------+------+------+-------------+
291 row in set (0.001 sec)

1#左模糊、全模糊是无法使用索引的
2MariaDB [hellodb]> select *from students where name like '%o';
3+-------+-----------+-----+--------+---------+-----------+
4| StuID | Name | Age | Gender | ClassID | TeacherID |
5+-------+-----------+-----+--------+---------+-----------+
6| 22 | Xiao Qiao | 20 | F | 1 | NULL |
7| 23 | Ma Chao | 23 | M | 4 | NULL |
8+-------+-----------+-----+--------+---------+-----------+
92 rows in set (0.001 sec)
10
11MariaDB [hellodb]> explain select *from students where name like '%o';
12+------+-------------+----------+------+---------------+------+---------+------+------+-------------+
13| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
14+------+-------------+----------+------+---------------+------+---------+------+------+-------------+
15| 1 | SIMPLE | students | ALL | NULL | NULL | NULL | NULL | 25 | Using where |
16+------+-------------+----------+------+---------------+------+---------+------+------+-------------+
171 row in set (0.000 sec)
18
19
20#以下是可以利用索引的
21MariaDB [hellodb]> explain select *from students where stuid > 20;
22+------+-------------+----------+-------+---------------+---------+---------+------+------+-------------+
23| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
24+------+-------------+----------+-------+---------------+---------+---------+------+------+-------------+
25| 1 | SIMPLE | students | range | PRIMARY | PRIMARY | 4 | NULL | 5 | Using where |
26+------+-------------+----------+-------+---------------+---------+---------+------+------+-------------+
271 row in set (0.000 sec)
28
29MariaDB [hellodb]> explain select *from students where stuid > 10 and stuid < 20;
30+------+-------------+----------+-------+---------------+---------+---------+------+------+-------------+
31| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
32+------+-------------+----------+-------+---------------+---------+---------+------+------+-------------+
33| 1 | SIMPLE | students | range | PRIMARY | PRIMARY | 4 | NULL | 9 | Using where |
34+------+-------------+----------+-------+---------------+---------+---------+------+------+-------------+
351 row in set (0.001 sec)

1#正则表达式是不使用索引的,很少简单where后面跟正则表达式的
2MariaDB [hellodb]> explain select *from students where name rlike '^w';
3+------+-------------+----------+------+---------------+------+---------+------+------+-------------+
4| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
5+------+-------------+----------+------+---------------+------+---------+------+------+-------------+
6| 1 | SIMPLE | students | ALL | NULL | NULL | NULL | NULL | 25 | Using where |
7+------+-------------+----------+------+---------------+------+---------+------+------+-------------+
81 row in set (0.001 sec)
9
10MariaDB [hellodb]> explain select *from students where name rlike '^W';
11+------+-------------+----------+------+---------------+------+---------+------+------+-------------+
12| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
13+------+-------------+----------+------+---------------+------+---------+------+------+-------------+
14| 1 | SIMPLE | students | ALL | NULL | NULL | NULL | NULL | 25 | Using where |
15+------+-------------+----------+------+---------------+------+---------+------+------+-------------+
161 row in set (0.001 sec)
1#创建复合索引
2MariaDB [hellodb]> create index idx_name_age on students(name,age);
3Query OK, 0 rows affected (0.006 sec)
4Records: 0 Duplicates: 0 Warnings: 0
5
6
7MariaDB [hellodb]> show index from students;
8+----------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
9| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
10+----------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
11| students | 0 | PRIMARY | 1 | StuID | A | 25 | NULL | NULL | | BTREE | | |
12| students | 1 | idx_name | 1 | Name | A | 25 | 10 | NULL | | BTREE | | |
13| students | 1 | idx_name_age | 1 | Name | A | 25 | NULL | NULL | | BTREE | | |
14| students | 1 | idx_name_age | 2 | Age | A | 25 | NULL | NULL | | BTREE | | |
15+----------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
16
17
18#删除冗余索引
19MariaDB [hellodb]> drop index idx_name on students;
20Query OK, 0 rows affected (0.004 sec)
21Records: 0 Duplicates: 0 Warnings: 0
22
23
24
25MariaDB [hellodb]> explain select *from students where name = "Xu Zhu";
26+------+-------------+----------+------+---------------+--------------+---------+-------+------+-----------------------+
27| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
28+------+-------------+----------+------+---------------+--------------+---------+-------+------+-----------------------+
29| 1 | SIMPLE | students | ref | idx_name_age | idx_name_age | 152 | const | 1 | Using index condition |
30+------+-------------+----------+------+---------------+--------------+---------+-------+------+-----------------------+
311 row in set (0.001 sec)
32
33#索引失效
34MariaDB [hellodb]> explain select *from students where age = 20;
35+------+-------------+----------+------+---------------+------+---------+------+------+-------------+
36| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
37+------+-------------+----------+------+---------------+------+---------+------+------+-------------+
38| 1 | SIMPLE | students | ALL | NULL | NULL | NULL | NULL | 25 | Using where |
39+------+-------------+----------+------+---------------+------+---------+------+------+-------------+
401 row in set (0.001 sec)
41
42#索引失效(做模糊)
43MariaDB [hellodb]> explain select *from students where name like '%s' and age = 20;
44+------+-------------+----------+------+---------------+------+---------+------+------+-------------+
45| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
46+------+-------------+----------+------+---------------+------+---------+------+------+-------------+
47| 1 | SIMPLE | students | ALL | NULL | NULL | NULL | NULL | 25 | Using where |
48+------+-------------+----------+------+---------------+------+---------+------+------+-------------+
491 row in set (0.001 sec)
50
51MariaDB [hellodb]> explain select *from students where name = 'Ma Chao' and age = 20;
52+------+-------------+----------+------+---------------+--------------+---------+-------------+------+-----------------------+
53| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
54+------+-------------+----------+------+---------------+--------------+---------+-------------+------+-----------------------+
55| 1 | SIMPLE | students | ref | idx_name_age | idx_name_age | 153 | const,const | 1 | Using index condition |
56+------+-------------+----------+------+---------------+--------------+---------+-------------+------+-----------------------+
571 row in set (0.001 sec)
并发控制
锁机制
锁:
读锁:共享锁,也称为 S 锁,只读不可写(包括当前事务) ,多个读互不阻塞
写锁:独占锁,排它锁,也称为 X 锁,写锁会阻塞其它事务(不包括当前事务)的读和写
S 锁和 S 锁是兼容的,X 锁和其它锁都不兼容,举个例子,事务 T1 获取了一个行 r1 的 S 锁,另外事务 T2 可以立即获得行 r1 的 S 锁,此时 T1 和 T2 共同获得行 r1 的 S 锁,此种情况称为锁兼容,但是另外一个事务 T2 此时如果想获得行 r1 的 X 锁,则必须等待 T1 对行 r 锁的释放,此种情况也成为锁冲突
锁粒度:
- 表级锁:MyISAM
- 行级锁:InnodB
实现:
存储引擎:自行实现其锁策略和锁粒度
服务器级:实现了锁,表级锁,用户可显式请求
分类:
隐式锁:由存储引擎自动施加锁
显式锁:用户手动请求
锁策略:在锁粒度及数据安全性寻求的平衡机制
显式使用锁
帮助:https://mariadb.com/kb/en/lock-tables/
加锁:
1LOCK TABLES tbl_name [[AS] alias] lock_type [, tbl_name [[AS] alias]
2lock_type] ...
3
4lock_type:
5READ
6WRITE
解锁
1UNLOCK TABLES
关闭正在打开的表(清除查询缓存),通常在备份前加全局读锁
1FLUSH TABLES [tb_name[,...]] [WITH READ LOCK]
2
3#范例
4FLUSH TABLES WITH READ LOCK;
查询时加写或读锁
1SELECT clause [FOR UPDATE | LOCK IN SHARE MODE]
范例: 加读锁
1mysql> lock tables students read ;
2Query OK, 0 rows affected (0.00 sec)
3
4mysql> update students set classid=2 where stuid=24;
5ERROR 1099 (HY000): Table 'students' was locked with a READ lock and can't be updated
6
7mysql> unlock tables ;
8mysql> update students set classid=2 where stuid=24;
9Query OK, 1 row affected (1 min 45.52 sec)
10Rows matched: 1 Changed: 1 Warnings: 0
范例: 同时在两个终端对同一行记录修改
1#同时对同一行记录执行update
2#在第一终端提示1行成功
3MariaDB [hellodb]> update students set classid=1 where stuid=24;
4Query OK, 1 row affected (0.002 sec)
5Rows matched: 1 Changed: 1 Warnings: 0
6
7#在第二终端提示0行修改
8MariaDB [hellodb]> update students set classid=1 where stuid=24;
9Query OK, 0 rows affected (0.000 sec)
10Rows matched: 1 Changed: 0 Warnings: 0
范例:如果加锁终端被关闭了,那么锁自然也不存在了。
1#终端1
2MariaDB [hellodb]> FLUSH TABLES WITH READ LOCK;
3
4#终端2
5MariaDB [hellodb]> show processlist;
6+----+------+-----------+---------+---------+------+----------+------------------+----------+
7| Id | User | Host | db | Command | Time | State | Info | Progress |
8+----+------+-----------+---------+---------+------+----------+------------------+----------+
9| 68 | root | localhost | hellodb | Sleep | 10 | | NULL | 0.000 |
10| 69 | root | localhost | hellodb | Query | 0 | starting | show processlist | 0.000 |
11+----+------+-----------+---------+---------+------+----------+------------------+----------+
122 rows in set (0.000 sec)
13
14MariaDB [hellodb]> \s
15--------------
16mysql Ver 15.1 Distrib 10.5.25-MariaDB, for Linux (x86_64) using readline 5.1
17
18Connection id: 69
19Current database: hellodb
20Current user: root@localhost
21SSL: Not in use
22Current pager: stdout
23Using outfile: ''
24Using delimiter: ;
25Server: MariaDB
26Server version: 10.5.25-MariaDB MariaDB Server
27Protocol version: 10
28Connection: Localhost via UNIX socket
29Server characterset: latin1
30Db characterset: utf8
31Client characterset: utf8
32Conn. characterset: utf8
33UNIX socket: /var/lib/mysql/mysql.sock
34Uptime: 1 day 1 hour 39 min 43 sec
35
36Threads: 2 Questions: 303 Slow queries: 0 Opens: 52 Open tables: 0 Queries per second avg: 0.003
37--------------
38
39MariaDB [hellodb]> update students set classid=2 where stuid=24;
40Query OK, 1 row affected (3.299 sec)
41Rows matched: 1 Changed: 1 Warnings: 0
42
43MariaDB [hellodb]>
事务
事务Transactions:一组原子性的SQL语句,或一个独立工作单元
事务日志:记录事务信息,实现undo,redo等故障恢复功能
事务特性
ACID特性:
- A:atomicity原子性:整个事务中的所有操作要么全部成功执行,要么全部失败后回滚
- C:consistency一致性:数据库总是从一个一致性状态转换为另一个一致性状态
- I:Isolation隔离性:一个事务所做出的操作在提交之前,是不能为其它事务所见;隔离有多种隔离级别,实现并发
- D:durability持久性:一旦事务提交,其所做的修改会永久保存于数据库中
Transaction生命周期

管理事务
显式启动事务:
1BEGIN
2BEGIN WORK
3START TRANSACTION
结束事务:
1#提交
2COMMIT
3#回滚
4ROLLBACK
注意:只有事务型存储引擎中的DML语句方能支持此类操作
事务不是万能的!有些指令,并不受事务的约束。 DML语句:insert、update、delete
但注意:truncate、drop等语句本身就是一条提交事务,不走事务机制的,删除就真难得被删除了。
drop table teachers;
truncate table students;
自动提交:
1set autocommit={1|0}
默认为1,为0时设为非自动提交
建议:显式请求和提交事务,而不要使用“自动提交”功能。
事务支持保存点:
1SAVEPOINT identifier
2ROLLBACK [WORK] TO [SAVEPOINT] identifier
3RELEASE SAVEPOINT identifier
查看事务:
1#查看当前正在进行的事务
2SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;
3#查看当前锁定的事务
4SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
5#查看当前等锁的事务
6SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
范例:测试事务
1#查看测试表
2MariaDB [hellodb]> select *from students;
3+-------+---------------+-----+--------+---------+-----------+
4| StuID | Name | Age | Gender | ClassID | TeacherID |
5+-------+---------------+-----+--------+---------+-----------+
6| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
7| 2 | Shi Potian | 22 | M | 1 | 7 |
8| 3 | Xie Yanke | 53 | M | 2 | 16 |
9| 4 | Ding Dian | 32 | M | 4 | 4 |
10| 5 | Yu Yutong | 26 | M | 3 | 1 |
11| 6 | Shi Qing | 46 | M | 5 | NULL |
12| 7 | Xi Ren | 19 | F | 3 | NULL |
13| 8 | Lin Daiyu | 17 | F | 7 | NULL |
14| 9 | Ren Yingying | 20 | F | 6 | NULL |
15| 10 | Yue Lingshan | 19 | F | 3 | NULL |
16| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
17| 12 | Wen Qingqing | 19 | F | 1 | NULL |
18| 13 | Tian Boguang | 33 | M | 2 | NULL |
19| 14 | Lu Wushuang | 17 | F | 3 | NULL |
20| 15 | Duan Yu | 19 | M | 4 | NULL |
21| 16 | Xu Zhu | 21 | M | 1 | NULL |
22| 17 | Lin Chong | 25 | M | 4 | NULL |
23| 18 | Hua Rong | 23 | M | 7 | NULL |
24| 19 | Xue Baochai | 18 | F | 6 | NULL |
25| 20 | Diao Chan | 19 | F | 7 | NULL |
26| 21 | Huang Yueying | 22 | F | 6 | NULL |
27| 22 | Xiao Qiao | 20 | F | 1 | NULL |
28| 23 | Ma Chao | 23 | M | 4 | NULL |
29| 24 | Xu Xian | 27 | M | 2 | NULL |
30| 25 | Sun Dasheng | 100 | M | NULL | NULL |
31+-------+---------------+-----+--------+---------+-----------+
3225 rows in set (0.000 sec)
33
34
35#在一个会话里显示开启一个事务
36MariaDB [hellodb]> begin;
37Query OK, 0 rows affected (0.000 sec)
38
39
40#执行2条DML语句
41MariaDB [hellodb]> update students set classid=1 where stuid=25;
42Query OK, 1 row affected (0.001 sec)
43Rows matched: 1 Changed: 1 Warnings: 0
44MariaDB [hellodb]> delete from students where stuid=24;
45Query OK, 1 row affected (0.001 sec)
46
47#在当前会话里是可以正常看到执行效果的
48
49MariaDB [hellodb]> select *from students;
50+-------+---------------+-----+--------+---------+-----------+
51| StuID | Name | Age | Gender | ClassID | TeacherID |
52+-------+---------------+-----+--------+---------+-----------+
53| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
54| 2 | Shi Potian | 22 | M | 1 | 7 |
55| 3 | Xie Yanke | 53 | M | 2 | 16 |
56| 4 | Ding Dian | 32 | M | 4 | 4 |
57| 5 | Yu Yutong | 26 | M | 3 | 1 |
58| 6 | Shi Qing | 46 | M | 5 | NULL |
59| 7 | Xi Ren | 19 | F | 3 | NULL |
60| 8 | Lin Daiyu | 17 | F | 7 | NULL |
61| 9 | Ren Yingying | 20 | F | 6 | NULL |
62| 10 | Yue Lingshan | 19 | F | 3 | NULL |
63| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
64| 12 | Wen Qingqing | 19 | F | 1 | NULL |
65| 13 | Tian Boguang | 33 | M | 2 | NULL |
66| 14 | Lu Wushuang | 17 | F | 3 | NULL |
67| 15 | Duan Yu | 19 | M | 4 | NULL |
68| 16 | Xu Zhu | 21 | M | 1 | NULL |
69| 17 | Lin Chong | 25 | M | 4 | NULL |
70| 18 | Hua Rong | 23 | M | 7 | NULL |
71| 19 | Xue Baochai | 18 | F | 6 | NULL |
72| 20 | Diao Chan | 19 | F | 7 | NULL |
73| 21 | Huang Yueying | 22 | F | 6 | NULL |
74| 22 | Xiao Qiao | 20 | F | 1 | NULL |
75| 23 | Ma Chao | 23 | M | 4 | NULL |
76| 25 | Sun Dasheng | 100 | M | 1 | NULL |
77+-------+---------------+-----+--------+---------+-----------+
7824 rows in set (0.001 sec)
79
80
81#但是重新打开一个会话后,发现students表是没任何变化的
82
83MariaDB [hellodb]> select *from students;
84+-------+---------------+-----+--------+---------+-----------+
85| StuID | Name | Age | Gender | ClassID | TeacherID |
86+-------+---------------+-----+--------+---------+-----------+
87| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
88| 2 | Shi Potian | 22 | M | 1 | 7 |
89| 3 | Xie Yanke | 53 | M | 2 | 16 |
90| 4 | Ding Dian | 32 | M | 4 | 4 |
91| 5 | Yu Yutong | 26 | M | 3 | 1 |
92| 6 | Shi Qing | 46 | M | 5 | NULL |
93| 7 | Xi Ren | 19 | F | 3 | NULL |
94| 8 | Lin Daiyu | 17 | F | 7 | NULL |
95| 9 | Ren Yingying | 20 | F | 6 | NULL |
96| 10 | Yue Lingshan | 19 | F | 3 | NULL |
97| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
98| 12 | Wen Qingqing | 19 | F | 1 | NULL |
99| 13 | Tian Boguang | 33 | M | 2 | NULL |
100| 14 | Lu Wushuang | 17 | F | 3 | NULL |
101| 15 | Duan Yu | 19 | M | 4 | NULL |
102| 16 | Xu Zhu | 21 | M | 1 | NULL |
103| 17 | Lin Chong | 25 | M | 4 | NULL |
104| 18 | Hua Rong | 23 | M | 7 | NULL |
105| 19 | Xue Baochai | 18 | F | 6 | NULL |
106| 20 | Diao Chan | 19 | F | 7 | NULL |
107| 21 | Huang Yueying | 22 | F | 6 | NULL |
108| 22 | Xiao Qiao | 20 | F | 1 | NULL |
109| 23 | Ma Chao | 23 | M | 4 | NULL |
110| 24 | Xu Xian | 27 | M | 2 | NULL |
111| 25 | Sun Dasheng | 100 | M | NULL | NULL |
112+-------+---------------+-----+--------+---------+-----------+
11325 rows in set (0.001 sec)
114
115#这是为什么呢?--事务的隔离性
116# I:Isolation隔离性:一个事务所做出的操作在提交之前,是不能为其它事务所见;隔离有多种隔离级别,实现并发
117
118
119#那么我们在原来会话里可以执行rollback
120MariaDB [hellodb]> rollback;
121Query OK, 0 rows affected (0.001 sec)
122
123#执行之后,本会话看,students里的数据已经恢复到更改前端的状态了。
124MariaDB [hellodb]> select *from students;
125+-------+---------------+-----+--------+---------+-----------+
126| StuID | Name | Age | Gender | ClassID | TeacherID |
127+-------+---------------+-----+--------+---------+-----------+
128| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
129| 2 | Shi Potian | 22 | M | 1 | 7 |
130| 3 | Xie Yanke | 53 | M | 2 | 16 |
131| 4 | Ding Dian | 32 | M | 4 | 4 |
132| 5 | Yu Yutong | 26 | M | 3 | 1 |
133| 6 | Shi Qing | 46 | M | 5 | NULL |
134| 7 | Xi Ren | 19 | F | 3 | NULL |
135| 8 | Lin Daiyu | 17 | F | 7 | NULL |
136| 9 | Ren Yingying | 20 | F | 6 | NULL |
137| 10 | Yue Lingshan | 19 | F | 3 | NULL |
138| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
139| 12 | Wen Qingqing | 19 | F | 1 | NULL |
140| 13 | Tian Boguang | 33 | M | 2 | NULL |
141| 14 | Lu Wushuang | 17 | F | 3 | NULL |
142| 15 | Duan Yu | 19 | M | 4 | NULL |
143| 16 | Xu Zhu | 21 | M | 1 | NULL |
144| 17 | Lin Chong | 25 | M | 4 | NULL |
145| 18 | Hua Rong | 23 | M | 7 | NULL |
146| 19 | Xue Baochai | 18 | F | 6 | NULL |
147| 20 | Diao Chan | 19 | F | 7 | NULL |
148| 21 | Huang Yueying | 22 | F | 6 | NULL |
149| 22 | Xiao Qiao | 20 | F | 1 | NULL |
150| 23 | Ma Chao | 23 | M | 4 | NULL |
151| 24 | Xu Xian | 27 | M | 2 | NULL |
152| 25 | Sun Dasheng | 100 | M | NULL | NULL |
153+-------+---------------+-----+--------+---------+-----------+
15425 rows in set (0.001 sec)
155
156
157#再测试
158#开启一个事务,然后执行2条DML语句
159MariaDB [hellodb]> begin;
160Query OK, 0 rows affected (0.000 sec)
161
162MariaDB [hellodb]> update students set classid=1 where stuid=25;
163Query OK, 1 row affected (0.001 sec)
164Rows matched: 1 Changed: 1 Warnings: 0
165
166MariaDB [hellodb]> delete from students where stuid=24;
167Query OK, 1 row affected (0.001 sec)
168
169
170#当我吧当前会话关闭后,重新打开一个会话后,那么查看表的现象是什么样的呢?
171MariaDB [hellodb]> select *from students;
172+-------+---------------+-----+--------+---------+-----------+
173| StuID | Name | Age | Gender | ClassID | TeacherID |
174+-------+---------------+-----+--------+---------+-----------+
175| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
176| 2 | Shi Potian | 22 | M | 1 | 7 |
177| 3 | Xie Yanke | 53 | M | 2 | 16 |
178| 4 | Ding Dian | 32 | M | 4 | 4 |
179| 5 | Yu Yutong | 26 | M | 3 | 1 |
180| 6 | Shi Qing | 46 | M | 5 | NULL |
181| 7 | Xi Ren | 19 | F | 3 | NULL |
182| 8 | Lin Daiyu | 17 | F | 7 | NULL |
183| 9 | Ren Yingying | 20 | F | 6 | NULL |
184| 10 | Yue Lingshan | 19 | F | 3 | NULL |
185| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
186| 12 | Wen Qingqing | 19 | F | 1 | NULL |
187| 13 | Tian Boguang | 33 | M | 2 | NULL |
188| 14 | Lu Wushuang | 17 | F | 3 | NULL |
189| 15 | Duan Yu | 19 | M | 4 | NULL |
190| 16 | Xu Zhu | 21 | M | 1 | NULL |
191| 17 | Lin Chong | 25 | M | 4 | NULL |
192| 18 | Hua Rong | 23 | M | 7 | NULL |
193| 19 | Xue Baochai | 18 | F | 6 | NULL |
194| 20 | Diao Chan | 19 | F | 7 | NULL |
195| 21 | Huang Yueying | 22 | F | 6 | NULL |
196| 22 | Xiao Qiao | 20 | F | 1 | NULL |
197| 23 | Ma Chao | 23 | M | 4 | NULL |
198| 24 | Xu Xian | 27 | M | 2 | NULL |
199| 25 | Sun Dasheng | 100 | M | NULL | NULL |
200+-------+---------------+-----+--------+---------+-----------+
20125 rows in set (0.001 sec)
202#会发现表的状态依然是未发生改变的
203#这是由事务的 原子性来决定的。
204#A:atomicity原子性:整个事务中的所有操作要么全部成功执行,要么全部失败后回滚
205
206
207#再测试
208#开启一个事务,然后执行2条DML语句
209MariaDB [hellodb]> begin;
210Query OK, 0 rows affected (0.000 sec)
211
212MariaDB [hellodb]> update students set classid=1 where stuid=25;
213Query OK, 1 row affected (0.001 sec)
214Rows matched: 1 Changed: 1 Warnings: 0
215
216MariaDB [hellodb]> delete from students where stuid=24;
217Query OK, 1 row affected (0.001 sec)
218
219#自己执行下commit
220MariaDB [hellodb]> commit;
221Query OK, 0 rows affected
222
223
224MariaDB [hellodb]> select
225+-------+---------------+-
226| StuID | Name |
227+-------+---------------+-
228| 1 | Shi Zhongyu |
229| 2 | Shi Potian |
230| 3 | Xie Yanke |
231| 4 | Ding Dian |
232| 5 | Yu Yutong |
233| 6 | Shi Qing |
234| 7 | Xi Ren |
235| 8 | Lin Daiyu |
236| 9 | Ren Yingying |
237| 10 | Yue Lingshan |
238| 11 | Yuan Chengzhi |
239| 12 | Wen Qingqing |
240| 13 | Tian Boguang |
241| 14 | Lu Wushuang |
242| 15 | Duan Yu |
243| 16 | Xu Zhu |
244| 17 | Lin Chong |
245| 18 | Hua Rong |
246| 19 | Xue Baochai |
247| 20 | Diao Chan |
248| 21 | Huang Yueying |
249| 22 | Xiao Qiao |
250| 23 | Ma Chao |
251| 25 | Sun Dasheng |
252+-------+---------------+-
25324 rows in set (0.001 sec)
254#会发现自己当前会话里数据是发行了改变。关闭当前会话,再重新打开一个会话查看,发现数据已经被改变了的,符合预期。
255MariaDB [hellodb]> select *from students;
256+-------+---------------+-----+--------+---------+-----------+
257| StuID | Name | Age | Gender | ClassID | TeacherID |
258+-------+---------------+-----+--------+---------+-----------+
259| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
260| 2 | Shi Potian | 22 | M | 1 | 7 |
261| 3 | Xie Yanke | 53 | M | 2 | 16 |
262| 4 | Ding Dian | 32 | M | 4 | 4 |
263| 5 | Yu Yutong | 26 | M | 3 | 1 |
264| 6 | Shi Qing | 46 | M | 5 | NULL |
265| 7 | Xi Ren | 19 | F | 3 | NULL |
266| 8 | Lin Daiyu | 17 | F | 7 | NULL |
267| 9 | Ren Yingying | 20 | F | 6 | NULL |
268| 10 | Yue Lingshan | 19 | F | 3 | NULL |
269| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
270| 12 | Wen Qingqing | 19 | F | 1 | NULL |
271| 13 | Tian Boguang | 33 | M | 2 | NULL |
272| 14 | Lu Wushuang | 17 | F | 3 | NULL |
273| 15 | Duan Yu | 19 | M | 4 | NULL |
274| 16 | Xu Zhu | 21 | M | 1 | NULL |
275| 17 | Lin Chong | 25 | M | 4 | NULL |
276| 18 | Hua Rong | 23 | M | 7 | NULL |
277| 19 | Xue Baochai | 18 | F | 6 | NULL |
278| 20 | Diao Chan | 19 | F | 7 | NULL |
279| 21 | Huang Yueying | 22 | F | 6 | NULL |
280| 22 | Xiao Qiao | 20 | F | 1 | NULL |
281| 23 | Ma Chao | 23 | M | 4 | NULL |
282| 25 | Sun Dasheng | 100 | M | 1 | NULL |
283+-------+---------------+-----+--------+---------+-----------+
28424 rows in set (0.001 sec)
范例:事务支持保存点
1MariaDB [hellodb]> select *from teachers;
2+-----+---------------+-----+--------+
3| TID | Name | Age | Gender |
4+-----+---------------+-----+--------+
5| 1 | Song Jiang | 45 | M |
6| 2 | Zhang Sanfeng | 94 | M |
7| 3 | Miejue Shitai | 77 | F |
8| 4 | Lin Chaoying | 93 | F |
9+-----+---------------+-----+--------+
104 rows in set (0.001 sec)
11
12
13#开始事务:
14MariaDB [hellodb]> begin;insert teachers (name,age,gender)value('a',20,'M');
15Query OK, 0 rows affected (0.000 sec)
16
17Query OK, 1 row affected (0.000 sec)
18
19MariaDB [hellodb]> savepoint a;
20Query OK, 0 rows affected (0.000 sec)
21
22MariaDB [hellodb]> insert teachers (name,age,gender)value('b',30,'F');
23Query OK, 1 row affected (0.000 sec)
24
25MariaDB [hellodb]> savepoint b;
26Query OK, 0 rows affected (0.000 sec)
27
28MariaDB [hellodb]> insert teachers (name,age,gender)value('c',40,'F');
29Query OK, 1 row affected (0.000 sec)
30
31
32MariaDB [hellodb]> select *from teachers;
33+-----+---------------+-----+--------+
34| TID | Name | Age | Gender |
35+-----+---------------+-----+--------+
36| 1 | Song Jiang | 45 | M |
37| 2 | Zhang Sanfeng | 94 | M |
38| 3 | Miejue Shitai | 77 | F |
39| 4 | Lin Chaoying | 93 | F |
40| 5 | a | 20 | M |
41| 6 | b | 30 | F |
42| 7 | c | 40 | F |
43+-----+---------------+-----+--------+
447 rows in set (0.000 sec)
45
46
47#撤销
48MariaDB [hellodb]> rollback to b;
49Query OK, 0 rows affected (0.000 sec)
50
51MariaDB [hellodb]> select *from teachers;
52+-----+---------------+-----+--------+
53| TID | Name | Age | Gender |
54+-----+---------------+-----+--------+
55| 1 | Song Jiang | 45 | M |
56| 2 | Zhang Sanfeng | 94 | M |
57| 3 | Miejue Shitai | 77 | F |
58| 4 | Lin Chaoying | 93 | F |
59| 5 | a | 20 | M |
60| 6 | b | 30 | F |
61+-----+---------------+-----+--------+
626 rows in set (0.001 sec)
63
64MariaDB [hellodb]> rollback to a;
65Query OK, 0 rows affected (0.000 sec)
66
67MariaDB [hellodb]> select *from teachers;
68+-----+---------------+-----+--------+
69| TID | Name | Age | Gender |
70+-----+---------------+-----+--------+
71| 1 | Song Jiang | 45 | M |
72| 2 | Zhang Sanfeng | 94 | M |
73| 3 | Miejue Shitai | 77 | F |
74| 4 | Lin Chaoying | 93 | F |
75| 5 | a | 20 | M |
76+-----+---------------+-----+--------+
775 rows in set (0.001 sec)
78MariaDB [hellodb]> rollback;
79Query OK, 0 rows affected (0.001 sec)
80
81MariaDB [hellodb]> select *from teachers;
82+-----+---------------+-----+--------+
83| TID | Name | Age | Gender |
84+-----+---------------+-----+--------+
85| 1 | Song Jiang | 45 | M |
86| 2 | Zhang Sanfeng | 94 | M |
87| 3 | Miejue Shitai | 77 | F |
88| 4 | Lin Chaoying | 93 | F |
89+-----+---------------+-----+--------+
904 rows in set (0.000 sec)
91
92
93#不能反撤销:
94MariaDB [hellodb]> rollback to c;
95ERROR 1305 (42000): SAVEPOINT c does not exist
范例:查看事务
1MariaDB [hellodb]> begin;
2Query OK, 0 rows affected (0.000 sec)
3
4MariaDB [hellodb]> SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;
5Empty set (0.000 sec)
6
7MariaDB [hellodb]> select *from teachers;
8+-----+---------------+-----+--------+
9| TID | Name | Age | Gender |
10+-----+---------------+-----+--------+
11| 1 | Song Jiang | 45 | M |
12| 2 | Zhang Sanfeng | 94 | M |
13| 3 | Miejue Shitai | 77 | F |
14| 4 | Lin Chaoying | 93 | F |
15+-----+---------------+-----+--------+
164 rows in set (0.000 sec)
17
18MariaDB [hellodb]> SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;
19+-----------------+-----------+---------------------+-----------------------+------------------+------------+---------------------+---------------------------------------------+---------------------+-------------------+-------------------+------------------+-----------------------+-----------------+-------------------+-------------------------+---------------------+-------------------+------------------------+----------------------------+------------------+----------------------------+
20| trx_id | trx_state | trx_started | trx_requested_lock_id | trx_wait_started | trx_weight | trx_mysql_thread_id | trx_query | trx_operation_state | trx_tables_in_use | trx_tables_locked | trx_lock_structs | trx_lock_memory_bytes | trx_rows_locked | trx_rows_modified | trx_concurrency_tickets | trx_isolation_level | trx_unique_checks | trx_foreign_key_checks | trx_last_foreign_key_error | trx_is_read_only | trx_autocommit_non_locking |
21+-----------------+-----------+---------------------+-----------------------+------------------+------------+---------------------+---------------------------------------------+---------------------+-------------------+-------------------+------------------+-----------------------+-----------------+-------------------+-------------------------+---------------------+-------------------+------------------------+----------------------------+------------------+----------------------------+
22| 421262868086992 | RUNNING | 2024-05-31 06:15:02 | NULL | NULL | 0 | 162 | SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX | | 0 | 0 | 0 | 1128 | 0 | 0 | 0 | REPEATABLE READ | 1 | 1 | NULL | 0 | 0 |
23+-----------------+-----------+---------------------+-----------------------+------------------+------------+---------------------+---------------------------------------------+---------------------+-------------------+-------------------+------------------+-----------------------+-----------------+-------------------+-------------------------+---------------------+-------------------+------------------------+----------------------------+------------------+----------------------------+
241 row in set (0.000 sec)
25
26
27MariaDB [hellodb]> SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX\G
28*************************** 1. row ***************************
29 trx_id: 421262868086992
30 trx_state: RUNNING
31 trx_started: 2024-05-31 06:15:02
32 trx_requested_lock_id: NULL
33 trx_wait_started: NULL
34 trx_weight: 0
35 trx_mysql_thread_id: 162
36 trx_query: SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX
37 trx_operation_state:
38 trx_tables_in_use: 0
39 trx_tables_locked: 0
40 trx_lock_structs: 0
41 trx_lock_memory_bytes: 1128
42 trx_rows_locked: 0
43 trx_rows_modified: 0
44 trx_concurrency_tickets: 0
45 trx_isolation_level: REPEATABLE READ
46 trx_unique_checks: 1
47 trx_foreign_key_checks: 1
48trx_last_foreign_key_error: NULL
49 trx_is_read_only: 0
50trx_autocommit_non_locking: 0
511 row in set (0.000 sec)
52
53
54MariaDB [hellodb]> update teachers set age=50 where tid=4;
55Query OK, 1 row affected (0.001 sec)
56Rows matched: 1 Changed: 1 Warnings: 0
57
58MariaDB [hellodb]> SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX\G
59*************************** 1. row ***************************
60 trx_id: 936
61 trx_state: RUNNING
62 trx_started: 2024-05-31 06:15:02
63 trx_requested_lock_id: NULL
64 trx_wait_started: NULL
65 trx_weight: 3
66 trx_mysql_thread_id: 162
67 trx_query: SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX
68 trx_operation_state:
69 trx_tables_in_use: 0
70 trx_tables_locked: 1
71 trx_lock_structs: 2
72 trx_lock_memory_bytes: 1128
73 trx_rows_locked: 1
74 trx_rows_modified: 1
75 trx_concurrency_tickets: 0
76 trx_isolation_level: REPEATABLE READ
77 trx_unique_checks: 1
78 trx_foreign_key_checks: 1
79trx_last_foreign_key_error: NULL
80 trx_is_read_only: 0
81trx_autocommit_non_locking: 0
821 row in set (0.000 sec)
83
84
85#再另开一个窗口,更改同一行数据,观察是否能修改成功?
86MariaDB [hellodb]> select *from teachers;
87+-----+---------------+-----+--------+
88| TID | Name | Age | Gender |
89+-----+---------------+-----+--------+
90| 1 | Song Jiang | 45 | M |
91| 2 | Zhang Sanfeng | 94 | M |
92| 3 | Miejue Shitai | 77 | F |
93| 4 | Lin Chaoying | 93 | F |
94+-----+---------------+-----+--------+
954 rows in set (0.000 sec)
96
97MariaDB [hellodb]> update teachers set gender='M' where tid=4;
98……#卡顿,无法更改
99#是因为innodb加了行级锁,导致另一个用户就无法修改这行的数据
100
101
102
103MariaDB [hellodb]> SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
104+------------+-------------+-----------+-----------+----------------------+------------+------------+-----------+----------+-----------+
105| lock_id | lock_trx_id | lock_mode | lock_type | lock_table | lock_index | lock_space | lock_page | lock_rec | lock_data |
106+------------+-------------+-----------+-----------+----------------------+------------+------------+-----------+----------+-----------+
107| 937:15:3:5 | 937 | X | RECORD | `hellodb`.`teachers` | PRIMARY | 15 | 3 | 5 | 4 |
108| 936:15:3:5 | 936 | X | RECORD | `hellodb`.`teachers` | PRIMARY | 15 | 3 | 5 | 4 |
109+------------+-------------+-----------+-----------+----------------------+------------+------------+-----------+----------+-----------+
1102 rows in set (0.001 sec)
111
112
113MariaDB [hellodb]> SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX\G
114*************************** 1. row ***************************
115 trx_id: 937
116 trx_state: LOCK WAIT
117 trx_started: 2024-05-31 06:22:49
118 trx_requested_lock_id: 937:15:3:5
119 trx_wait_started: 2024-05-31 06:25:41
120 trx_weight: 2
121 trx_mysql_thread_id: 163 #线程id
122 trx_query: update teachers set gender='M' where tid=4
123 trx_operation_state: starting index read
124 trx_tables_in_use: 1
125 trx_tables_locked: 1
126 trx_lock_structs: 2
127 trx_lock_memory_bytes: 1128
128 trx_rows_locked: 2
129 trx_rows_modified: 0
130 trx_concurrency_tickets: 0
131 trx_isolation_level: REPEATABLE READ
132 trx_unique_checks: 1
133 trx_foreign_key_checks: 1
134trx_last_foreign_key_error: NULL
135 trx_is_read_only: 0
136trx_autocommit_non_locking: 0
137*************************** 2. row ***************************
138 trx_id: 936
139 trx_state: RUNNING
140 trx_started: 2024-05-31 06:15:02
141 trx_requested_lock_id: NULL
142 trx_wait_started: NULL
143 trx_weight: 3
144 trx_mysql_thread_id: 162 #线程id
145 trx_query: SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX
146 trx_operation_state:
147 trx_tables_in_use: 0
148 trx_tables_locked: 1
149 trx_lock_structs: 2
150 trx_lock_memory_bytes: 1128
151 trx_rows_locked: 1
152 trx_rows_modified: 1
153 trx_concurrency_tickets: 0
154 trx_isolation_level: REPEATABLE READ
155 trx_unique_checks: 1
156 trx_foreign_key_checks: 1
157trx_last_foreign_key_error: NULL
158 trx_is_read_only: 0
159trx_autocommit_non_locking: 0
1602 rows in set (0.001 sec)
161
162
163#超时,回滚(50s的超时时长)
164MariaDB [hellodb]> update teachers set gender='M' where tid=4;
165ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
166
167
168#查看当前等锁的事务
169MariaDB [hellodb]> SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
170+-------------------+-------------------+-----------------+------------------+
171| requesting_trx_id | requested_lock_id | blocking_trx_id | blocking_lock_id |
172+-------------------+-------------------+-----------------+------------------+
173| 937 | 937:15:3:5 | 936 | 936:15:3:5 |
174+-------------------+-------------------+-----------------+------------------+
1751 row in set (0.000 sec)
176
177
178MariaDB [hellodb]> show processlist;
179+-----+------+-----------+---------+---------+------+----------+--------------------------------------------+----------+
180| Id | User | Host | db | Command | Time | State | Info | Progress |
181+-----+------+-----------+---------+---------+------+----------+--------------------------------------------+----------+
182| 162 | root | localhost | hellodb | Sleep | 44 | | NULL | 0.000 |
183| 163 | root | localhost | hellodb | Query | 48 | Updating | update teachers set gender='M' where tid=4 | 0.000 |
184| 164 | root | localhost | hellodb | Query | 0 | starting | show processlist | 0.000 |
185+-----+------+-----------+---------+---------+------+----------+--------------------------------------------+----------+
1863 rows in set (0.000 sec)
范例:找到未完成的导致阻塞的事务
1#在第一会话中执行
2MariaDB [hellodb]> begin;
3Query OK, 0 rows affected (0.000 sec)
4MariaDB [hellodb]> update students set classid=10;
5
6#在第二个会话中执行
7MariaDB [hellodb]> update students set classid=20;
8
9
10#在第三个会话中执行
11MariaDB [hellodb]> show engine innodb status;
12...省略...
13---TRANSACTION 120, ACTIVE 673 sec
142 lock struct(s), heap size 1136, 28 row lock(s), undo log entries 27
15MySQL thread id 13, OS thread handle 139719808595712, query id 206 localhost
16root
17
18...省略...
19MariaDB [hellodb]> SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
20+-----------+-------------+-----------+-----------+----------------------+------
21------+------------+-----------+----------+-----------+
22| lock_id | lock_trx_id | lock_mode | lock_type | lock_table |
23lock_index | lock_space | lock_page | lock_rec | lock_data |
24+-----------+-------------+-----------+-----------+----------------------+------
25------+------------+-----------+----------+-----------+
26| 123:9:3:2 | 123 | X | RECORD | `hellodb`.`students` |
27PRIMARY | 9 | 3 | 2 | 1 |
28| 120:9:3:2 | 120 | X | RECORD | `hellodb`.`students` |
29PRIMARY | 9 | 3 | 2 | 1 |
30+-----------+-------------+-----------+-----------+----------------------+------
31------+------------+-----------+----------+-----------+
322 rows in set (0.001 sec)
33MariaDB [hellodb]> SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
34+-------------------+-------------------+-----------------+------------------+
35| requesting_trx_id | requested_lock_id | blocking_trx_id | blocking_lock_id |
36+-------------------+-------------------+-----------------+------------------+
37| 123 | 123:9:3:2 | 120 | 120:9:3:2 |
38+-------------------+-------------------+-----------------+------------------+
391 row in set (0.000 sec)
40
41#查看正在进行的事务
42MariaDB [hellodb]> SELECT * FROM information_schema.INNODB_TRX\G
43*************************** 1. row ***************************
44 trx_id: 123
45 trx_state: LOCK WAIT
46 trx_started: 2019-11-22 19:17:06
47 trx_requested_lock_id: 123:9:3:2
48 trx_wait_started: 2019-11-22 19:18:50
49 trx_weight: 2
50 trx_mysql_thread_id: 15 #线程ID
51 trx_query: update students set classid=20
52 trx_operation_state: starting index read
53 trx_tables_in_use: 1
54 trx_tables_locked: 1
55 trx_lock_structs: 2
56 trx_lock_memory_bytes: 1136
57 trx_rows_locked: 2
58 trx_rows_modified: 0
59 trx_concurrency_tickets: 0
60 trx_isolation_level: REPEATABLE READ
61 trx_unique_checks: 1
62 trx_foreign_key_checks: 1
63trx_last_foreign_key_error: NULL
64 trx_is_read_only: 0
65trx_autocommit_non_locking: 0
66*************************** 2. row ***************************
67 trx_id: 120
68 trx_state: RUNNING
69 trx_started: 2019-11-22 19:08:51
70 trx_requested_lock_id: NULL
71 trx_wait_started: NULL
72 trx_weight: 29
73 trx_mysql_thread_id: 13 #线程ID
74 trx_query: NULL
75 trx_operation_state: NULL
76 trx_tables_in_use: 0
77 trx_tables_locked: 1
78 trx_lock_structs: 2
79 trx_lock_memory_bytes: 1136
80 trx_rows_locked: 28
81 trx_rows_modified: 27
82 trx_concurrency_tickets: 0
83 trx_isolation_level: REPEATABLE READ
84 trx_unique_checks: 1
85 trx_foreign_key_checks: 1
86trx_last_foreign_key_error: NULL
87 trx_is_read_only: 0
88trx_autocommit_non_locking: 0
892 rows in set (0.000 sec)
90
91
92MariaDB [hellodb]> show processlist;
93
94+----+-------------+-----------+---------+---------+------+---------------------
95-----+------------------+----------+
96| Id | User | Host | db | Command | Time | State
97 | Info | Progress |
98+----+-------------+-----------+---------+---------+------+---------------------
99-----+------------------+----------+
100| 1 | system user | | NULL | Daemon | NULL | InnoDB purge
101coordinator | NULL | 0.000 |
102| 3 | system user | | NULL | Daemon | NULL | InnoDB purge worker
103 | NULL | 0.000 |
104| 4 | system user | | NULL | Daemon | NULL | InnoDB purge worker
105 | NULL | 0.000 |
106| 2 | system user | | NULL | Daemon | NULL | InnoDB purge worker
107 | NULL | 0.000 |
108| 5 | system user | | NULL | Daemon | NULL | InnoDB shutdown
109handler | NULL | 0.000 |
110| 11 | root | localhost | hellodb | Query | 0 | Init
111 | show processlist | 0.000 |
112| 13 | root | localhost | hellodb | Sleep | 38 |
113 | NULL | 0.000 |
114+----+-------------+-----------+---------+---------+------+---------------------
115-----+------------------+----------+
1167 rows in set (0.000 sec)
117
118
119#杀掉未完成的事务
120MariaDB [hellodb]> kill 13;
121Query OK, 0 rows affected (0.000 sec)
122#查看事务锁的超时时长,默认50s
123MariaDB [hellodb]> show global variables like 'innodb_lock_wait_timeout';
124+--------------------------+-------+
125| Variable_name | Value |
126+--------------------------+-------+
127| innodb_lock_wait_timeout | 50 |
128+--------------------------+-------+
1291 row in set (0.001 sec)
事务隔离级别
面试重点。
MySQL 支持四种隔离级别,事务隔离级别:从上至下更加严格

- READ UNCOMMITTED
可读取到未提交数据,产生脏读
- READ COMMITTED
可读取到提交数据,但未提交数据不可读,产生不可重复读,即可读取到多个提交数据,导致每次读取数据不一致
- REPEATABLE READ
可重复读,多次读取数据都一致,产生幻读,即读取过程中,即使有其它提交的事务修改数据,仍只能读取到未修改前的旧数据。此为MySQL默认设置
- SERIALIZABLE
可串行化,未提交的读事务阻塞修改事务(加读锁,但不阻塞读事务),或者未提交的修改事务阻塞读事务(加写锁,其它事务的读,写都不可以执行)。会导致并发性能差。
MVCC和事务的隔离级别:
MVCC(多版本并发控制机制)只在REPEATABLE READ和READ COMMITTED两个隔离级别下工作。其他两个隔离级别都和MVCC不兼容,因为READ UNCOMMITTED总是读取最新的数据行,而不是符合当前事务版本的数据行。而SERIALIZABLE则会对所有读取的行都加锁。
指定事务隔离级别:
服务器变量tx_isolation指定,默认为REPEATABLE-READ,可在GLOBAL和SESSION级进行设置
1SET tx_isolation='READ-UNCOMMITTED|READ-COMMITTED|REPEATABLE-READ|SERIALIZABLE'服务器选项中指定
1vim /etc/my.cnf 2[mysqld] 3transaction-isolation=SERIALIZABLE
死锁:
两个或多个事务在同一资源相互占用,并请求锁定对方占用的资源的状态。
死锁问题,数据库会自动解决。
日志管理
MySQL 支持丰富的日志类型,如下:
事务日志:transaction log
事务日志的写入类型为“追加”,因此其操作为“顺序IO”;通常也被称为:预写式日志 write ahead logging
事务日志文件: ib_logfile0, ib_logfile1
错误日志 error log
通用日志 general log
慢查询日志 slow query log
二进制日志 binary log
中继日志 reley log,在主从复制架构中,从服务器用于保存从主服务器的二进制日志中读取的事
事务日志
事务日志:transaction log
事务型存储引擎自行管理和使用,建议和数据文件分开存放,redo log和undo log
Innodb事务日志相关配置:
show variables like '%innodb_log%';
1MariaDB [hellodb]> show variables like '%innodb_log%';
2+-----------------------------+-----------+
3| Variable_name | Value |
4+-----------------------------+-----------+
5| innodb_log_buffer_size | 16777216 |
6| innodb_log_checksums | ON |
7| innodb_log_compressed_pages | ON |
8| innodb_log_file_size | 100663296 |
9| innodb_log_files_in_group | 1 |
10| innodb_log_group_home_dir | ./ |
11| innodb_log_optimize_ddl | OFF |
12| innodb_log_write_ahead_size | 8192 |
13+-----------------------------+-----------+
148 rows in set (0.001 sec)
说明:
1innodb_log_file_size 50331648 #每个日志文件大小 #50M
2innodb_log_files_in_group 2 #日志组成员个数
3innodb_log_group_home_dir ./ #事务文件路径
4innodb_flush_log_at_trx_commit #默认为1(尤其这个值)
配置文件里修改事务日志选项:(修改成功)
1[root@test ~]# mkdir -p /data/trans_log
2[root@test ~]# chown mysql.mysql /data/trans_log/
3
4
5# vim /etc/my.cnf.d/server.cnf
6[mysqld]
7……
8innodb_log_group_home_dir=/data/trans_log
9innodb_log_files_in_group=3
10innodb_log_file_size=200M
11
12
13[root@test ~]# systemctl restart mariadb

事务日志性能优化:
1innodb_flush_log_at_trx_commit=0|1|2

1 此为默认值,日志缓冲区将写入日志文件,并在每次事务后执行刷新到磁盘。 这是完全遵守ACID特性
0 提交时没有写磁盘的操作; 而是每秒执行一次将日志缓冲区的提交的事务写入刷新到磁盘。 这样可提供更好的性能,但服务器崩溃可能丢失最后一秒的事务
2 每次提交后都会写入OS的缓冲区,但每秒才会进行一次刷新到磁盘文件中。 性能比0略差一些,但操作系统或停电可能导致最后一秒的交易丢失
高并发业务行业最佳实践,是使用第三种折衷配置(=2):
1.配置为2和配置为0,性能差异并不大,因为将数据从Log Buffer拷贝到OS cache,虽然跨越用户态与内核态,但毕竟只是内存的数据拷贝,速度很快
2.配置为2和配置为0,安全性差异巨大,操作系统崩溃的概率相比MySQL应用程序崩溃的概率,小很多,设置为2,只要操作系统不奔溃,也绝对不会丢数据
说明:
设置为1,同时sync_binlog = 1表示最高级别的容错
innodb_use_global_flush_log_at_trx_commit=0 时,将不能用SET语句重置此变量( MariaDB 10.2.6 后废弃)
错误日志
错误日志
mysqld启动和关闭过程中输出的事件信息
mysqld运行中产生的错误信息
event scheduler运行一个event时产生的日志信息
在主从复制架构中的从服务器上启动从服务器线程时产生的信息
错误文件路径
1SHOW GLOBAL VARIABLES LIKE 'log_error';
范例:
1MariaDB [hellodb]> SHOW GLOBAL VARIABLES LIKE 'log_error';
2+---------------+------------------------------+
3| Variable_name | Value |
4+---------------+------------------------------+
5| log_error | /var/log/mariadb/mariadb.log |
6+---------------+------------------------------+
71 row in set (0.001 sec)

记录哪些警告信息至错误日志文件
1#CentOS7 mariadb 5.5 默认值为1
2#CentOS8 mariadb 10.3 默认值为2
3log_warnings=0|1|2|3...
范例:
1MariaDB [hellodb]> SHOW GLOBAL VARIABLES LIKE 'log_warnings';
2+---------------+-------+
3| Variable_name | Value |
4+---------------+-------+
5| log_warnings | 2 |
6+---------------+-------+
71 row in set (0.001 sec)

通用日志
通用日志:记录对数据库的通用操作,包括:错误的SQL语句
通用日志可以保存在:file(默认值)或 table(mysql.general_log表)
通用日志相关设置
1general_log=ON|OFF
2general_log_file=HOSTNAME.log
3
4log_output=TABLE|FILE|NONE
范例:
1#修改通用日志,记录通用日志至mysql.general_log表中
2MariaDB [mysql]> set global log_output="table";
3MariaDB [mysql]> SHOW GLOBAL VARIABLES LIKE 'log_output';
4+---------------+-------+
5| Variable_name | Value |
6+---------------+-------+
7| log_output | TABLE |
8+---------------+-------+
91 row in set (0.002 sec)
10MariaDB [mysql]> select * from mysql.general_log\G
11...省略...
12*************************** 6. row ***************************
13 event_time: 2019-11-25 11:03:41.163896
14 user_host: root[root] @ localhost []
15 thread_id: 9
16 server_id: 1
17command_type: Query
18 argument: xxx
19*************************** 7. row ***************************
20 event_time: 2019-11-25 11:03:44.549211
21 user_host: root[root] @ localhost []
22 thread_id: 8
23 server_id: 1
24command_type: Query
25 argument: select * from general_log
267 rows in set (0.000 sec)
范例:对访问的语句进行排序
1[root@centos8 ~]#mysql -e 'select argument from mysql.general_log' | awk
2'{sql[$0]++}END{for(i in sql){print sql[i],i}}'|sort -nr
3
4[root@centos8 ~]#mysql -e 'select argument from mysql.general_log' |sort |uniq -
5c |sort -nr



慢查询日志
慢查询日志:记录执行查询时长超出指定时长的操作
慢查询相关变量
1slow_query_log=ON|OFF #开启或关闭慢查询,支持全局和会话,只有全局设置才会生成慢查询文件
2long_query_time=N #慢查询的阀值,单位秒(默认是10s)
3slow_query_log_file=HOSTNAME-slow.log #慢查询日志文件
4
5
6log_slow_filter = admin,filesort,filesort_on_disk,full_join,full_scan,
7query_cache,query_cache_miss,tmp_table,tmp_table_on_disk
8#上述查询类型且查询时长超过long_query_time,则记录日志
9
10log_queries_not_using_indexes=ON #不使用索引或使用全索引扫描,不论是否达到慢查询阀值的语句是否记录日志,默认OFF,即不记录
11log_slow_rate_limit = 1 #多少次查询才记录,mariadb特有
12log_slow_verbosity= Query_plan,explain #记录内容
13log_slow_queries = OFF #同slow_query_log,MariaDB 10.0/MySQL 5.6.1 版后已删除
范例:模拟慢查询情况
这个事务得30-40s:


范例:模拟慢查询情况
1s查询1行。


范例:未使用索引,慢查询记录
1log_queries_not_using_indexes=ON #不使用索引或使用全索引扫描,不论是否达到慢查询阀值的语句是否记录日志,默认OFF,即不记录

创建索引:

再次查询:

可以看到,本次未触发慢日志功能:

慢查询分析工具
1mysqldumpslow -s c -t 10 /data/mysql/slow.log
使用profile工具
1#打开后,会显示语句执行详细的过程
2set profiling = ON
3#查看语句,注意结果中的query_id值
4show profiles ;
5MariaDB [hellodb]> show profiles ;
6+----------+------------+-------------------------------------+
7| Query_ID | Duration | Query |
8+----------+------------+-------------------------------------+
9| 1 | 0.00019238 | select @@profiling |
10| 2 | 0.00115590 | select * from students where age=20 |
11| 3 | 0.00006616 | show profiles for query 2 |
12| 4 | 4.00319568 | select sleep(1) from teachers |
13+----------+------------+-------------------------------------+
144 rows in set (0.000 sec)
15#显示语句的详细执行步骤和时长
16Show profile for query #
17MariaDB [hellodb]> show profile for query 4;
18+------------------------+----------+
19| Status | Duration |
20+------------------------+----------+
21| Starting | 0.000157 |
22| Checking permissions | 0.000009 |
23| Opening tables | 0.000025 |
24| After opening tables | 0.000005 |
25| System lock | 0.000004 |
26| Table lock | 0.000006 |
27| Init | 0.000017 |
28| Optimizing | 0.000009 |
29| Statistics | 0.000018 |
30| Preparing | 0.000028 |
31| Executing | 0.000003 |
32| Sending data | 0.000070 |
33| User sleep | 1.001128 |
34| User sleep | 1.000313 |
35| User sleep | 1.000834 |
36| User sleep | 1.000348 |
37| End of update loop | 0.000032 |
38| Query end | 0.000003 |
39| Commit | 0.000014 |
40| Closing tables | 0.000004 |
41| Unlocking tables | 0.000003 |
42| Closing tables | 0.000012 |
43| Starting cleanup | 0.000003 |
44| Freeing items | 0.000056 |
45| Updating status | 0.000024 |
46| Logging slow query | 0.000069 |
47| Reset for next command | 0.000004 |
48+------------------------+----------+
4927 rows in set (0.000 sec)
50
51
52
53MariaDB [hellodb]>
54#显示cpu使用情况
55Show profile cpu for query #
56MariaDB [hellodb]> Show profile cpu for query 4;
57+------------------------+----------+----------+------------+
58| Status | Duration | CPU_user | CPU_system |
59+------------------------+----------+----------+------------+
60| Starting | 0.000157 | 0.000090 | 0.000065 |
61| Checking permissions | 0.000009 | 0.000005 | 0.000004 |
62| Opening tables | 0.000025 | 0.000014 | 0.000010 |
63| After opening tables | 0.000005 | 0.000003 | 0.000002 |
64| System lock | 0.000004 | 0.000002 | 0.000002 |
65| Table lock | 0.000006 | 0.000004 | 0.000002 |
66| Init | 0.000017 | 0.000010 | 0.000007 |
67| Optimizing | 0.000009 | 0.000005 | 0.000004 |
68| Statistics | 0.000018 | 0.000010 | 0.000007 |
69| Preparing | 0.000028 | 0.000016 | 0.000012 |
70| Executing | 0.000003 | 0.000002 | 0.000002 |
71| Sending data | 0.000070 | 0.000059 | 0.000000 |
72| User sleep | 1.001128 | 0.000665 | 0.000000 |
73| User sleep | 1.000313 | 0.000716 | 0.000000 |
74| User sleep | 1.000834 | 0.000379 | 0.000100 |
75| User sleep | 1.000348 | 0.000319 | 0.000231 |
76| End of update loop | 0.000032 | 0.000017 | 0.000012 |
77| Query end | 0.000003 | 0.000002 | 0.000002 |
78| Commit | 0.000014 | 0.000008 | 0.000005 |
79| Closing tables | 0.000004 | 0.000002 | 0.000002 |
80| Unlocking tables | 0.000003 | 0.000002 | 0.000001 |
81| Closing tables | 0.000012 | 0.000007 | 0.000005 |
82| Starting cleanup | 0.000003 | 0.000001 | 0.000001 |
83| Freeing items | 0.000056 | 0.000034 | 0.000024 |
84| Updating status | 0.000024 | 0.000013 | 0.000010 |
85| Logging slow query | 0.000069 | 0.000040 | 0.000029 |
86| Reset for next command | 0.000004 | 0.000002 | 0.000001 |
87+------------------------+----------+----------+------------+
8827 rows in set (0.000 sec)
89MariaDB [hellodb]>
二进制日志(备份)(很重要)
二进制日志默认不启用的;😉
在工作中肯定是要启用二进制日志的。(增删改操作都会记录到)
- 记录导致数据改变或潜在导致数据改变的SQL语句
- 记录已提交的日志
- 不依赖于存储引擎类型
功能:通过“重放”日志文件中的事件来生成数据副本
注意:建议二进制日志和数据文件分开存放
二进制日志记录三种格式
- 基于“语句”记录:statement,记录语句,默认模式( MariaDB 10.2.3 版本以下 ),日志量较少
- 基于“行”记录:row,记录数据,日志量较大,更加安全,建议使用的格式
- 混合模式:mixed, 让系统自行判定该基于哪种方式进行,默认模式( MariaDB 10.2.4及版本以上)
格式配置
1MariaDB [hellodb]> show variables like 'binlog_format';
2+---------------+-------+
3| Variable_name | Value |
4+---------------+-------+
5| binlog_format | MIXED |
6+---------------+-------+
71 row in set (0.001 sec)
8
9
10
11#MySQL 8.0 默认使用ROW方式
12mysql> show variables like 'binlog_format';
13+---------------+-------+
14| Variable_name | Value |
15+---------------+-------+
16| binlog_format | ROW |
17+---------------+-------+
181 row in set (0.07 sec)
二进制日志文件的构成
1有两类文件
21.日志文件:mysql|mariadb-bin.文件名后缀,二进制格式,如: mariadb-bin.000001
32.索引文件:mysql|mariadb-bin.index,文本格式
二进制日志相关的服务器变量:
1sql_log_bin=ON|OFF:#是否记录二进制日志,默认ON,支持动态修改,系统变量,而非服务器选项(是一个sesson变量)
2log_bin=/PATH/BIN_LOG_FILE:#指定文件位置;默认OFF,表示不启用二进制日志功能,上述两项都开启才可以
3
4
5binlog_format=STATEMENT|ROW|MIXED:#二进制日志记录的格式,默认STATEMENT
6max_binlog_size=1073741824:#单个二进制日志文件的最大体积,到达最大值会自动滚动,默认为1G
7#说明:文件达到上限时的大小未必为指定的精确值
8#事务日志:默认是2个
9
10binlog_cache_size=4m #此变量确定在每次事务中保存二进制日志更改记录的缓存的大小(每次连接)
11max_binlog_cache_size=512m #限制用于缓存多事务查询的字节大小。
12
13sync_binlog=1|0:#设定是否启动二进制日志即时同步磁盘功能,默认0,由操作系统负责同步日志到磁盘
14expire_logs_days=N:#二进制日志可以自动删除的天数。 默认为0,即不自动删除
范例:


二进制日志相关配置
查看mariadb自行管理使用中的二进制日志文件列表,及大小
1SHOW {BINARY | MASTER} LOGS

查看使用中的二进制日志文件
1SHOW MASTER STATUS

在线查看二进制文件中的指定内容
1SHOW BINLOG EVENTS [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count]
范例:
1show binlog events in 'mysql-bin.000001' from 6516 limit 2,3

案例:
1mysqlbinlog /backup/newlogbin/mysql-bin.000002 ##默认查看所有内容

清除指定二进制日志
1PURGE { BINARY | MASTER } LOGS { TO 'log_name' | BEFORE datetime_expr }
范例:
1PURGE BINARY LOGS TO 'mariadb-bin.000003'; #删除mariadb-bin.000003之前的日志
2PURGE BINARY LOGS BEFORE '2017-01-23';
3PURGE BINARY LOGS BEFORE '2017-03-22 09:25:30';
删除所有二进制日志,index文件重新记数
1RESET MASTER [TO #]; #删除所有二进制日志文件,并重新生成日志文件,文件名从#开始记数,默认从
21开始,一般是master主机第一次启动时执行,MariaDB 10.1.6开始支持TO #
刷新二进制日志文件的方法:
方法1:重启服务,可以生成一个新的二进制日志文件
方法2:切换日志文件:
1FLUSH LOGS;

方法3:
1mysqladmin flush-logs

5、备份和恢复
5.1 备份恢复概述

5.1.1 为什么要备份
灾难恢复:硬件故障、软件故障、自然灾害、黑客攻击、误操作测试等数据丢失场景。
5.1.2 备份类型
完全备份,部分备份
完全备份:整个数据集
部分备份:只备份数据子集,如部分库或表
- 完全备份、增量备份、差异备份
增量备份:仅备份最近一次完全备份或增量备份(如果存在增量)以来变化的数据,备份较快,还原复杂。

差异备份:仅备份最近一次完全备份以来变化的数据,备份较慢,还原简单

注意:二进制日志文件不应该与数据文件放在同一磁盘。
- 冷、温、热备份
冷备:读、写操作均不可进行,数据库停止服务 (适合传统业务)
温备:读操作可执行;但写操作不可执行
热备:读、写操作均可执行
MyISAM:温备,不支持热备
InnoDB:都支持
事务具有隔离性。(可重复读)
- 物理和逻辑备份
物理备份:直接复制数据文件进行备份,与存储引擎有关,占用较多的空间,速度快
逻辑备份:从数据库中“导出”数据另存而进行的备份,与存储引擎无关,占用空间少,速度慢,可能丢失精度
5.1.3 备份什么
- 数据
- 二进制日志、InnoDB的事务日志
- 用户帐号,权限设置,程序代码(存储过程、函数、触发器、事件调度器)
- 服务器的配置文件
这2个数据库是没必要备份的:(用来描述数据库状态的)
1information_schema
2performance_schema

5.1.4 备份注意要点
- 能容忍最多丢失多少数据
- 备份产生的负载
- 备份过程的时长
- 温备的持锁多久
- 恢复数据需要在多长时间内完成
- 需要备份和恢复哪些数据
5.1.5 还原要点
- 做还原测试,用于测试备份的可用性
- 还原演练,写成规范的技术文档
5.1.6 备份工具
cp, tar等复制归档工具:物理备份工具,适用所有存储引擎;只支持冷备;完全和部分备份
LVM的快照:先加读锁,做快照后解锁,几乎热备;借助文件系统工具进行备份;–(工作里用的极少)
mysqldump:逻辑备份工具,适用所有存储引擎,对MyISAM存储引擎进行温备;支持完全或部分备份;对InnoDB存储引擎支持热备,结合binlog的增量备份。
xtrabackup:由Percona提供支持对InnoDB做热备(物理备份)的工具,支持完全备份、增量备份–(大型公司可能会用到)
MariaDB Backup: 从MariaDB 10.1.26开始集成,基于Percona XtraBackup 2.3.8实现
mysqlbackup:热备份, MySQL Enterprise Edition组件
mysqlhotcopy:PERL 语言实现,几乎冷备,仅适用于MyISAM存储引擎,使用LOCK TABLES、FLUSH TABLES和cp或scp来快速备份数据库–(用的少)
5.1.6 基于 LVM 的快照备份
前提:你的数据库要存放在lvm里。
1(1) 请求锁定所有表
2mysql> FLUSH TABLES WITH READ LOCK; (这里不要关窗口哦)
3
4(2) 记录二进制日志文件及事件位置
5mysql> FLUSH LOGS;
6mysql> SHOW MASTER STATUS;
7mysql -e 'SHOW MASTER STATUS' > /PATH/TO/SOMEFILE
8
9(3) 创建快照
10lvcreate -L # -s -p r -n NAME /DEV/VG_NAME/LV_NAME
11
12(4) 释放锁
13mysql> UNLOCK TABLES;
14(5) 挂载快照卷,执行数据备份
15(6) 备份完成后,删除快照卷
16(7) 制定好策略,通过原卷备份二进制日志
5.1.7 实战案例:数据库冷备份和还原😉
老师课件文档:
1#在目标服务器(10.0.0.18)安装mariadb-server,不启动服务
2[root@centos8 ~]#dnf install mariadb-server
3
4
5#在源主机(10.0.0.8)执行
6[root@centos8 ~]# systemctl stop mariadb
7
8#复制相关文件
9[root@centos8 ~]# scp /etc/my.cnf.d/mariadb-server.cnf 10.0.0.18:/etc/my.cnf.d/
10[root@centos8 ~]# scp -r /var/lib/mysql/* 10.0.0.18:/var/lib/mysql/
11[root@centos8 ~]# scp -r /data/logbin/ 10.0.0.18:/data/ #10.0.0.18事先存在/data/目录
12
13#保留属性:可以用rsync
14[root@centos8 ~]#rsync -av /var/lib/mysql/ 10.0.0.18:/var/lib/mysql/
15
16
17#在目标主机(10.0.0.18)执行
18[root@centos8 ~]#chown -R mysql.mysql /var/lib/mysql/
19[root@centos8 ~]#chown -R mysql.mysql /data/logbin/
20[root@centos8 ~]#systemctl start mariadb
2024年9月21日测试成功
10.3.17-MariaDB MariaDB Server
centos8
自己测试过程:

1.当前mysql机器
10.3.17-MariaDB MariaDB Server
centos8
192.168.1.81
当前自己mysql机器:
安装mysql
1dnf install mariadb-server -y
2systemctl enable --now mariadb
3mysql

导入测试数据
当前是有一些数据的
我们导入一下正在使用的测试sql:
1mysql -uroot -p123456 < hellodb_innodb.sql

1[root@centos8 ~]# ll /var/lib/mysql/
2total 122912
3-rw-rw----. 1 mysql mysql 16384 Sep 21 17:14 aria_log.00000001
4-rw-rw----. 1 mysql mysql 52 Sep 21 17:14 aria_log_control
5drwx------. 2 mysql mysql 272 Sep 21 17:06 hellodb
6-rw-rw----. 1 mysql mysql 1318 Sep 21 17:14 ib_buffer_pool
7-rw-rw----. 1 mysql mysql 12582912 Sep 21 17:14 ibdata1
8-rw-rw----. 1 mysql mysql 50331648 Sep 21 17:21 ib_logfile0
9-rw-rw----. 1 mysql mysql 50331648 Sep 21 16:46 ib_logfile1
10-rw-rw----. 1 mysql mysql 12582912 Sep 21 17:21 ibtmp1
11-rw-rw----. 1 mysql mysql 0 Sep 21 16:46 multi-master.info
12drwx------. 2 mysql mysql 4096 Sep 21 16:46 mysql
13srwxrwxrwx. 1 mysql mysql 0 Sep 21 17:21 mysql.sock
14-rw-rw----. 1 mysql mysql 16 Sep 21 16:46 mysql_upgrade_info
15drwx------. 2 mysql mysql 20 Sep 21 16:46 performance_schema
启用下二进制日志
1mkdir -p /data/logbin/mysql-bin
2chown mysql.mysql /data/logbin/
3
4
5vim /etc/my.cnf.d/mariadb-server.cnf
6log-bin=/data/logbin/mysql-bin

重启mysql服务:
1systemctl restart mariadb
- 此时,出现了二进制日志文件了
1[root@centos8 ~]# ll /data/logbin/
2total 8
3-rw-rw----. 1 mysql mysql 328 Sep 21 17:21 mysql-bin.000001
4-rw-rw----. 1 mysql mysql 30 Sep 21 17:21 mysql-bin.index
2.准备一台备份机器
安装好mysql软件,但是不启动mysql服务,版本要和生产的机器版本保持一致。
10.3.17-MariaDB MariaDB Server
centos8
192.168.1.82
1dnf install mariadb-server -y
刚装好数据库后,其数据库目录是空的:(现在也不需要把他启动起来)
1[root@mysql_backup ~]# ll /var/lib/mysql/
2total 0
3[root@mysql_backup ~]#
- 创建个备份目录
1mkdir /backup
3.开始冷备份
- 停止数据库服务:
1systemctl stop mariadb
- 先把一些核心文件拷贝到远程机器
1rsync -av /var/lib/mysql 192.168.1.82:/backup #复制数据库:
2rsync -av /data/logbin 192.168.1.82:/backup #复制二进制文件:
3rsync -av /etc/my.cnf.d/mariadb-server.cnf 192.168.1.82:/backup #复制数据库配置文件:
到备份机器验证:
1[root@mysql_backup ~]# ll /backup/
2total 4
3drwxr-xr-x. 2 mysql mysql 76 Sep 21 21:47 logbin
4-rw-r--r--. 1 root root 1489 Sep 21 17:12 mariadb-server.cnf
5drwxr-xr-x. 5 mysql mysql 235 Sep 21 21:47 mysql
- 启动原生产服务器数据库服务
1[root@mysql ~]# systemctl start mariadb
2
3mysql -uroot -p123456 hellodb

- 这里做一些测试数据操作
1mysql -uroot -p123456 hellodb
2
3create database db1;
4show databases;
5
6#对数据再做一些修改吧
7#对teachers表添加2行数据:
8insert teachers (name,age,gender)values('mage',30,'M');
9insert teachers (name,age,gender)values('wang',33,'M');
10
11exit
- 现在模拟数据库的奔溃
1#删库了
2[root@mysql ~]# rm -rf /var/lib/mysql/*
3[root@mysql ~]# mysql -uroot -p
4Enter password:
5ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mysql/mysql.sock' (2)
6[root@mysql ~]#
4.模拟还原数据库
还原数据库
拿数据库的备份来还原:
把之前备份好的数据拷贝到它应该在的地方:
1[root@mysql_backup ~]# ls /backup/
2logbin mariadb-server.cnf mysql
开始拷贝:
1[root@mysql_backup ~]# cp -av /backup/mysql/* /var/lib/mysql/
2[root@mysql_backup ~]# cp /backup/mariadb-server.cnf /etc/my.cnf.d/
3cp: overwrite '/etc/my.cnf.d/mariadb-server.cnf'? y
4[root@mysql_backup ~]# cp -av /backup/logbin /data/ #注意,备份机器上必须已经存在/data目录哦
- 目前所有数据都齐全了

- 启动数据库服务
1[root@mysql_backup ~]# systemctl start mariadb
2[root@mysql_backup ~]# mysql -uroot -p123456
3Welcome to the MariaDB monitor. Commands end with ; or \g.
4Your MariaDB connection id is 9
5Server version: 10.3.17-MariaDB-log MariaDB Server
6
7Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
8
9Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
10
11MariaDB [(none)]> show databases;
12+--------------------+
13| Database |
14+--------------------+
15| hellodb |
16| information_schema |
17| mysql |
18| performance_schema |
19+--------------------+
204 rows in set (0.000 sec)
21
22MariaDB [(none)]> select *from hellodb.teachers;
23+-----+---------------+-----+--------+
24| TID | Name | Age | Gender |
25+-----+---------------+-----+--------+
26| 1 | Song Jiang | 45 | M |
27| 2 | Zhang Sanfeng | 94 | M |
28| 3 | Miejue Shitai | 77 | F |
29| 4 | Lin Chaoying | 93 | F |
30+-----+---------------+-----+--------+
314 rows in set (0.001 sec)
复合预期。
还原到了我们备份的那个状态。
但是我们不甘心:。。。
现在的数据不是最新的。。。
该怎么办??
期望能还原到数据库最新的状态?
回退到删库前的状态。
利用二进制日志。😎
利用二进制日志进行数据库的还原
- 数据库服务一启动,就会生成新的二进制文件:

002文件是自己数据库服务启动后生成的文件:(冷被后–到删库前的一些操作-重要)

备份机器:

002文件是自己数据库服务启动后生成的文件:

现在的情况是:
数据库服务器数据库所在磁盘坏了,但是二进制日志文件所在磁盘是ok的:
那么我们就可以把这个002文件给拷贝出来。
1[root@mysql ~]# rsync -av /data/logbin/ 192.168.1.82:/backup/newlogbin

现在的重点就是如何处理二进制日志文件mysql-bin.000002里面的东西?
利用它里面的数据进行还原的。
查看二进制日志文件mysql-bin.000002内容:
1mysqlbinlog /backup/newlogbin/mysql-bin.000002 #####默认查看所有内容

- 导出文件
1mysqlbinlog /backup/newlogbin/mysql-bin.000002 > logbin.sql
- 将导出的这个sql文件导入数据库即可
我们来临时关闭下二进制日志文件的记录:(没必要记录数据库恢复过程的二进制日志)
1mysql -uroot -p123456
2show variables like 'sql_log_bin';
3set sql_log_bin=0;
4show variables like 'sql_log_bin';
5
6
7#####此时一定不要退出来,然后进行导入,否则就白设置了哈哈
8system ls /root
9source /root/logbin.sql



- 打开二进制日志功能
1MariaDB [hellodb]> set sql_log_bin=1;
2Query OK, 0 rows affected (0.000 sec)
5.验证
- 验证下
1show databases;
2select * from teachers;

完美。😉(大功告成)
注意
- 备份的重要性
- 推荐使用rsync;(拷贝过来的权限是对的)
- 备份测试;(写一个备份还原测试脚本)
5.2 mysqldump备份工具
5.2.1 mysqldump 说明
逻辑备份工具:
mysqldump, mydumper, phpMyAdmin
Schema和数据存储在一起、巨大的SQL语句、单个巨大的备份文件
mysqldump:是MySQL的客户端命令,通过mysql协议连接至mysql服务器进行备份
安装数据库时默认已经安装好工具包:

命令格式:
1mysqldump [OPTIONS] database [tables] #支持指定数据库和指定多表的备份,但数据库本身定义不备份🤣
2mysqldump [OPTIONS] –B DB1 [DB2 DB3...] #支持指定数据库备份,包含数据库本身定义也会备份
3mysqldump [OPTIONS] –A [OPTIONS] #备份所有数据库,包含数据库本身定义也会备份
mysqldump参考:
https://dev.mysql.com/doc/refman/5.7/en/mysqldump.html
mysqldump 常见通用选项📢
1-A, --all-databases #备份所有数据库,含create database
2-B, --databases db_name… #指定备份的数据库,包括create database语句
3
4-E, --events:#备份相关的所有event scheduler
5-R, --routines:#备份所有存储过程和自定义函数
6--triggers:#备份表相关触发器,默认启用,用--skip-triggers,不备份触发器
7
8--default-character-set=utf8 #指定字符集,默认用utf-8
9
10--master-data[=#]: #此选项须启用二进制日志(重要)😉
11#1:所备份的数据之前加一条记录为CHANGE MASTER TO语句,非注释,不指定#,默认为1,适合于主从复制多机使用
12#2:记录为被注释的#CHANGE MASTER TO语句,适合于单机使用
13#此选项会自动关闭--lock-tables功能,自动打开-x | --lock-all-tables功能(除非开启--single-transaction)
14
15
16
17-F, --flush-logs #备份前滚动日志,锁定表完成后,执行flush logs命令,生成新的二进制日志文件,配合-A 或 -B 选项时,会导致刷新多次数据库。建议在同一时刻执行转储和日志刷新,可通过和--single-transaction或-x,--master-data 一起使用实现,此时只刷新一次二进制日志。
18--single-transaction 常用的必备选项,针对innodb的
19
20--compact #去掉注释,适合调试,生产不使用
21
22-d, --no-data #只备份表结构,不备份数据
23-t, --no-create-info #只备份数据,不备份表结构,即create table
24
25-n,--no-create-db #不备份create database,可被-A或-B覆盖
26--flush-privileges #备份mysql或相关时需要使用
27-f, --force #忽略SQL错误,继续执行
28--hex-blob #使用十六进制符号转储二进制列,当有包括BINARY, VARBINARY,BLOB,BIT的数据类型的列时使用,避免乱码
29-q, --quick #不缓存查询,直接输出,加快备份速度
常用备份命令:(推荐)
1#压缩
2mysqldump -A -F --single-transaction --master-data=1|gzip > /data/all-`date +%F`.sql.gz
3
4#不压缩
5mysqldump -A -F --single-transaction --master-data=1 > /data/all-`date +%F`.sql
-R选项
- 创建一个存储过程
1[root@mysql ~]# mysql hellodb < testlog.sql
2[root@mysql ~]# mysql hellodb
3MariaDB [hellodb]> help show
4MariaDB [hellodb]> SHOW PROCEDURE STATUS;

- 发现,是没有备份相关存储过程的
1[root@mysql ~]# mysqldump -B hellodb > /backup/hellodb_B.sql
2[root@mysql ~]# grep pro_testlog /backup/hellodb_B.sql
- 带上-R选项,再次备份,并验证
1[root@mysql ~]# mysqldump -R -B hellodb > /backup/hellodb_R_B.sql
2[root@mysql ~]# grep pro_testlog /backup/hellodb_R_B.sql
3/*!50003 DROP PROCEDURE IF EXISTS `pro_testlog` */;
4CREATE DEFINER=`root`@`localhost` PROCEDURE `pro_testlog`()
可以看到,此时备份的sql里是有相关存储过程的。
mysql数据库里面有没有存储过程呢?
是有的,因为存储过程本身就是默认存储在mysql数据库的。
1[root@mysql ~]# mysqldump -B mysql > /backup/mysql.sql
2[root@mysql ~]# grep pro_testlog /backup/mysql.sql
3INSERT INTO `proc` VALUES ('mysql','AddGeometryColumn','PROCEDURE','AddGeometryColumn','SQL','CONTAINS_SQL','NO','INVOKER','catalog varchar(64), t_schema varchar(64),\n t_name varchar(64), geometry_column varchar(64), t_srid int','','begin\n set @qwe= concat(\'ALTER TABLE \', t_schema, \'.\', t_name, \' ADD \', geometry_column,\' GEOMETRY REF_SYSTEM_ID=\', t_srid); PREPARE ls from @qwe; execute ls; deallocate prepare ls; end','root@localhost','2024-09-21 15:23:35','2024-09-21 15:23:35','','','utf8','utf8_general_ci','latin1_swedish_ci','begin\n set @qwe= concat(\'ALTER TABLE \', t_schema, \'.\', t_name, \' ADD \', geometry_column,\' GEOMETRY REF_SYSTEM_ID=\', t_srid); PREPARE ls from @qwe; execute ls; deallocate prepare ls; end','NONE'),('mysql','DropGeometryColumn','PROCEDURE','DropGeometryColumn','SQL','CONTAINS_SQL','NO','INVOKER','catalog varchar(64), t_schema varchar(64),\n t_name varchar(64), geometry_column varchar(64)','','begin\n set @qwe= concat(\'ALTER TABLE \', t_schema, \'.\', t_name, \' DROP \', geometry_column); PREPARE ls from @qwe; execute ls; deallocate prepare ls; end','root@localhost','2024-09-21 15:23:35','2024-09-21 15:23:35','','','utf8','utf8_general_ci','latin1_swedish_ci','begin\n set @qwe= concat(\'ALTER TABLE \', t_schema, \'.\', t_name, \' DROP \', geometry_column); PREPARE ls from @qwe; execute ls; deallocate prepare ls; end','NONE'),('hellodb','pro_testlog','PROCEDURE','pro_testlog','SQL','CONTAINS_SQL','NO','DEFINER','','','begin \ndeclare i int;\nset i = 1; \nwhile i < 100000 \ndo insert into testlog(name,age) values (concat(\'wang\',i),i); \nset i = i +1; \nend while; \nend','root@localhost','2024-09-21 18:42:55','2024-09-21 18:42:55','STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION','','utf8','utf8_general_ci','utf8_general_ci','begin \ndeclare i int;\nset i = 1; \nwhile i < 100000 \ndo insert into testlog(name,age) values (concat(\'wang\',i),i); \nset i = i +1; \nend while; \nend','NONE');
4[root@mysql ~]#
所以,即使你以后忘记加-R了,只要你把mysql数据库备份好了,那么相关的存储过程也算是备份下来了。
default-character-set选项
utf-8兼容latin1
1[root@mysql ~]# mysql
2Welcome to the MariaDB monitor. Commands end with ; or \g.
3Your MariaDB connection id is 62
4Server version: 10.3.17-MariaDB-log MariaDB Server
5
6Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
7
8Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
9
10MariaDB [(none)]> show create database hellodb;
11+----------+------------------------------------------------------------------+
12| Database | Create Database |
13+----------+------------------------------------------------------------------+
14| hellodb | CREATE DATABASE `hellodb` /*!40100 DEFAULT CHARACTER SET utf8 */ |
15+----------+------------------------------------------------------------------+
161 row in set (0.000 sec)
17
18MariaDB [(none)]> show create database hellodb2;
19+----------+---------------------------------------------------------------------+
20| Database | Create Database |
21+----------+---------------------------------------------------------------------+
22| hellodb2 | CREATE DATABASE `hellodb2` /*!40100 DEFAULT CHARACTER SET latin1 */ |
23+----------+---------------------------------------------------------------------+
241 row in set (0.000 sec)
25
26MariaDB [(none)]> show create database mysql;
27+----------+------------------------------------------------------------------+
28| Database | Create Database |
29+----------+------------------------------------------------------------------+
30| mysql | CREATE DATABASE `mysql` /*!40100 DEFAULT CHARACTER SET latin1 */ |
31+----------+------------------------------------------------------------------+
321 row in set (0.000 sec)
33
34MariaDB [(none)]>
35
36MariaDB [(none)]> show variables like 'character%';
37+--------------------------+------------------------------+
38| Variable_name | Value |
39+--------------------------+------------------------------+
40| character_set_client | utf8 |
41| character_set_connection | utf8 |
42| character_set_database | latin1 |
43| character_set_filesystem | binary |
44| character_set_results | utf8 |
45| character_set_server | latin1 |
46| character_set_system | utf8 |
47| character_sets_dir | /usr/share/mariadb/charsets/ |
48+--------------------------+------------------------------+
498 rows in set (0.001 sec)
50
51MariaDB [(none)]>
52
53
54##目前推荐
55utf-8mb4
–master-data选项
- 测试–master-data选项
1MariaDB [(none)]> select @@sql_log_bin;
2+---------------+
3| @@sql_log_bin |
4+---------------+
5| 1 |
6+---------------+
71 row in set (0.000 sec)
8
9MariaDB [(none)]> show master logs;
10+------------------+-----------+
11| Log_name | File_size |
12+------------------+-----------+
13| mysql-bin.000001 | 1308 |
14| mysql-bin.000002 | 950 |
15| mysql-bin.000003 | 28208 |
16| mysql-bin.000004 | 523073 |
17+------------------+-----------+
184 rows in set (0.000 sec)
19
20MariaDB [(none)]>
21
22
23
24[root@mysql ~]# mysqldump -A --master-data=2 > /backup/all_2.sql
25[root@mysql ~]# vim /backup/all_2.sql


如果继续修改数据库:
1MariaDB [(none)]> create database db2;
2Query OK, 1 row affected (0.000 sec)
3
4MariaDB [(none)]> show master logs;
5+------------------+-----------+
6| Log_name | File_size |
7+------------------+-----------+
8| mysql-bin.000001 | 1308 |
9| mysql-bin.000002 | 950 |
10| mysql-bin.000003 | 28208 |
11| mysql-bin.000004 | 523200 |
12+------------------+-----------+
134 rows in set (0.000 sec)
14
15MariaDB [(none)]>
再次对数据库做下修改。
不小心把表给误删除了:
1[root@mysql ~]# mysql hellodb
2
3MariaDB [hellodb]> drop table students;
4Query OK, 0 rows affected (0.003 sec)
5
6MariaDB [hellodb]>
又增加了一条新记录:
1MariaDB [hellodb]> insert teachers (name,age,gender)values('a',20,'M');
2Query OK, 1 row affected (0.001 sec)
3MariaDB [hellodb]> select *from teachers;
4+-----+---------------+-----+--------+
5| TID | Name | Age | Gender |
6+-----+---------------+-----+--------+
7| 1 | Song Jiang | 45 | M |
8| 2 | Zhang Sanfeng | 94 | M |
9| 3 | Miejue Shitai | 77 | F |
10| 4 | Lin Chaoying | 93 | F |
11| 5 | a | 20 | M |
12+-----+---------------+-----+--------+
135 rows in set (0.000 sec)
当前的环境:

看下当前最新备份的文件:
1[root@mysql ~]# ll /backup/ -t
2total 2108
3-rw-r--r--. 1 root root 498187 Sep 22 03:08 all_2.sql
4-rw-r--r--. 1 root root 484275 Sep 22 02:52 mysql.sql
5-rw-r--r--. 1 root root 7864 Sep 22 02:51 hellodb2_R_B.sql
6-rw-r--r--. 1 root root 9532 Sep 22 02:49 hellodb_R_B.sql
7-rw-r--r--. 1 root root 8418 Sep 22 02:46 hellodb_B.sql
8-rw-r--r--. 1 root root 138245 Sep 22 02:35 all.sql.gz
9-rw-r--r--. 1 root root 496386 Sep 22 02:34 all.sql
10-rw-r--r--. 1 root root 483318 Sep 22 01:53 mysql_2024-09-22.sql
11-rw-r--r--. 1 root root 7813 Sep 22 01:53 hellodb2_2024-09-22.sql
12-rw-r--r--. 1 root root 7807 Sep 22 01:53 hellodb_2024-09-22.sql
13[root@mysql ~]#
开始恢复故障:
查看备份文件
从这个点往后的都是备份后新增的数据:

导出备份后改变的所有sql操作
1[root@mysql ~]# ll /data/logbin/
2total 552
3-rw-rw----. 1 mysql mysql 1308 Sep 21 21:47 mysql-bin.000001
4-rw-rw----. 1 mysql mysql 950 Sep 21 23:22 mysql-bin.000002
5-rw-rw----. 1 mysql mysql 28208 Sep 21 23:23 mysql-bin.000003
6-rw-rw----. 1 mysql mysql 523585 Sep 22 09:35 mysql-bin.000004
7-rw-rw----. 1 mysql mysql 120 Sep 21 23:23 mysql-bin.index
8
9[root@mysql ~]# mysqlbinlog /data/logbin/mysql-bin.000004 --start-position=523073 > /backup/inc.sql
10
11[root@mysql ~]# vim /backup/inc.sql

1[root@mysql ~]# sed -n '/^DROP TABLE/p' /backup/inc.sql
2DROP TABLE `students` /* generated by server */
3
4#删除
5[root@mysql ~]# sed -i.bak '/^DROP TABLE/d' /backup/inc.sql
6[root@mysql ~]# ll /backup/inc.sql
7-rw-r--r--. 1 root root 2909 Sep 22 17:17 /backup/inc.sql
8[root@mysql ~]# ll /backup/inc.sql.bak
9-rw-r--r--. 1 root root 2957 Sep 22 17:12 /backup/inc.sql.bak
10
11
12[root@mysql ~]# ll /backup/ -t
13total 2116
14-rw-r--r--. 1 root root 2909 Sep 22 17:17 inc.sql
15-rw-r--r--. 1 root root 2957 Sep 22 17:12 inc.sql.bak
16-rw-r--r--. 1 root root 498187 Sep 22 03:08 all_2.sql
恢复数据库
- 关闭二进制日志
1MariaDB [(none)]> set @@sql_log_bin=0;
2Query OK, 0 rows affected (0.000 sec)
3
4MariaDB [(none)]> select @@sql_log_bin;
5+---------------+
6| @@sql_log_bin |
7+---------------+
8| 0 |
9+---------------+
101 row in set (0.000 sec)
- 覆盖还原数据库
1MariaDB [(none)]> source /backup/all_2.sql
2MariaDB [(none)]> source /backup/inc.sql
- 打开二进制日志功能
验证
1MariaDB [hellodb]> show databases;
2+--------------------+
3| Database |
4+--------------------+
5| db2 |
6| hellodb |
7| hellodb2 |
8| information_schema |
9| mysql |
10| performance_schema |
11+--------------------+
126 rows in set (0.000 sec)
13
14MariaDB [hellodb]> select *from students;
15+-------+---------------+-----+--------+---------+-----------+
16| StuID | Name | Age | Gender | ClassID | TeacherID |
17+-------+---------------+-----+--------+---------+-----------+
18| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
19| 2 | Shi Potian | 22 | M | 1 | 7 |
20| 3 | Xie Yanke | 53 | M | 2 | 16 |
21| 4 | Ding Dian | 32 | M | 4 | 4 |
22| 5 | Yu Yutong | 26 | M | 3 | 1 |
23| 6 | Shi Qing | 46 | M | 5 | NULL |
24| 7 | Xi Ren | 19 | F | 3 | NULL |
25| 8 | Lin Daiyu | 17 | F | 7 | NULL |
26| 9 | Ren Yingying | 20 | F | 6 | NULL |
27| 10 | Yue Lingshan | 19 | F | 3 | NULL |
28| 11 | Yuan Chengzhi | 23 | M | 6 | NULL |
29| 12 | Wen Qingqing | 19 | F | 1 | NULL |
30| 13 | Tian Boguang | 33 | M | 2 | NULL |
31| 14 | Lu Wushuang | 17 | F | 3 | NULL |
32| 15 | Duan Yu | 19 | M | 4 | NULL |
33| 16 | Xu Zhu | 21 | M | 1 | NULL |
34| 17 | Lin Chong | 25 | M | 4 | NULL |
35| 18 | Hua Rong | 23 | M | 7 | NULL |
36| 19 | Xue Baochai | 18 | F | 6 | NULL |
37| 20 | Diao Chan | 19 | F | 7 | NULL |
38| 21 | Huang Yueying | 22 | F | 6 | NULL |
39| 22 | Xiao Qiao | 20 | F | 1 | NULL |
40| 23 | Ma Chao | 23 | M | 4 | NULL |
41| 24 | Xu Xian | 27 | M | NULL | NULL |
42| 25 | Sun Dasheng | 100 | M | NULL | NULL |
43+-------+---------------+-----+--------+---------+-----------+
4425 rows in set (0.000 sec)
45
46MariaDB [hellodb]> select *from teachers;
47+-----+---------------+-----+--------+
48| TID | Name | Age | Gender |
49+-----+---------------+-----+--------+
50| 1 | Song Jiang | 45 | M |
51| 2 | Zhang Sanfeng | 94 | M |
52| 3 | Miejue Shitai | 77 | F |
53| 4 | Lin Chaoying | 93 | F |
54| 5 | a | 20 | M |
55+-----+---------------+-----+--------+
565 rows in set (0.000 sec)
57
58MariaDB [hellodb]>
搞定。
存在的问题:
一个库里2张表的时间可能不一致,会存在问题:😒(数据不一致问题)
理论上可以恢复,但是实际上可能存在问题;

因为只能还原到删表之前的状态:(后面的数据就是丢了,丢了的部分手工完成。)

mysqldump的MyISAM存储引擎相关的备份选项:
MyISAM不支持事务,只能支持温备;不支持热备,所以必须先锁定要备份的库,而后启动备份操作
1-x,--lock-all-tables #加全局读锁,锁定所有库的所有表,同时加--single-transaction或--lock-tables选项会关闭此选项功能,注意:数据量大时,可能会导致长时间无法并发访问数据库
2
3-l,--lock-tables #对于需要备份的每个数据库,在启动备份之前分别锁定其所有表,默认为on,--skip-lock-tables选项可禁用,对备份MyISAM的多个库,可能会造成数据不一致
4#注:以上选项对InnoDB表一样生效,实现温备,但不推荐使用
mysqldump的InnoDB存储引擎相关的备份选项:
InnoDB 存储引擎支持事务,可以利用事务的相应的隔离级别,实现热备,也可以实现温备但不建议用
1--single-transaction
2#此选项Innodb中推荐使用,不适用MyISAM,此选项会开始备份前,先执行START TRANSACTION指令开启事务
3
4#此选项通过在单个事务中转储所有表来创建一致的快照。 仅适用于存储在支持多版本控制的存储引擎中的表(目前只有InnoDB可以); 转储不保证与其他存储引擎保持一致。 在进行单事务转储时,要确保有效的转储文件(正确的表内容和二进制日志位置),没有其他连接应该使用以下语句:ALTER TABLE,DROP TABLE,RENAME TABLE,TRUNCATE TABLE,此选项和--lock-tables(此选项隐含提交挂起的事务)选项是相互排斥,备份大型表时,建议将--single-transaction选项和--quick结合一起使用
案例:第1种方式
1mysqldump [OPTIONS] database [tables] #支持指定数据库和指定多表的备份,但数据库本身定义不备份
2
3mysqldump -uroot -p'' hellodb students

过滤下:
1mysqldump -uroot -p'' hellodb students|grep -v '^\/\*'|grep -v '^--'

备份:
1mysqldump -uroot -p'' hellodb students > students.sql
那么生产的这个文件就可以用来还原了。
- 模拟误操作hellodb.studnets表
1mysql hellodb
2
3select *from students;
4MariaDB [hellodb]> update students set classid=1;
5Query OK, 21 rows affected (0.003 sec)
6Rows matched: 25 Changed: 21 Warnings: 0
7
8select *from students;

- 一旦发现数据库故障后,立刻停止让别人访问数据库,但是自己可以访问到。待故障解决后,再让数据库提供服务。
1show variables like 'skip_networking';

这个是个只读变量,只能写到数据库配置文件里,然后重启服务。
这个里如何配置,请看前面文档,此处忽略。
- 开始还原
1#建议也是先停掉二级日志
2mysql hellodb
3
4MariaDB [hellodb]> set sql_log_bin=0;
5Query OK, 0 rows affected (0.000 sec)
6
7MariaDB [hellodb]> system ls /root
8anaconda-ks.cfg Documents hellodb_innodb.sql ios Pictures students.sql testlog.sql
9Desktop Downloads initial-setup-ks.cfg Music Public Templates Videos
10MariaDB [hellodb]> source /root/students.sql

- 验证(符合预期😉)
1MariaDB [hellodb]> select *from students;
2+-------+---------------+-----+--------+---------+-----------+
3| StuID | Name | Age | Gender | ClassID | TeacherID |
4+-------+---------------+-----+--------+---------+-----------+
5| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
6| 2 | Shi Potian | 22 | M | 1 | 7 |
7| 3 | Xie Yanke | 53 | M | 2 | 16 |
8| 4 | Ding Dian | 32 | M | 4 | 4 |
9| 5 | Yu Yutong | 26 | M | 3 | 1 |
10| 6 | Shi Qing | 46 | M | 5 | NULL |
11| 7 | Xi Ren | 19 | F | 3 | NULL |
12| 8 | Lin Daiyu | 17 | F | 7 | NULL |
13| 9 | Ren Yingying | 20 | F | 6 | NULL |
14| 10 | Yue Lingshan | 19 | F | 3 | NULL |
单表恢复有可能导致表和表之间的数据可能不一致了。。。
案例:第2种方式
1mysqldump [OPTIONS] –B DB1 [DB2 DB3...] #支持指定数据库备份,包含数据库本身定义也会备份
- 查看当前数据库
1[root@mysql ~]# mysql -e 'show databases'
2+--------------------+
3| Database |
4+--------------------+
5| hellodb |
6| hellodb2 |
7| information_schema |
8| mysql |
9| performance_schema |
10+--------------------+
- 开始备份
1mysqldump -B hellodb mysql > hellodb_mysql_B.sql
- 模拟删除数据库
1mysql -e 'drop database hellodb'
- 还原数据库
1mysql < hellodb_mysql_B.sql
- 验证
1[root@mysql ~]# mysql
2Welcome to the MariaDB monitor. Commands end with ; or \g.
3Your MariaDB connection id is 41
4Server version: 10.3.17-MariaDB-log MariaDB Server
5
6Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
7
8Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
9
10MariaDB [(none)]> show databases;
11+--------------------+
12| Database |
13+--------------------+
14| hellodb |
15| hellodb2 |
16| information_schema |
17| mysql |
18| performance_schema |
19+--------------------+
205 rows in set (0.000 sec)
21
22MariaDB [(none)]> use hellodb;
23Reading table information for completion of table and column names
24You can turn off this feature to get a quicker startup with -A
25
26Database changed
27MariaDB [hellodb]> show tables;
28+-------------------+
29| Tables_in_hellodb |
30+-------------------+
31| classes |
32| coc |
33| courses |
34| scores |
35| students |
36| teachers |
37| toc |
38+-------------------+
397 rows in set (0.000 sec)
可以看到,数据库被还原了,里也是有数据的。
案例:第3种方式(推荐)
1[root@mysql ~]# mysql -e 'show databases'
2+--------------------+
3| Database |
4+--------------------+
5| hellodb |
6| hellodb2 |
7| information_schema |
8| mysql |
9| performance_schema |
10+--------------------+
11
12
13[root@mysql ~]# mysqldump -A > /backup/all.sql
14[root@mysql ~]# mysqldump -A |gzip > /backup/all.sql.gz
15[root@mysql ~]# ll /backup/all.sql*
16-rw-r--r--. 1 root root 496386 Sep 22 02:34 /backup/all.sql
17-rw-r--r--. 1 root root 138245 Sep 22 02:35 /backup/all.sql.gz
18
19
20[root@mysql ~]# grep ^'CREATE DATABASE' /backup/all.sql
21CREATE DATABASE /*!32312 IF NOT EXISTS*/ `hellodb` /*!40100 DEFAULT CHARACTER SET utf8 */;
22CREATE DATABASE /*!32312 IF NOT EXISTS*/ `hellodb2` /*!40100 DEFAULT CHARACTER SET latin1 */;
23CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysql` /*!40100 DEFAULT CHARACTER SET latin1 */;

mysqldump的MyISAM存储引擎相关的备份选项:
5.2.2 生产环境实战备份策略
InnoDB建议备份策略
1mysqldump –uroot -p –A –F –E –R --triggers --single-transaction --master-data=1
2--flush-privileges --default-character-set=utf8 --hex-blob
3>${BACKUP}/fullbak_${BACKUP_TIME}.sql

MyISAM建议备份策略
1mysqldump –uroot -p –A –F –E –R –x --master-data=1 --flush-privileges --
2triggers --default-character-set=utf8 --hex-blob
3>${BACKUP}/fullbak_${BACKUP_TIME}.sql

5.2.3 mysqldump 备份还原实战案例
5.2.3.1 实战案例:特定数据库的备份脚本
1[root@centos8 ~]#cat backup_hellodb.sh
2#!/bin/bash
3TIME=`date +%F_%H-%M-%S`
4DIR=/backup
5DB=hellodb
6PASS=magedu
7mysqldump -uroot -p "$PASS" -F –E –R --triggers --single-transaction --masterdata=2 --default-character-set=utf8 -q -B $DB | gzip >
8${DIR}/${DB}_${TIME}.sql.gz

5.2.3.2 实战案例:分库备份并压缩
1#案例1:grep+for循环
2for db in `mysql -e 'show databases'|grep -Ev 'information_schema|performance_schema|Database'`;do mysqldump -B $db > /backup/${db}_`date +%F`.sql;done
3
4
5#案例:2:grep+while read
6mysql -uroot -e 'show databases'|grep -Ev '^(Database|information_schema|performance_schema)$' |while read db;do mysqldump -B $db | gzip > /backup/$db.sql.gz;done
7
8
9#案例3:grep+sed
10mysql -uroot -e 'show databases'|grep -Ev '^(Database|information_schema|performance_schema)$' | sed -rn 's#(.*)#mysqldump -B \1 | gzip > /backup/\1.sql.gz#p' |bash
11
12
13#案例4:纯sed
14mysql -uroot -e 'show databases'|sed -rn '/^(Database|information_schema|performance_schema)$/!s#(.*)#mysqldump -B \1 | gzip > /backup/\1.sql.gz#p' |bash

案例1:grep+for循环
分库备份
以上是多个库备份在一起的。
那么如何分库备份呢?
1mysqldump -B hellodb > hellodb_B.sql
2mysqldump -B mysql > mysql_B.sql
备份命令:
1#准备备份目录
2mkdir /backup
3
4#备份
5for db in `mysql -e 'show databases'|grep -Ev 'information_schema|performance_schema|Database'`;do mysqldump -B $db > /backup/${db}_`date +%F`.sql;done
6
7#验证
8ll /backup/

注意:
1mysql -e 'show databases'
2mysql -e 'show databases'|grep -Ev 'information_schema|performance_schema|Database'

案例:2:grep+while read
1mysql -uroot -e 'show databases'|grep -Ev '^(Database|information_schema|performance_schema)$' |while read db;do mysqldump -B $db | gzip > /backup/$db.sql.gz;done
测试过程:
1[root@mysql ~]# mysql -uroot -e 'show databases'|grep -Ev '^(Database|information_schema|performance_schema)$' |while read db;do mysqldump -B $db | gzip > /backup/$db.sql.gz;done
2[root@mysql ~]# ll /backup/ -t
3total 3228
4-rw-r--r--. 1 root root 137111 Sep 23 06:51 mysql.sql.gz
5-rw-r--r--. 1 root root 1900 Sep 23 06:51 hellodb2.sql.gz
6-rw-r--r--. 1 root root 1971 Sep 23 06:51 hellodb.sql.gz
7-rw-r--r--. 1 root root 519 Sep 23 06:51 db2.sql.gz
8……

案例3:grep+sed
1mysql -uroot -e 'show databases'|grep -Ev '^(Database|information_schema|performance_schema)$' | sed -rn 's#(.*)#mysqldump -B \1 | gzip > /backup/\1.sql.gz#p' |bash
测试过程:
1[root@mysql ~]# mysql -uroot -e 'show databases'|grep -Ev '^(Database|information_schema|performance_schema)$' | sed -rn 's#(.*)#mysqldump -B \1 | gzip > /backup/\1.sql.gz#p' |bash
2[root@mysql ~]# ll /backup/ -t
3total 3092
4-rw-r--r--. 1 root root 137110 Sep 23 06:56 mysql.sql.gz
5-rw-r--r--. 1 root root 1900 Sep 23 06:56 hellodb2.sql.gz
6-rw-r--r--. 1 root root 1971 Sep 23 06:56 hellodb.sql.gz
7-rw-r--r--. 1 root root 519 Sep 23 06:56 db2.sql.gz
8……
说明:
这条命令的作用是备份 MySQL 数据库,并将备份文件压缩为 .sql.gz 格式。下面是每个部分的详细说明:
mysql -uroot -e 'show databases':- 使用
mysql命令行客户端,以root用户身份连接到 MySQL 数据库,并执行SHOW DATABASES命令,列出所有数据库。
- 使用
| grep -Ev '^(Database|information_schema|performance_schema)$':- 将
mysql命令的输出通过管道传递给grep,过滤掉不需要的数据库:-E选项允许使用扩展正则表达式。-v选项表示反向匹配(即排除)。- 正则表达式
^(Database|information_schema|performance_schema)$匹配数据库名称为Database、information_schema或performance_schema的行,这些是默认的系统数据库,通常不需要备份。
- 将
| sed -rn 's#(.*)#mysqldump -B \1 | gzip > /backup/\1.sql.gz#p':- 将经过过滤的数据库列表传递给
sed命令,进行格式化处理。 -r选项启用扩展正则表达式,-n选项使sed只输出被处理的行。s#(.*)#mysqldump -B \1 | gzip > /backup/\1.sql.gz#p:s#(.*)#...#是替换命令,将匹配到的行替换为mysqldump命令。\1表示被匹配的数据库名称。- 最终输出的格式是
mysqldump -B 数据库名 | gzip > /backup/数据库名.sql.gz。
- 将经过过滤的数据库列表传递给
| bash:- 将构造好的命令传递给
bash执行。 - 这样,实际的备份命令将被运行,创建数据库的备份并压缩存储到
/backup/目录下。
- 将构造好的命令传递给
总结
整条命令的作用是:
- 连接到 MySQL,列出所有数据库。
- 排除掉系统数据库。
- 为每个剩余的数据库生成一个
mysqldump命令,并通过gzip压缩备份文件。 - 将备份文件保存到
/backup/目录,文件名格式为数据库名.sql.gz。
案例4:纯sed
1mysql -uroot -e 'show databases'|sed -rn '/^(Database|information_schema|performance_schema)$/!s#(.*)#mysqldump -B \1 | gzip > /backup/\1.sql.gz#p' |bash
亲自测试:
1[root@mysql ~]# mysql -uroot -e 'show databases'|sed -rn '/^(Database|information_schema|performance_schema)$/!s#(.*)#mysqldump -B \1 | gzip > /backup/\1.sql.gz#p' |bash
2[root@mysql ~]# ll /backup/ -t
3total 3092
4-rw-r--r--. 1 root root 137111 Sep 23 06:58 mysql.sql.gz
5-rw-r--r--. 1 root root 1900 Sep 23 06:58 hellodb2.sql.gz
6-rw-r--r--. 1 root root 1971 Sep 23 06:58 hellodb.sql.gz
7-rw-r--r--. 1 root root 519 Sep 23 06:58 db2.sql.gz
说明:

实战案例:分库备份的实战脚本😉
1[root@centos8 ~]#cat backup_db.sh
2#!/bin/bash
3TIME=`date +%F_%H-%M-%S`
4DIR=/backup
5PASS=magedu
6[ -d "$DIR" ] || mkdir $DIR
7for DB in `mysql -uroot -p "$PASS" -e 'show databases' | grep -Ev
8"^Database|.*schema$"`;do
9 mysqldump -F --single-transaction --master-data=2 --default-characterset=utf8 -q -B $DB | gzip > ${DIR}/${DB}_${TIME}.sql.gz
10done

5.2.3.3 实战案例:分库备份的实战脚本
1[root@centos8 ~]#cat backup_db.sh
2#!/bin/bash
3TIME=`date +%F_%H-%M-%S`
4DIR=/backup
5PASS=magedu
6[ -d "$DIR" ] || mkdir $DIR
7for DB in `mysql -uroot -p "$PASS" -e 'show databases' | grep -Ev
8"^Database|.*schema$"`;do
9 mysqldump -F --single-transaction --master-data=2 --default-characterset=utf8 -q -B $DB | gzip > ${DIR}/${DB}_${TIME}.sql.gz
10done

5.2.3.4 实战案例:完全备份和还原
1#开启二进制日志
2[root@centos8 ~]#vim /etc/my.cnf.d/mariadb-server.cnf
3[mysqld]
4log-bin
5#备份
6
7[root@centos8 ~]#mysqldump -uroot -pmagedu -A -F --single-transaction --masterdata=2 |gzip > /backup/all-`date +%F`.sql.gz
8#还原
9[root@centos8 backup]#dnf install mariadb-server
10[root@centos8 backup]#gzip -d all-2019-11-27.sql.gz
11[root@centos8 ~]#mysql
12MariaDB [(none)]> set sql_log_bin=off;
13MariaDB [(none)]> source /backup/all-2019-11-27.sql
14MariaDB [(none)]> set sql_log_bin=on;

5.2.3.5 实战案例:利用二进制日志,还原数据库最新状态
1#二进制日志独立存放
2[mysqld]
3log-bin=/data/mysql/mysql-bin
4#完全备份,并记录备份的二进制位置
5mysqldump -uroot -pmagedu -A -F --default-character-set=utf8 --singletransaction --master-data=2 | gzip > /backup/all_`date +%F`.sql.gz
6#修改数据库
7insert students (name,age,gender)value('mage',20,'M');
8insert students (name,age,gender)value('wang',22,'M');
9#损坏数据库
10rm -rf /var/lib/mysql/*
11#还原
12cd /backup
13gzip -d all_2019-11-25.sql.gz
14#CentOS 8 需要事先生成数据库相关文件,CentOS7 不需要执行此步
15mysql_install_db --user=mysql
16systemctl restart mariadb
17MariaDB [(none)]> show master logs;
18+------------------+-----------+
19| Log_name | File_size |
20+------------------+-----------+
21| mysql-bin.000001 | 998 |
22| mysql-bin.000002 | 28090 |
23| mysql-bin.000003 | 342 |
24+------------------+-----------+
253 rows in set (0.000 sec)
26MariaDB [(none)]>set sql_log_bin=0;
27MariaDB [(none)]>source /data/all_2019-11-25.sql
28[root@centos8 ~]#grep '^-- CHANGE MASTER TO' /data/all_2019-11-25.sql
29-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=328;
30#二进制日志的备份
31[root@centos8 mysql]#mysqlbinlog mysql-bin.000001 --start-position=328 >
32/backup/inc.sql
33[root@centos8 mysql]#mysqlbinlog mysql-bin.000002 >> /backup/inc.sql
34MariaDB [(none)]>set sql_log_bin=0;
35MariaDB [(none)]>source /backup/inc.sql
36MariaDB [(none)]>set sql_log_bin=1;



5.2.3.6 实战案例:mysqldump 和二进制日志结合实现增量备份
1[root@centos8 ~]#mysqldump -uroot -p -A -F --single-transaction --master-data=2
2|gzip > /backup/all-`date +%F`.sql.gz
3#观察备份文件中的二进制文件和位置,将之后的二进制日志进行复制备份
4[root@centos8 ~]#cp /var/lib/mysql/mariadb-bin.000003 /backup
5[root@centos8 ~]#mysqlbinlog --start-position=389 /backup/mariadb-bin.000003 >
6/backup/inc.sql

5.2.3.7 实战案例:恢复误删除的表
案例说明:每天2:30做完全备份,早上10:00误删除students,10:10才发现故障,现需要将数据库还原到10:10的状态,且恢复被删除的students表
1#完全备份
2[root@centos8 ~]#mysqldump -uroot -p -A -F --single-transaction --master-data=2
3> /backup/allbackup_`date +%F_%T`.sql
4[root@centos8 ~]#ll /backup/
5total 2992
6-rw-r--r-- 1 root root 3060921 Nov 27 10:20 allbackup_2019-11-27_10:20:08.sql
7#完全备份后数据更新
8MariaDB [testdb]> insert students (name,age,gender) values('rose',20,'f');
9Query OK, 1 row affected (0.001 sec)
10MariaDB [testdb]> insert students (name,age,gender) values('jack',22,'M');
11Query OK, 1 row affected (0.001 sec)
12#10:00误删除了一个重要的表
13MariaDB [testdb]> drop table students;
14Query OK, 0 rows affected (0.021 sec)
15#后续其它表继续更新
16MariaDB [testdb]> use hellodb;
17Reading table information for completion of table and column names
18You can turn off this feature to get a quicker startup with -A
19Database changed
20MariaDB [hellodb]> insert teachers (name,age,gender)values('wang',30,'M');
21Query OK, 1 row affected (0.002 sec)
22MariaDB [hellodb]> insert teachers (name,age,gender)values('mage',28,'M');
23Query OK, 1 row affected (0.002 sec)
24MariaDB [hellodb]> select * from teachers;
25+-----+---------------+-----+--------+
26| TID | Name | Age | Gender |
27+-----+---------------+-----+--------+
28| 1 | Song Jiang | 45 | M |
29| 2 | Zhang Sanfeng | 94 | M |
30| 3 | Miejue Shitai | 77 | F |
31| 4 | Lin Chaoying | 93 | F |
32| 5 | wang | 30 | M |
33| 6 | mage | 28 | M |
34+-----+---------------+-----+--------+
356 rows in set (0.001 sec)
36#10:10发现表删除,进行还原
37#停止数据库访问
38#从完全备份中,找到二进制位置
39[root@centos8 ~]#grep '\-\- CHANGE MASTER TO' /backup/allbackup_2019-11-
4027_10\:20\:08.sql
41-- CHANGE MASTER TO MASTER_LOG_FILE='mariadb-bin.000003', MASTER_LOG_POS=389;
42#备份从完全备份后的二进制日志
43[root@centos8 ~]#mysqlbinlog --start-position=389 /var/lib/mysql/mariadbbin.000003 > /backup/inc.sql
44#找到误删除的语句,从备份中删除此语句
45[root@centos8 ~]#vim /data/inc.sql
46#DROP TABLE `student_info` /* generated by server */
47#如果文件过大,可以使用sed实现
48[root@centos8 ~]#sed -i.bak '/^DROP TABLE/d' /data/inc.sql
49#利用完全备份和修改过的二进制日志进行还原
50[root@centos8 ~]#mysql -uroot -p
51MariaDB [hellodb]> set sql_log_bin=0;
52MariaDB [hellodb]> source /backup/allbackup_2019-11-27_10:20:08.sql;
53MariaDB [hellodb]> source /backup/inc.sql
54MariaDB [hellodb]> set sql_log_bin=1;

5.3 xtrabackup备份工具
5.3.1 xtrabackup工具介绍
Percona 公司
官网:www.percona.com
percona-server
InnoDB –> XtraDB
Xtrabackup备份工具
percona提供的mysql数据库备份工具,惟一开源的能够对innodb和xtradb数据库进行热备的工具
手册:https://www.percona.com/doc/percona-xtrabackup/LATEST/index.html
下载: https://www.percona.com/downloads/



xtrabackup 特点:
- 备份还原过程快速、可靠
- 备份过程不会打断正在执行的事务
- 能够基于压缩等功能节约磁盘空间和流量
- 自动实现备份检验
- 开源,免费
xtrabackup工具文件组成
Xtrabackup2.2 版之前包括4个可执行文件:
- innobackupex: Perl 脚本
- xtrabackup: C/C++,编译的二进制程序
- xbcrypt: 加解密
- xbstream: 支持并发写的流文件格式
说明:
xtrabackup 是用来备份 InnoDB 表的,不能备份非 InnoDB 表,和 MySQL Server 没有交互;
innobackupex 脚本用来备份非 InnoDB 表,同时会调用 xtrabackup 命令来备份 InnoDB 表,还会和MySQL Server 发送命令进行交互,如加全局读锁(FTWRL)、获取位点(SHOW SLAVE STATUS)等。即innobackupex是在 xtrabackup 之上做了一层封装实现的。
xtrabackup的新版变化
xtrabackup版本升级到2.4后,相比之前的2.1有了比较大的变化:innobackupex 功能全部集成到xtrabackup 里面,只有一个 binary程序,另外为了兼容考虑,innobackupex作为 xtrabackup 的软链接,即xtrabackup现在支持非Innodb表备份,并且 Innobackupex 在下一版本中移除,建议通过xtrabackup替换innobackupex。
xtrabackup备份过程

备份生成的相关文件
使用innobackupex备份时,其会调用xtrabackup备份所有的InnoDB表,复制所有关于表结构定义的相关文件(.frm)、以及MyISAM、MERGE、CSV和ARCHIVE表的相关文件,同时还会备份触发器和数据库配置信息相关的文件。这些文件会被保存至一个以时间命名的目录中,在备份时,innobackupex还会在备份目录中创建如下文件:
- xtrabackup_info:文本文件,innobackupex工具执行时的相关信息,包括版本,备份选项,备份时长,备份LSN(log sequence number日志序列号),BINLOG的位置
- xtrabackup_checkpoints:文本文件,备份类型(如完全或增量)、备份状态(如是否已经为prepared状态)和LSN范围信息,每个InnoDB页(通常为16k大小)都会包含一个日志序列号LSN。LSN是整个数据库系统的系统版本号,每个页面相关的LSN能够表明此页面最近是如何发生改变的
- xtrabackup_binlog_info:文本文件,MySQL服务器当前正在使用的二进制日志文件及至备份这一刻为止二进制日志事件的位置,可利用实现基于binlog的恢复
- backup-my.cnf:文本文件,备份命令用到的配置选项信息
- xtrabackup_logfile:备份生成的二进制日志文件
范例:相关文件
1[root@centos8 ~]#ll /backup/
2total 12340
3-rw-r----- 1 root root 487 Jun 12 15:07 backup-my.cnf
4
5drwxr-x--- 2 root root 272 Jun 12 15:07 hellodb
6-rw-r----- 1 root root 425 Jun 12 15:07 ib_buffer_pool
7-rw-r----- 1 root root 12582912 Jun 12 15:07 ibdata1
8drwxr-x--- 2 root root 4096 Jun 12 15:07 mysql
9drwxr-x--- 2 root root 8192 Jun 12 15:07 performance_schema
10drwxr-x--- 2 root root 8192 Jun 12 15:07 sys
11-rw-r----- 1 root root 25 Jun 12 15:07 xtrabackup_binlog_info
12-rw-r----- 1 root root 135 Jun 12 15:07 xtrabackup_checkpoints
13-rw-r----- 1 root root 479 Jun 12 15:07 xtrabackup_info
14-rw-r----- 1 root root 2560 Jun 12 15:07 xtrabackup_logfile
15[root@centos8 ~]#cat /backup/xtrabackup_info
16uuid = 55a26ea0-ac7b-11ea-a8ab-000c293f7395
17name =
18tool_name = xtrabackup
19tool_command = -uroot -pmagedu --backup --target-dir=/backup/
20tool_version = 2.4.20
21ibbackup_version = 2.4.20
22server_version = 5.7.29-log
23start_time = 2020-06-12 15:07:08
24end_time = 2020-06-12 15:07:10
25lock_time = 1
26binlog_pos = filename 'centos8-bin.000002', position '10185'
27innodb_from_lsn = 0
28innodb_to_lsn = 2687527
29partial = N
30incremental = N
31format = file
32compact = N
33compressed = N
34encrypted = N
35[root@centos8 ~]#cat /backup/xtrabackup_checkpoints
36backup_type = full-backuped
37from_lsn = 0
38to_lsn = 2687527
39last_lsn = 2687536
40compact = 0
41recover_binlog_info = 0
42flushed_lsn = 2687536
43[root@centos8 ~]#cat /backup/xtrabackup_binlog_info
44centos8-bin.000002 10185
45[root@centos8 ~]#cat /backup/backup-my.cnf
46# This MySQL options file was generated by innobackupex.
47# The MySQL server
48[mysqld]
49innodb_checksum_algorithm=crc32
50innodb_log_checksum_algorithm=strict_crc32
51innodb_data_file_path=ibdata1:12M:autoextend
52innodb_log_files_in_group=2
53innodb_log_file_size=50331648
54innodb_fast_checksum=false
55innodb_page_size=16384
56innodb_log_block_size=512
57innodb_undo_directory=./
58innodb_undo_tablespaces=0
59server_id=1
60redo_log_version=1
61server_uuid=6fb9641a-ac79-11ea-8bed-000c293f7395
62master_key_id=0
63[root@centos8 ~]#file /backup/xtrabackup_logfile
64/backup/xtrabackup_logfile: data
5.3.2 xtrabackup安装
yum install percona-xtrabackup 在EPEL源中
最新版本下载安装:
https://www.percona.com/downloads/XtraBackup/LATEST/
1dnf install -y percona-xtrabackup-24-2.4.20-1.el8.x86_64.rpm
2
3
4[root@centos8 ~]# rpm -ql percona-xtrabackup-24
5/usr/bin/innobackupex
6/usr/bin/xbcloud
7/usr/bin/xbcloud_osenv
8/usr/bin/xbcrypt
9/usr/bin/xbstream
10/usr/bin/xtrabackup
11/usr/lib/.build-id
12/usr/lib/.build-id/07
13/usr/lib/.build-id/07/7cff02ee26ea646a822a3f936194758707edd1
14/usr/lib/.build-id/39
15/usr/lib/.build-id/39/f3e9ba1bfa15a43b78bca58bc6ae9c3b15f1b5
16/usr/lib/.build-id/3a
17/usr/lib/.build-id/3a/911c034513e809c6752d5297c9d69c9c19bc9a
18/usr/lib/.build-id/85
19/usr/lib/.build-id/85/3597a47905af2ef200a6def4fb2582dc3ff60b
20/usr/lib/.build-id/ad
21/usr/lib/.build-id/ad/45538c7f190bf3875f39562c7e33c39ef9425c
22/usr/lib/.build-id/ea
23/usr/lib/.build-id/ea/0e60d4d718a1127d337df206d7004656433ebc
24/usr/lib64/xtrabackup/plugin/keyring_file.so
25/usr/lib64/xtrabackup/plugin/keyring_vault.so
26/usr/share/doc/percona-xtrabackup-24
27/usr/share/doc/percona-xtrabackup-24/COPYING
28/usr/share/man/man1/innobackupex.1.gz
29/usr/share/man/man1/xbcrypt.1.gz
30/usr/share/man/man1/xbstream.1.gz
31/usr/share/man/man1/xtrabackup.1.gz
32[root@centos8 ~]#
33
34
35🍊 innobackupex工具和xtrabackup已经合二为一了:
36[root@centos8 ~]# ll /usr/bin/innobackupex
37lrwxrwxrwx. 1 root root 10 Apr 21 2020 /usr/bin/innobackupex -> xtrabackup
38[root@centos8 ~]# ll /usr/bin/xtrabackup
39-rwxr-xr-x. 1 root root 21303688 Apr 21 2020 /usr/bin/xtrabackup
5.3.3 xtrabackup用法
5.3.4 实战案例:利用xtrabackup实现完全备份及还原
2.4以后的是新版本,2.4以前的是老版本。
测试成功(2024年10月29日)
测试环境:
1CentOS Linux release 8.1.1911 (Core)系统
2mysql 5.7.29
3xtrabackup-24-2.4.20
汇总
11 安装xtrabackup包
2[root@centos8 ~]#yum -y install percona-xtrabackup-24-2.4.20-1.el8.x86_64.rpm
3
42 在原主机做完全备份到/backup
5#/backup目录不需事先创建
6[root@centos8 ~]#xtrabackup -uroot -pmagedu --backup --target-dir=/backup/
7[root@centos8 ~]#scp -r /backup/* 目标主机:/backup
8
93 在目标主机上还原
101)预准备:确保数据一致,提交完成的事务,回滚未完成的事务
11[root@centos8 ~]#xtrabackup --prepare --target-dir=/backup/
12
132)复制到数据库目录
14 注意:数据库目录必须为空,MySQL服务不能启动
15[root@centos8 ~]#xtrabackup --copy-back --target-dir=/backup/
163)还原属性
17[root@centos8 ~]#chown -R mysql:mysql /var/lib/mysql
184)启动服务
19[root@centos8 ~]#service mysqld start
备份
- 本地数据库导入测试数据
1[root@centos8 ~]# mysql -uroot -pmagedu < hellodb_innodb.sql
2mysql: [Warning] Using a password on the command line interface can be insecure.
3[root@centos8 ~]#
- 开始备份
1[root@centos8 ~]# xtrabackup --backup --target-dir=/backup/

备份完成。
- 查看一些备份下来的文件内容。
1[root@centos8 backup]# cat xtrabackup_info
2uuid = 9515214f-7b9f-11ef-8d4a-000c29e77e43
3name =
4tool_name = xtrabackup
5tool_command = --backup --target-dir=/backup/
6tool_version = 2.4.20
7ibbackup_version = 2.4.20
8server_version = 5.7.29-log
9start_time = 2024-09-26 08:37:58
10end_time = 2024-09-26 08:38:00
11lock_time = 1
12binlog_pos = filename 'mysql-bin.000002', position '11019'
13innodb_from_lsn = 0
14innodb_to_lsn = 2682511
15partial = N
16incremental = N
17format = file
18compact = N
19compressed = N
20encrypted = N
21[root@centos8 backup]# cat xtrabackup_checkpoints
22backup_type = full-backuped
23from_lsn = 0
24to_lsn = 2682511
25last_lsn = 2682520
26compact = 0
27recover_binlog_info = 0
28flushed_lsn = 2682520
29[root@centos8 backup]# cat xtrabackup_binlog_info
30mysql-bin.000002 11019
31[root@centos8 backup]# cat backup-my.cnf
32# This MySQL options file was generated by innobackupex.
33
34# The MySQL server
35[mysqld]
36innodb_checksum_algorithm=crc32
37innodb_log_checksum_algorithm=strict_crc32
38innodb_data_file_path=ibdata1:12M:autoextend
39innodb_log_files_in_group=2
40innodb_log_file_size=50331648
41innodb_fast_checksum=false
42innodb_page_size=16384
43innodb_log_block_size=512
44innodb_undo_directory=./
45innodb_undo_tablespaces=0
46server_id=1
47redo_log_version=1
48server_uuid=897cf451-7b98-11ef-8a5e-000c29e77e43
49master_key_id=0
50[root@centos8 backup]# file xtrabackup_logfile
51xtrabackup_logfile: data
另外,这个数据库配置文件我们得手动拷贝下:🚦
1[root@centos8 backup]# cat /etc/my.cnf
2[mysqld]
3server-id=1
4log-bin
5datadir=/data/mysql
6socket=/data/mysql/mysql.sock
7
8log-error=/data/mysql/mysql.log
9pid-file=/data/mysql/mysql.pid
10[client]
11socket=/data/mysql/mysql.sock
12[root@centos8 backup]#
现在来对数据库做一下破坏:。。。
模拟数据库奔溃:。。。
把mysql数据给移动到opt目录:
1[root@centos8 backup]# ls /opt/
2[root@centos8 backup]# mv /data/mysql/* /opt
此时能看到当前mysql是启动失败的:
service mysqld status

虽然mysql的进程还在,但他的数据文件时已经不在了,服务也异常开了,我们来杀掉mysql的服务进程:
1[root@centos8 ~]# ss -ntlp
2State Recv-Q Send-Q Local Address:Port Peer Address:Port
3LISTEN 0 128 0.0.0.0:111 0.0.0.0:* users:(("rpcbind",pid=981,fd=4),("systemd",pid=1,fd=42))
4LISTEN 0 32 192.168.122.1:53 0.0.0.0:* users:(("dnsmasq",pid=2145,fd=6))
5LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1135,fd=5))
6LISTEN 0 5 127.0.0.1:631 0.0.0.0:* users:(("cupsd",pid=1132,fd=10))
7LISTEN 0 128 [::]:111 [::]:* users:(("rpcbind",pid=981,fd=6),("systemd",pid=1,fd=44))
8LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=1135,fd=7))
9LISTEN 0 5 [::1]:631 [::]:* users:(("cupsd",pid=1132,fd=9))
10LISTEN 0 80 *:3306 *:* users:(("mysqld",pid=1910,fd=40))
11[root@centos8 ~]# ps -aux|grep mysqld
12root 1598 0.0 0.1 25380 3696 ? S 07:16 0:00 /bin/sh /usr/local/mysql/bin/mysqld_safe --datadir=/data/mysql --pid-file=/data/mysql/mysql.pid
13mysql 1910 0.0 5.2 1418500 188036 ? Sl 07:16 0:00 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/data/mysql --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=/data/mysql/mysql.log --pid-file=/data/mysql/mysql.pid --socket=/data/mysql/mysql.sock
14root 2933 0.0 0.0 12108 972 pts/0 S+ 07:42 0:00 grep --color=auto mysqld
15[root@centos8 ~]# killall mysqld
16[root@centos8 ~]# ss -ntlp
17State Recv-Q Send-Q Local Address:Port Peer Address:Port
18LISTEN 0 128 0.0.0.0:111 0.0.0.0:* users:(("rpcbind",pid=981,fd=4),("systemd",pid=1,fd=42))
19LISTEN 0 32 192.168.122.1:53 0.0.0.0:* users:(("dnsmasq",pid=2145,fd=6))
20LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1135,fd=5))
21LISTEN 0 5 127.0.0.1:631 0.0.0.0:* users:(("cupsd",pid=1132,fd=10))
22LISTEN 0 128 [::]:111 [::]:* users:(("rpcbind",pid=981,fd=6),("systemd",pid=1,fd=44))
23LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=1135,fd=7))
24LISTEN 0 5 [::1]:631 [::]:* users:(("cupsd",pid=1132,fd=9))
25[root@centos8 ~]# ps -aux|grep mysqld
26root 2946 0.0 0.0 12108 1084 pts/0 S+ 07:42 0:00 grep --color=auto mysqld
27[root@centos8 ~]#
现在来开始还原下数据库:
- 必须清空里面的东西:
1[root@centos8 ~]# ll /data/mysql
2total 4
3-rw-r-----. 1 mysql mysql 324 Oct 29 07:42 ib_buffer_pool
4[root@centos8 ~]# rm -rf /data/mysql/*
- 我们来尝试手动起一下
1[root@centos8 ~]# service mysqld start
2Starting MySQL.Logging to '/data/mysql/mysql.log'.
3... ERROR! The server quit without updating PID file (/data/mysql/mysql.pid).
4[root@centos8 ~]# ll /data/mysql
5total 110652
6-rw-r-----. 1 mysql mysql 56 Oct 29 07:48 auto.cnf
7-rw-------. 1 mysql mysql 1676 Oct 29 07:48 ca-key.pem
8-rw-r--r--. 1 mysql mysql 1112 Oct 29 07:48 ca.pem
9-rw-r-----. 1 mysql mysql 177 Oct 29 07:48 centos8-bin.000001
10-rw-r-----. 1 mysql mysql 21 Oct 29 07:48 centos8-bin.index
11-rw-r--r--. 1 mysql mysql 1112 Oct 29 07:48 client-cert.pem
12-rw-------. 1 mysql mysql 1680 Oct 29 07:48 client-key.pem
13-rw-r-----. 1 mysql mysql 215 Oct 29 07:48 ib_buffer_pool
14-rw-r-----. 1 mysql mysql 12582912 Oct 29 07:48 ibdata1
15-rw-r-----. 1 mysql mysql 50331648 Oct 29 07:48 ib_logfile0
16-rw-r-----. 1 mysql mysql 50331648 Oct 29 07:48 ib_logfile1
17-rw-r-----. 1 mysql mysql 9523 Oct 29 07:48 mysql.log
18-rw-------. 1 mysql mysql 1680 Oct 29 07:48 private_key.pem
19-rw-r--r--. 1 mysql mysql 452 Oct 29 07:48 public_key.pem
20-rw-r--r--. 1 mysql mysql 1112 Oct 29 07:48 server-cert.pem
21-rw-------. 1 mysql mysql 1680 Oct 29 07:48 server-key.pem
22[root@centos8 ~]# rm -rf /data/mysql/*
23[root@centos8 ~]# ss -ntlp
24State Recv-Q Send-Q Local Address:Port Peer Address:Port
25LISTEN 0 128 0.0.0.0:111 0.0.0.0:* users:(("rpcbind",pid=981,fd=4),("systemd",pid=1,fd=42))
26LISTEN 0 32 192.168.122.1:53 0.0.0.0:* users:(("dnsmasq",pid=2145,fd=6))
27LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1135,fd=5))
28LISTEN 0 5 127.0.0.1:631 0.0.0.0:* users:(("cupsd",pid=1132,fd=10))
29LISTEN 0 128 [::]:111 [::]:* users:(("rpcbind",pid=981,fd=6),("systemd",pid=1,fd=44))
30LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=1135,fd=7))
31LISTEN 0 5 [::1]:631 [::]:* users:(("cupsd",pid=1132,fd=9))
32[root@centos8 ~]# ps -aux|grep mysqld
33root 3326 0.0 0.0 12108 1100 pts/0 S+ 07:51 0:00 grep --color=auto mysqld
34[root@centos8 ~]#
手动起mysql是起不来了,同样我们再次删除下/data/mysql/下文件。
还原
1)预准备:确保数据一致,提交完成的事务,回滚未完成的事务
1[root@centos8 ~]#xtrabackup --prepare --target-dir=/backup/


2)复制到数据库目录 注意:数据库目录必须为空,MySQL服务不能启动
1[root@centos8 backup]# ls /data/mysql
2[root@centos8 backup]# ss -ntlp
3State Recv-Q Send-Q Local Address:Port Peer Address:Port
4LISTEN 0 128 0.0.0.0:111 0.0.0.0:* users:(("rpcbind",pid=981,fd=4),("systemd",pid=1,fd=42))
5LISTEN 0 32 192.168.122.1:53 0.0.0.0:* users:(("dnsmasq",pid=2145,fd=6))
6LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1135,fd=5))
7LISTEN 0 5 127.0.0.1:631 0.0.0.0:* users:(("cupsd",pid=1132,fd=10))
8LISTEN 0 128 [::]:111 [::]:* users:(("rpcbind",pid=981,fd=6),("systemd",pid=1,fd=44))
9LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=1135,fd=7))
10LISTEN 0 5 [::1]:631 [::]:* users:(("cupsd",pid=1132,fd=9))
11[root@centos8 backup]# xtrabackup --copy-back --target-dir=/backup/

1[root@centos8 backup]# ll /data/mysql
2total 122924
3drwxr-x---. 2 root root 272 Oct 29 08:01 hellodb
4-rw-r-----. 1 root root 425 Oct 29 08:01 ib_buffer_pool
5-rw-r-----. 1 root root 12582912 Oct 29 08:01 ibdata1
6-rw-r-----. 1 root root 50331648 Oct 29 08:01 ib_logfile0
7-rw-r-----. 1 root root 50331648 Oct 29 08:01 ib_logfile1
8-rw-r-----. 1 root root 12582912 Oct 29 08:01 ibtmp1
9drwxr-x---. 2 root root 4096 Oct 29 08:01 mysql
10drwxr-x---. 2 root root 8192 Oct 29 08:01 performance_schema
11drwxr-x---. 2 root root 8192 Oct 29 08:01 sys
12-rw-r-----. 1 root root 22 Oct 29 08:01 xtrabackup_binlog_pos_innodb
13-rw-r-----. 1 root root 461 Oct 29 08:01 xtrabackup_info
14-rw-r-----. 1 root root 1 Oct 29 08:01 xtrabackup_master_key_id
15[root@centos8 backup]#
16[root@centos8 backup]# ll -d /data/mysql
17drwxr-xr-x. 6 mysql mysql 251 Oct 29 08:01 /data/mysql
3)还原属性
1[root@centos8 backup]# chown -R mysql:mysql /data/mysql
4)启动服务
1[root@centos8 backup]# service mysqld start
2Starting MySQL.Logging to '/data/mysql/mysql.log'.
3. SUCCESS!
4[root@centos8 backup]# ss -ntlp
5State Recv-Q Send-Q Local Address:Port Peer Address:Port
6LISTEN 0 128 0.0.0.0:111 0.0.0.0:* users:(("rpcbind",pid=981,fd=4),("systemd",pid=1,fd=42))
7LISTEN 0 32 192.168.122.1:53 0.0.0.0:* users:(("dnsmasq",pid=2145,fd=6))
8LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1135,fd=5))
9LISTEN 0 5 127.0.0.1:631 0.0.0.0:* users:(("cupsd",pid=1132,fd=10))
10LISTEN 0 128 [::]:111 [::]:* users:(("rpcbind",pid=981,fd=6),("systemd",pid=1,fd=44))
11LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=1135,fd=7))
12LISTEN 0 5 [::1]:631 [::]:* users:(("cupsd",pid=1132,fd=9))
13LISTEN 0 80 *:3306 *:* users:(("mysqld",pid=3992,fd=25))
14
15[root@centos8 backup]# mysql
16Welcome to the MySQL monitor. Commands end with ; or \g.
17Your MySQL connection id is 2
18Server version: 5.7.29-log MySQL Community Server (GPL)
19
20Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
21
22Oracle is a registered trademark of Oracle Corporation and/or its
23affiliates. Other names may be trademarks of their respective
24owners.
25
26Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
27
28mysql> show databases;
29+--------------------+
30| Database |
31+--------------------+
32| information_schema |
33| hellodb |
34| mysql |
35| performance_schema |
36| sys |
37+--------------------+
385 rows in set (0.00 sec)
39
40mysql> use hellodb;
41Reading table information for completion of table and column names
42You can turn off this feature to get a quicker startup with -A
43
44Database changed
45mysql> select * from teachers;
46+-----+---------------+-----+--------+
47| TID | Name | Age | Gender |
48+-----+---------------+-----+--------+
49| 1 | Song Jiang | 45 | M |
50| 2 | Zhang Sanfeng | 94 | M |
51| 3 | Miejue Shitai | 77 | F |
52| 4 | Lin Chaoying | 93 | F |
53+-----+---------------+-----+--------+
544 rows in set (0.00 sec)
55
56mysql> \q
57Bye
58[root@centos8 backup]#
完成。
旧版本
11 在源主机备份
2innobackupex --user=root /backup
3scp -r /backup/2018-02-23_11-55-57/ 目标主机:/data/
4
52 在目标主机预准备并还原
6#预准备
7innobackupex --apply-log /data/2018-02-23_11-55-57/
8#还原过程
9systemctl stop mariadb
10rm -rf /var/lib/mysql/*
11innobackupex --copy-back /data/2018-02-23_11-55-57/
12chown -R mysql.mysql /var/lib/mysql/
13systemctl start mariadb

5.3.5 实战案例:利用xtrabackup完全,增量备份及还原

形象记忆:扎口袋

案例1:新版xtrabackup完全,增量备份及还原
11 备份过程
21)完全备份:
3[root@centos8 ~]#mkdir /backup/
4[root@centos8 ~]#xtrabackup -uroot -pmagedu --backup --target-dir=/backup/base
52)第一次修改数据
63)第一次增量备份
7[root@centos8 ~]#xtrabackup -uroot -pmagedu --backup --target-dir=/backup/inc1 -
8-incremental-basedir=/backup/base
94)第二次修改数据
105)第二次增量
11[root@centos8 ~]#xtrabackup -uroot -pmagedu --backup --target-dir=/backup/inc2 -
12-incremental-basedir=/backup/inc1
136)[root@centos8 ~]#scp -r /backup/* 目标主机:/backup/
14#备份过程生成三个备份目录
15/backup/{base,inc1,inc2}
16
17
182还原过程
191)预准备完成备份,此选项--apply-log-only 阻止回滚未完成的事务
20[root@centos8 ~]#xtrabackup --prepare --apply-log-only --target-dir=/backup/base
212)合并第1次增量备份到完全备份,
22[root@centos8 ~]#xtrabackup --prepare --apply-log-only --target-dir=/backup/base
23--incremental-dir=/backup/inc1
243)合并第2次增量备份到完全备份:最后一次还原不需要加选项--apply-log-only
25[root@centos8 ~]#xtrabackup --prepare --target-dir=/backup/base --incrementaldir=/backup/inc2
264)复制到数据库目录,注意数据库目录必须为空,MySQL服务不能启动
27[root@centos8 ~]#xtrabackup --copy-back --target-dir=/backup/base
285)还原属性:[root@centos8 ~]#chown -R mysql:mysql /var/lib/mysql
296)启动服务:[root@centos8 ~]#service mysqld start
案例2:旧版xtrabackup完全,增量备份及还原
11 在源主机备份
2innobackupex /backup
3mkdir /backup/inc{1,2}
4#修改数据库内容
5innobackupex --incremental /backup/inc1 --incremental-basedir=/backup/2018-02-
623_14-21-42(完全备份生成的路径)
7#再次修改数据库内容
8innobackupex --incremental /backup/inc2 --incrementalbasedir=/backup/inc1/2018-02-23_14-26-17 (上次增量备份生成的路径)
9scp -r /backup/* 目标主机:/data/
10
11
122 在目标主机还原
13#预准备过程
14innobackupex --apply-log --redo-only /data/2018-02-23_14-21-42/
15innobackupex --apply-log --redo-only /data/2018-02-23_14-21-42/ --incrementaldir=/data/inc1/2018-02-23_14-26-17
16innobackupex --apply-log /data/2018-02-23_14-21-42/ --incrementaldir=/data/inc2/2018-02-23_14-28-29/
17#还原过程
18不启动mariadb
19systemctl stop mariadb
20rm -rf /var/lib/mysql/*
21innobackupex --copy-back /data/2018-02-23_14-21-42/
22chown -R mysql.mysql /var/lib/mysql/
23systemctl start mariadb

本次测试
2024年11月5日测试(测试成功)
环境
1CentOS Linux release 8.1.1911 (Core)系统
2mysql 5.7.29
3xtrabackup-24-2.4.20
- 清空当前文件夹
1[root@centos8 backup]# rm -rf /backup/*
2[root@centos8 backup]# ls /backup/
- 当前数据库是有数据的
1[root@centos8 backup]# mysql -e "show databases;"
2+--------------------+
3| Database |
4+--------------------+
5| information_schema |
6| hellodb |
7| mysql |
8| performance_schema |
9| sys |
10+--------------------+
11[root@centos8 backup]# mysql -e "select * from hellodb.teachers;"
12+-----+---------------+-----+--------+
13| TID | Name | Age | Gender |
14+-----+---------------+-----+--------+
15| 1 | Song Jiang | 45 | M |
16| 2 | Zhang Sanfeng | 94 | M |
17| 3 | Miejue Shitai | 77 | F |
18| 4 | Lin Chaoying | 93 | F |
19+-----+---------------+-----+--------+
20[root@centos8 backup]#
- 开始备份
命令代码:
1[root@centos8 ~]#xtrabackup -uroot -pmagedu --backup --target-dir=/backup/base
22)第一次修改数据
33)第一次增量备份
4[root@centos8 ~]#xtrabackup -uroot -pmagedu --backup --target-dir=/backup/inc1 --incremental-basedir=/backup/base
54)第二次修改数据
65)第二次增量
7[root@centos8 ~]#xtrabackup -uroot -pmagedu --backup --target-dir=/backup/inc2 --incremental-basedir=/backup/inc1
- 第一次完全备份:
1[root@centos8 backup]# xtrabackup --backup --target-dir=/backup/base
2[root@centos8 backup]# tree -d /backup/base/
3/backup/base/
4├── hellodb
5├── mysql
6├── performance_schema
7└── sys
8
94 directories
10[root@centos8 backup]# du -sh /backup/base/
1127M /backup/base/
12[root@centos8 backup]# du -sh /data/mysql
13135M /data/mysql
- 第一次修改数据:
1[root@centos8 backup]# mysql -e "insert hellodb.teachers (name,age,gender) values('mage',30,'M')"
2[root@centos8 backup]# mysql -e "insert hellodb.teachers (name,age,gender) values('wang',34,'M')"
3[root@centos8 backup]# mysql -e "select * from hellodb.teachers;"
4+-----+---------------+-----+--------+
5| TID | Name | Age | Gender |
6+-----+---------------+-----+--------+
7| 1 | Song Jiang | 45 | M |
8| 2 | Zhang Sanfeng | 94 | M |
9| 3 | Miejue Shitai | 77 | F |
10| 4 | Lin Chaoying | 93 | F |
11| 5 | mage | 30 | M |
12| 6 | wang | 34 | M |
13+-----+---------------+-----+--------+
14[root@centos8 backup]#
- 第一次增量备份
1[root@centos8 ~]#xtrabackup --backup --target-dir=/backup/inc1 --incremental-basedir=/backup/base
2
3[root@centos8 backup]# ls /backup/
4base inc1
5[root@centos8 backup]# tree -d /backup/inc1/
6/backup/inc1/
7├── hellodb
8├── mysql
9├── performance_schema
10└── sys
11
124 directories
13[root@centos8 backup]# du -sh /backup/*
1427M /backup/base
153.4M /backup/inc1
- 第二次修改数据
1[root@centos8 ~]# mysql -e "insert hellodb.teachers (name,age,gender) values('zhang',38,'M')"
2[root@centos8 ~]# mysql -e "insert hellodb.teachers (name,age,gender) values('guiyuan',28,'M')"
3[root@centos8 ~]# mysql -e "select * from hellodb.teachers;"
4+-----+---------------+-----+--------+
5| TID | Name | Age | Gender |
6+-----+---------------+-----+--------+
7| 1 | Song Jiang | 45 | M |
8| 2 | Zhang Sanfeng | 94 | M |
9| 3 | Miejue Shitai | 77 | F |
10| 4 | Lin Chaoying | 93 | F |
11| 5 | mage | 30 | M |
12| 6 | wang | 34 | M |
13| 7 | zhang | 38 | M |
14| 8 | guiyuan | 28 | M |
15+-----+---------------+-----+--------+
16[root@centos8 ~]#
- 第二次增量备份
1xtrabackup --backup --target-dir=/backup/inc2 --incremental-basedir=/backup/inc1
2
3[root@centos8 ~]# du -sh /backup/*
427M /backup/base
53.4M /backup/inc1
63.4M /backup/inc2
以上备份完成。
- 模拟数据库崩溃
1#先停止数据库
2[root@centos8 ~]# service mysqld stop
3Shutting down MySQL.. SUCCESS!
4[root@centos8 ~]# ls /data/mysql
5auto.cnf centos8-bin.000001 client-key.pem ibdata1 mysql private_key.pem server-key.pem xtrabackup_info
6ca-key.pem centos8-bin.index hellodb ib_logfile0 mysql.log public_key.pem sys xtrabackup_master_key_id
7ca.pem client-cert.pem ib_buffer_pool ib_logfile1 performance_schema server-cert.pem xtrabackup_binlog_pos_innodb
8
9#清空数据库目录
10[root@centos8 ~]# rm -rf /data/mysql/*
开始回滚:
- 预准备完成备份,此选项–apply-log-only 阻止回滚未完成的事务
1[root@centos8 ~]#xtrabackup --prepare --apply-log-only --target-dir=/backup/base
- 合并第1次增量备份到完全备份
1[root@centos8 ~]#xtrabackup --prepare --apply-log-only --target-dir=/backup/base --incremental-dir=/backup/inc1
- 合并第2次增量备份到完全备份:最后一次还原不需要加选项–apply-log-only
1[root@centos8 ~]#xtrabackup --prepare --target-dir=/backup/base --incremental-dir=/backup/inc2
2
3[root@centos8 ~]# du -sh /backup/*
4143M /backup/base
512M /backup/inc1
612M /backup/inc2
- 复制到数据库目录,注意数据库目录必须为空,MySQL服务不能启动
1[root@centos8 ~]# ss -ntlp|grep 3306
2[root@centos8 ~]# ps -ef|grep mysqld
3root 6499 6128 0 06:36 pts/2 00:00:00 grep --color=auto mysqld
4
5[root@centos8 ~]#xtrabackup --copy-back --target-dir=/backup/base
6
7[root@centos8 ~]# ll /data/mysql
8total 122924
9drwxr-x---. 2 root root 272 Nov 5 06:35 hellodb
10-rw-r-----. 1 root root 425 Nov 5 06:35 ib_buffer_pool
11-rw-r-----. 1 root root 12582912 Nov 5 06:35 ibdata1
12-rw-r-----. 1 root root 50331648 Nov 5 06:35 ib_logfile0
13-rw-r-----. 1 root root 50331648 Nov 5 06:35 ib_logfile1
14-rw-r-----. 1 root root 12582912 Nov 5 06:35 ibtmp1
15drwxr-x---. 2 root root 4096 Nov 5 06:35 mysql
16drwxr-x---. 2 root root 8192 Nov 5 06:35 performance_schema
17drwxr-x---. 2 root root 8192 Nov 5 06:35 sys
18-rw-r-----. 1 root root 24 Nov 5 06:35 xtrabackup_binlog_pos_innodb
19-rw-r-----. 1 root root 507 Nov 5 06:35 xtrabackup_info
20-rw-r-----. 1 root root 1 Nov 5 06:35 xtrabackup_master_key_id
21[root@centos8 ~]# du -sh /data/mysql
22135M /data/mysql
- 还原属性 & 启动服务
1[root@centos8 ~]#chown -R mysql:mysql /data/mysql
2[root@centos8 ~]# service mysqld start
3Starting MySQL.Logging to '/data/mysql/mysql.log'.
4. SUCCESS!
- 验证
1[root@centos8 ~]# mysql hellodb
2Reading table information for completion of table and column names
3You can turn off this feature to get a quicker startup with -A
4
5Welcome to the MySQL monitor. Commands end with ; or \g.
6Your MySQL connection id is 3
7Server version: 5.7.29-log MySQL Community Server (GPL)
8
9Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
10
11Oracle is a registered trademark of Oracle Corporation and/or its
12affiliates. Other names may be trademarks of their respective
13owners.
14
15Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
16
17mysql> select *from teachers;
18+-----+---------------+-----+--------+
19| TID | Name | Age | Gender |
20+-----+---------------+-----+--------+
21| 1 | Song Jiang | 45 | M |
22| 2 | Zhang Sanfeng | 94 | M |
23| 3 | Miejue Shitai | 77 | F |
24| 4 | Lin Chaoying | 93 | F |
25| 5 | mage | 30 | M |
26| 6 | wang | 34 | M |
27| 7 | zhang | 38 | M |
28| 8 | guiyuan | 28 | M |
29+-----+---------------+-----+--------+
308 rows in set (0.00 sec)
31
32mysql>
mysql数据库备份还原成功。
5.3.6 实战案例:xtrabackup单表导出和导入
不常用,本次不做测试。

1#导出
21 单表备份
3innobackupex -uroot -pmagedu --include='hellodb.students' /backup
42备份表结构
5mysql -e 'show create table hellodb.students' > student.sql
63删除表
7mysql -e 'drop table hellodb.students‘
8#导出
94 innobackupex --apply-log --export /backups/2018-02-23_15-03-23/
105 创建表
11 mysql>CREATE TABLE `students` (
12 `StuID` int(10) unsigned NOT NULL AUTO_INCREMENT,
13 `Name` varchar(50) NOT NULL,
14 `Age` tinyint(3) unsigned NOT NULL,
15 `Gender` enum('F','M') NOT NULL,
16 `ClassID` tinyint(3) unsigned DEFAULT NULL,
17 `TeacherID` int(10) unsigned DEFAULT NULL,
18 PRIMARY KEY (`StuID`)
19) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8
206 删除表空间
21alter table students discard tablespace;
227 cp /backups/2018-02-23_15-03-23/hellodb/students.{cfg,exp,ibd}
23/var/lib/mysql/hellodb/
248 chown -R mysql.mysql /var/lib/mysql/hellodb/
259 mysql>alter table students import tablespace;
6、MySQL 集群 Cluster
6.1 MySQL主从复制
6.1.1 主从复制架构和原理
6.1.1.1 服务性能扩展方式
- Scale Up,向上扩展,垂直扩展
- Scale Out,向外扩展,横向扩展
6.1.1.2 MySQL的扩展
- 读写分离
- 复制:每个节点都有相同的数据集,向外扩展,基于二进制日志的单向复制
6.1.1.3 复制的功用
- 数据分布
- 负载均衡读
- 备份
- 高可用和故障切换
- MySQL升级测试
6.1.1.4 复制架构
一主一从复制架构

一主多从复制架构

6.1.1.5 主从复制原理

主从复制相关线程
主节点:
dump Thread:为每个Slave的I/O Thread启动一个dump线程,用于向其发送binary log events
从节点:
I/O Thread:向Master请求二进制日志事件,并保存于中继日志中
SQL Thread:从中继日志中读取日志事件,在本地完成重放
跟复制功能相关的文件:
master.info:用于保存slave连接至master时的相关信息,例如账号、密码、服务器地址等
relay-log.info:保存在当前slave节点上已经复制的当前二进制日志和本地relay log日志的对应关系
mariadb-relay-bin.00000#: 中继日志,保存从主节点复制过来的二进制日志,本质就是二进制日志
范例: 中继日志
1[root@slave ~]#file /var/lib/mysql/mariadb-relay-bin.000001
2/var/lib/mysql/mariadb-relay-bin.000001: MySQL replication log, server id 18
3MySQL V5+, server version 10.3.17-MariaDB-log
4[root@slave ~]#mysqlbinlog /var/lib/mysql/mariadb-relay-bin.000001|head
5/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
6/*!40019 SET @@session.max_insert_delayed_threads=0*/;
7/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
8DELIMITER /*!*/;
9# at 4
10#200615 17:58:48 server id 18 end_log_pos 256 CRC32 0x7bd00c79 Start:
11binlog v 4, server v 10.3.17-MariaDB-log created 200615 17:58:48
12BINLOG '
13WEbnXg8cAAAA/AAAAAABAAAAAAQAMTAuMy4xNy1NYXJpYURCLWxvZwAAAAAAAAAAAAAAAAAAAAAA
14AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAA5AAEGggAAAAICAgCAAAACgoKAAAAAAAA
15AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
6.1.1.6 主从复制特点
- 异步复制
- 主从数据不一致比较常见
6.1.1.7 各种复制架构

- 一Master/一Slave
- 一主多从
- 从服务器还可以再有从服务器
- Master/Master
- 一从多主:适用于多个不同数据库
- 环状复制
复制需要考虑二进制日志事件记录格式
STATEMENT(5.0之前)
ROW(5.1之后,推荐)
MIXED
6.1.2 实现主从复制配置
参考官网
https://mariadb.com/kb/en/library/setting-up-replication/
https://dev.mysql.com/doc/refman/5.5/en/replication-configuration.html
主节点配置:
(1) 启用二进制日志
1[mysqld]
2log_bin
(2) 为当前节点设置一个全局惟一的ID号
1[mysqld]
2server-id=#
3log-basename=master #可选项,设置datadir中日志名称,确保不依赖主机名
说明:
server-id的取值范围
1 to 4294967295 (>= MariaDB 10.2.2),默认值为1
0 to 4294967295 (<= MariaDB 10.2.1),默认值为0,如果从节点为0,所有master都将拒绝此slave的连接
1[root@centos8 ~]# mysql -e 'select @@server_id'
2+-------------+
3| @@server_id |
4+-------------+
5| 1 |
6+-------------+
(3) 创建有复制权限的用户账号
1GRANT REPLICATION SLAVE ON *.* TO 'repluser'@'HOST' IDENTIFIED BY 'replpass';
(4) 查看从二进制日志的文件和位置开始进行复制
1SHOW MASTER LOG;
从节点配置:
(1) 启动中继日志
1[mysqld]
2server_id=# #为当前节点设置一个全局惟的ID号
3log-bin
4read_only=ON #设置数据库只读,针对supper user无效
5relay_log=relay-log #relay log的文件路径,默认值hostname-relay-bin
6relay_log_index=relay-log.index #默认值hostname-relay-bin.index
(2) 使用有复制权限的用户账号连接至主服务器,并启动复制线程
1CHANGE MASTER TO MASTER_HOST='masterhost',
2MASTER_USER='repluser',
3MASTER_PASSWORD='replpass',
4MASTER_LOG_FILE='mariadb-bin.xxxxxx',
5MASTER_LOG_POS=#;
6
7START SLAVE [IO_THREAD|SQL_THREAD];
8SHOW SLAVE STATUS;
范例:新建主从复制
1#主节点
2[root@master ~]#vim /etc/my.cnf.d/mariadb-server.cnf
3[mysqld]
4server-id=8
5log-bin
6[root@master ~]#systemctl restart mariadb
7[root@master ~]#mysql
8MariaDB [(none)]> grant replication slave on *.* to repluser@'192.168.8.%'
9identified by 'magedu';
10#查看二进制文件和位置
11MariaDB [(none)]> show master logs;
12+--------------------+-----------+
13| Log_name | File_size |
14+--------------------+-----------+
15| mariadb-bin.000001 | 28052 |
16| mariadb-bin.000002 | 545 |
17+--------------------+-----------+
182 rows in set (0.001 sec)
19#从节点
20[root@slave ~]#vim /etc/my.cnf.d/mariadb-server.cnf
21[mysqld]
22server-id=18
23[root@slave ~]#systemctl restart mariadb
24[root@slave1 ~]#mysql
25MariaDB [(none)]> help change master to
26MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='192.168.8.8',
27MASTER_USER='repluser', MASTER_PASSWORD='magedu', MASTER_PORT=3306,
28MASTER_LOG_FILE='mariadb-bin.000002', MASTER_LOG_POS=545;
29MariaDB [(none)]> start slave;
30Query OK, 0 rows affected, 1 warning (0.000 sec)
31
32MariaDB [(none)]> show slave status\G
33*************************** 1. row ***************************
34 Slave_IO_State: Waiting for master to send event
35 Master_Host: 192.168.8.8
36 Master_User: repluser
37 Master_Port: 3306
38 Connect_Retry: 60
39 Master_Log_File: mariadb-bin.000002
40 Read_Master_Log_Pos: 26987890
41 Relay_Log_File: mariadb-relay-bin.000002
42 Relay_Log_Pos: 26987902
43 Relay_Master_Log_File: mariadb-bin.000002
44 Slave_IO_Running: Yes
45 Slave_SQL_Running: Yes
46 Replicate_Do_DB:
47 Replicate_Ignore_DB:
48 Replicate_Do_Table:
49 Replicate_Ignore_Table:
50 Replicate_Wild_Do_Table:
51 Replicate_Wild_Ignore_Table:
52 Last_Errno: 0
53 Last_Error:
54 Skip_Counter: 0
55 Exec_Master_Log_Pos: 26987890
56 Relay_Log_Space: 26988213
57 Until_Condition: None
58 Until_Log_File:
59 Until_Log_Pos: 0
60 Master_SSL_Allowed: No
61 Master_SSL_CA_File:
62 Master_SSL_CA_Path:
63 Master_SSL_Cert:
64 Master_SSL_Cipher:
65 Master_SSL_Key:
66 Seconds_Behind_Master: 0 #复制的延迟时间
67 Master_SSL_Verify_Server_Cert: No
68 Last_IO_Errno: 0
69 Last_IO_Error:
70 Last_SQL_Errno: 0
71 Last_SQL_Error:
72 Replicate_Ignore_Server_Ids:
73 Master_Server_Id: 8
74 Master_SSL_Crl:
75 Master_SSL_Crlpath:
76 Using_Gtid: No
77 Gtid_IO_Pos:
78 Replicate_Do_Domain_Ids:
79 Replicate_Ignore_Domain_Ids:
80 Parallel_Mode: conservative
81 SQL_Delay: 0
82 SQL_Remaining_Delay: NULL
83 Slave_SQL_Running_State: Slave has read all relay log; waiting for the
84slave I/O thread to update it
85 Slave_DDL_Groups: 34
86Slave_Non_Transactional_Groups: 0
87 Slave_Transactional_Groups: 100006
881 row in set (0.000 sec)
范例:主服务器非新建时,主服务器运行一段时间后,新增从节点服务(完整)😁
如果主节点已经运行了一段时间,且有大量数据时,如何配置并启动slave节点
- 通过备份恢复数据至从服务器
- 复制起始位置为备份时,二进制日志文件及其POS
课件步骤
1#在主服务器完全备份
2[root@master ~]#mysqldump -A -F --single-transaction --master-data=1 >
3/backup/fullbackup_`date +%F_%T`.sql
4[root@master ~]#ll /backup/
5total 2988
6-rw-r--r-- 1 root root 3055918 Nov 27 17:41 fullbackup_2019-11-27_17:41:17.sql
7[root@master ~]#scp /backup/fullbackup_2019-11-27_17\:41\:17.sql
8192.168.8.11:/data/
9
10
11#建议优化主和从节点服务器的性能
12MariaDB [hellodb]> set global innodb_flush_log_at_trx_commit=2
13MariaDB [hellodb]> set global sync_binlog=0
14MariaDB [hellodb]> set global innodb_flush_log_at_trx_commit=2;
15Query OK, 0 rows affected (0.001 sec)
16MariaDB [hellodb]> show variables like 'sync_binlog';
17+---------------------+-------+
18| Variable_name | Value |
19+---------------------+-------+
20| sync_binlog | 0 |
21|---------------------+-------+
225 rows in set (0.001 sec)
23
24
25#将完全备份还原到新的从节点
26[root@slave ~]#dnf -y install mariadb-server
27[root@slave ~]#vim /etc/my.cnf.d/mariadb-server.cnf
28[mysqld]
29server-id=11
30read-only
31[root@slave ~]#systemctl restart mariadb
32#配置从节点,从完全备份的位置之后开始复制
33[root@slave ~]#grep '^CHANGE MASTER' /data/fullbackup_2019-11-27_17\:41\:17.sql
34CHANGE MASTER TO MASTER_LOG_FILE='mariadb-bin.000003', MASTER_LOG_POS=389;
35[root@slave ~]#vim /data/fullbackup_2019-11-27_17\:41\:17.sql
36CHANGE MASTER TO
37MASTER_HOST='192.168.8.10',
38MASTER_USER='repluser',
39MASTER_PASSWORD='magedu',
40MASTER_PORT=3306,
41 MASTER_LOG_FILE='mariadb-bin.000003', MASTER_LOG_POS=389;
42[root@slave ~]#mysql < /data/fullbackup_2019-11-27_17\:41\:17.sql
43[root@slave ~]#mysql
44Welcome to the MariaDB monitor. Commands end with ; or \g.
45Your MariaDB connection id is 9
46Server version: 10.3.11-MariaDB MariaDB Server
47Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
48Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
49MariaDB [(none)]> show slave status\G;
50*************************** 1. row ***************************
51 Slave_IO_State:
52 Master_Host: 192.168.8.10
53 Master_User: repluser
54 Master_Port: 3306
55 Connect_Retry: 60
56 Master_Log_File: mariadb-bin.000003
57 Read_Master_Log_Pos: 389
58 Relay_Log_File: mariadb-relay-bin.000001
59 Relay_Log_Pos: 4
60 Relay_Master_Log_File: mariadb-bin.000003
61 Slave_IO_Running: No
62 Slave_SQL_Running: No
63 Replicate_Do_DB:
64 Replicate_Ignore_DB:
65 Replicate_Do_Table:
66 Replicate_Ignore_Table:
67 Replicate_Wild_Do_Table:
68 Replicate_Wild_Ignore_Table:
69 Last_Errno: 0
70 Last_Error:
71 Skip_Counter: 0
72 Exec_Master_Log_Pos: 389
73 Relay_Log_Space: 256
74 Until_Condition: None
75 Until_Log_File:
76 Until_Log_Pos: 0
77 Master_SSL_Allowed: No
78 Master_SSL_CA_File:
79 Master_SSL_CA_Path:
80 Master_SSL_Cert:
81 Master_SSL_Cipher:
82 Master_SSL_Key:
83 Seconds_Behind_Master: NULL
84Master_SSL_Verify_Server_Cert: No
85 Last_IO_Errno: 0
86 Last_IO_Error:
87 Last_SQL_Errno: 0
88 Last_SQL_Error:
89 Replicate_Ignore_Server_Ids:
90 Master_Server_Id: 0
91 Master_SSL_Crl:
92 Master_SSL_Crlpath:
93 Using_Gtid: No
94 Gtid_IO_Pos:
95 Replicate_Do_Domain_Ids:
96 Replicate_Ignore_Domain_Ids:
97 Parallel_Mode: conservative
98 SQL_Delay: 0
99 SQL_Remaining_Delay: NULL
100 Slave_SQL_Running_State:
101 Slave_DDL_Groups: 0
102Slave_Non_Transactional_Groups: 0
103 Slave_Transactional_Groups: 0
1041 row in set (0.000 sec)
105MariaDB [(none)]> start slave;
实际测试过程
(亲自测试成功)-2024年12月6日。
环境:
centos8.1 mariadb10.3
主服务器:192.168.1.81
从服务器:192.168.1.82
- 当前主服务器已经运行了一些mysql数据了
1[root@mysql ~]# mysql -e 'select * from hellodb.teachers'
2+-----+---------------+-----+--------+
3| TID | Name | Age | Gender |
4+-----+---------------+-----+--------+
5| 1 | Song Jiang | 45 | M |
6| 2 | Zhang Sanfeng | 94 | M |
7| 3 | Miejue Shitai | 77 | F |
8| 4 | Lin Chaoying | 93 | F |
9+-----+---------------+-----+--------+
编辑主服务器配置文件
1#vim /etc/my.cnf.d/mariadb-server.cnf
2
3log_bin
4server-id=81

重启mariadb前文件如下:ls -l /var/lib/mysql/

重启mariadb后文件如下:
1systemctl restart mariadb

主要多了这2个文件。
- 查看当前二进制日志的文件和位置:
1MariaDB [(none)]> show master logs;
2+--------------------+-----------+
3| Log_name | File_size |
4+--------------------+-----------+
5| mariadb-bin.000001 | 330 |
6+--------------------+-----------+
71 row in set (0.000 sec)
8
9MariaDB [(none)]> show databases;
10+--------------------+
11| Database |
12+--------------------+
13| hellodb |
14| information_schema |
15| mysql |
16| performance_schema |
17+--------------------+
184 rows in set (0.000 sec)
19
20MariaDB [(none)]>
存在的问题,老数据该怎么办呢?

在主服务器做完全备份
- 需要做一个数据库的完全备份,然后再从后面的数据进行同步
1mkdir /backup
2
3mysqldump -A -F --single-transaction --master-data=1 > /backup/all.sql
4
5[root@mysql ~]# ll /backup/all.sql
6-rw-r--r--. 1 root root 487675 Dec 3 21:30 /backup/all.sql
7
8
9cat /backup/all.sql
10
11#也就是说从这个位置往后就是我们要同步的内容:
12CHANGE MASTER TO MASTER_LOG_FILE='mariadb-bin.000002', MASTER_LOG_POS=375;

主节点创建有复制权限的用户账号
1MariaDB [(none)]> grant replication slave on *.* to repluser@'192.168.1.%' identified by '123456';
2Query OK, 0 rows affected (0.000 sec)
3
4
5MariaDB [(none)]> show processlist;
6+----+-------------+-----------+------+---------+------+--------------------------+------------------+----------+
7| Id | User | Host | db | Command | Time | State | Info | Progress |
8+----+-------------+-----------+------+---------+------+--------------------------+------------------+----------+
9| 2 | system user | | NULL | Daemon | NULL | InnoDB purge worker | NULL | 0.000 |
10| 1 | system user | | NULL | Daemon | NULL | InnoDB purge coordinator | NULL | 0.000 |
11| 3 | system user | | NULL | Daemon | NULL | InnoDB purge worker | NULL | 0.000 |
12| 4 | system user | | NULL | Daemon | NULL | InnoDB purge worker | NULL | 0.000 |
13| 5 | system user | | NULL | Daemon | NULL | InnoDB shutdown handler | NULL | 0.000 |
14| 11 | root | localhost | NULL | Query | 0 | Init | show processlist | 0.000 |
15+----+-------------+-----------+------+---------+------+--------------------------+------------------+----------+
166 rows in set (0.000 sec)
来到从节点
此时,从节点服务器是一个干净的系统。
把主节点的all.sql给复制过来:
1[root@mysql ~]# scp /backup/all.sql root@192.168.1.82:/data
2root@192.168.1.82's password:
3all.sql 100% 476KB 67.3MB/s 00:00
4[root@mysql ~]#
- 给从服务器安装mysql:
1[root@mysql_backup ~]# dnf install mariadb-server -y
- 修改从服务器的数据库配置文件
1[root@mysql_backup ~]# vim /etc/my.cnf.d/mariadb-server.cnf
2……
3[mysqld]
4server-id=82
5
6#这里先只配置server_id,可以不用配置log-bin的
- 把数据库启动起来
1[root@mysql_backup ~]# systemctl restart mariadb
2
3[root@mysql_backup ~]# ss -ntlp|grep 3306
4LISTEN 0 80 *:3306 *:* users:(("mysqld",pid=45568,fd=22))
5[root@mysql_backup ~]#
6[root@mysql_backup ~]# mysql
7Welcome to the MariaDB monitor. Commands end with ; or \g.
8Your MariaDB connection id is 8
9Server version: 10.3.17-MariaDB MariaDB Server
10
11Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
12
13Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
14
15MariaDB [(none)]>
- 现在要把数据同步过来
—参考文档:
使用有复制权限的用户账号连接至主服务器,并启动复制线程
1CHANGE MASTER TO MASTER_HOST='masterhost',
2MASTER_USER='repluser',
3MASTER_PASSWORD='replpass',
4MASTER_LOG_FILE='mariadb-bin.xxxxxx',
5MASTER_LOG_POS=#;
6
7START SLAVE [IO_THREAD|SQL_THREAD];
8SHOW SLAVE STATUS;
查看帮助:
1MariaDB [(none)]> help change master to;
2Name: 'CHANGE MASTER TO'
3Description:
4Syntax:
5CHANGE MASTER TO option [, option] ...
6
7CHANGE MASTER TO
8 MASTER_HOST='master2.mycompany.com',
9 MASTER_USER='replication',
10 MASTER_PASSWORD='bigs3cret',
11 MASTER_PORT=3306,
12 MASTER_LOG_FILE='master2-bin.001',
13 MASTER_LOG_POS=4,
14 MASTER_CONNECT_RETRY=10;
15……
编辑all.sql文件:
1[root@mysql_backup ~]# vim /data/all.sql
2
3CHANGE MASTER TO
4MASTER_HOST='192.168.1.81',
5MASTER_USER='repluser',
6MASTER_PASSWORD='123456',
7MASTER_PORT=3306,
8MASTER_LOG_FILE='mariadb-bin.xxxxxx',
9MASTER_LOG_POS=#;

- 导入all.sql文件(恢复了数据库,并且做了数据同步操作)
1[root@mysql_backup ~]# mysql < /data/all.sql
默认是没有启动线程的:
1MariaDB [(none)]>
2MariaDB [(none)]> show processlist;
3+----+-------------+-----------+------+---------+------+--------------------------+------------------+----------+
4| Id | User | Host | db | Command | Time | State | Info | Progress |
5+----+-------------+-----------+------+---------+------+--------------------------+------------------+----------+
6| 1 | system user | | NULL | Daemon | NULL | InnoDB purge worker | NULL | 0.000 |
7| 2 | system user | | NULL | Daemon | NULL | InnoDB purge coordinator | NULL | 0.000 |
8| 3 | system user | | NULL | Daemon | NULL | InnoDB purge worker | NULL | 0.000 |
9| 4 | system user | | NULL | Daemon | NULL | InnoDB purge worker | NULL | 0.000 |
10| 5 | system user | | NULL | Daemon | NULL | InnoDB shutdown handler | NULL | 0.000 |
11| 9 | root | localhost | NULL | Query | 0 | Init | show processlist | 0.000 |
12+----+-------------+-----------+------+---------+------+--------------------------+------------------+----------+
136 rows in set (0.000 sec)
14
15MariaDB [(none)]>
- 导入完后,运行2个线程即可
1#先来看下这个状态:
2MariaDB [(none)]> show slave status\G
3*************************** 1. row ***************************
4 Slave_IO_State:
5 Master_Host: 192.168.1.81
6 Master_User: repluser
7 Master_Port: 3306
8 Connect_Retry: 60
9 Master_Log_File: mariadb-bin.000002
10 Read_Master_Log_Pos: 375
11 Relay_Log_File: mariadb-relay-bin.000001
12 Relay_Log_Pos: 4
13 Relay_Master_Log_File: mariadb-bin.000002
14 Slave_IO_Running: No
15 Slave_SQL_Running: No

这个Seconds_Behind_Master参数很重要,代表主和从之间的复制延迟的,null代表还没开始复制。(最好显示0,代表已同步了)

此时,在我们系统里已经生成了若干文件:
1[root@mysql_backup ~]# ll -t /var/lib/mysql/

- 启动2个线程:
1MariaDB [(none)]> start slave;
2Query OK, 0 rows affected (0.001 sec)
观察:
1#从节点
2MariaDB [(none)]> show slave status\G

主节点:


探讨个问题
当时在主服务器上执行这个命令后,是在数据库备份后操作的,那么问下,在从服务器上这个用户还存在吗?
1MariaDB [(none)]> grant replication slave on *.* to repluser@'192.168.1.%' identified by '123456';
2Query OK, 0 rows affected (0.000 sec)
来到从服务器上验证:
1MariaDB [(none)]> select user,host from mysql.user;
2+----------+-------------+
3| user | host |
4+----------+-------------+
5| root | 127.0.0.1 |
6| repluser | 192.168.1.% |
7| root | ::1 |
8| root | localhost |
9| root | mysql |
10+----------+-------------+
115 rows in set (0.001 sec)
可以看到,从服务器上这个用户也是存在的,为什么呢,因为数据被同步过来了。
1#主服务器
2MariaDB [(none)]> show databases;
3+--------------------+
4| Database |
5+--------------------+
6| hellodb |
7| information_schema |
8| mysql |
9| performance_schema |
10+--------------------+
114 rows in set (0.000 sec)
12
13MariaDB [(none)]>
14
15
16#从服务器
17MariaDB [(none)]> show databases;
18+--------------------+
19| Database |
20+--------------------+
21| hellodb |
22| information_schema |
23| mysql |
24| performance_schema |
25+--------------------+
264 rows in set (0.000 sec)
27
28
29#主服务器上创建db1
30MariaDB [(none)]> create database db1;
31Query OK, 1 row affected (0.000 sec)
32
33#从服务器上立马验证,会发现立马出现了db1,由此,我们实现了主从服务器的实时同步。
34MariaDB [(none)]> show databases;
35+--------------------+
36| Database |
37+--------------------+
38| db1 |
39| hellodb |
40| information_schema |
41| mysql |
42| performance_schema |
43+--------------------+
445 rows in set (0.000 sec)
45
46
47#主服务器上删除db1
48MariaDB [(none)]> drop database db1;
49Query OK, 0 rows affected (0.001 sec)
50#从服务器上立马验证,发现db1被删除了(不要想着主从复制会备份数据,所以数据库还是得备份好。)
51MariaDB [(none)]> show databases;
52+--------------------+
53| Database |
54+--------------------+
55| hellodb |
56| information_schema |
57| mysql |
58| performance_schema |
59+--------------------+
604 rows in set (0.000 sec)
如果是干净数据库
1CHANGE MASTER TO
2 MASTER_HOST='master2.mycompany.com',
3 MASTER_USER='replication',
4 MASTER_PASSWORD='bigs3cret',
5 MASTER_PORT=3306,
6 MASTER_LOG_FILE='master2-bin.001',
7 MASTER_LOG_POS=4,
8 MASTER_CONNECT_RETRY=10;
9……
10
11
12
13这个命令手工巧就好,干净的数据库不需要备份。
研究下这个东西
1#建议优化主和从节点服务器的性能
2MariaDB [hellodb]> set global innodb_flush_log_at_trx_commit=2
3MariaDB [hellodb]> set global sync_binlog=0
测试过程:
主服务器上执行:
1[root@mysql ~]# cat testlog.sql
2create table testlog (id int auto_increment primary key,name char(10),age int default 20);
3
4delimiter $$
5
6create procedure pro_testlog()
7begin
8declare i int;
9set i = 1;
10while i < 100000
11do insert into testlog(name,age) values (concat('wang',i),i);
12set i = i +1;
13end while;
14end$$
15
16delimiter ;
17
18[root@mysql ~]# mysql hellodb < testlog.sql
然后在从服务器上查看:(可以看到testlog这个表是空的)
1MariaDB [(none)]> use hellodb;
2Reading table information for completion of table and column names
3You can turn off this feature to get a quicker startup with -A
4
5Database changed
6MariaDB [hellodb]> show tables;
7+-------------------+
8| Tables_in_hellodb |
9+-------------------+
10| classes |
11| coc |
12| courses |
13| scores |
14| students |
15| teachers |
16| testlog |
17| toc |
18+-------------------+
198 rows in set (0.000 sec)
20
21MariaDB [hellodb]> select *from testlog;
22Empty set (0.000 sec)
主服务器上:
1[root@mysql ~]# mysql
2Welcome to the MariaDB monitor. Commands end with ; or \g.
3Your MariaDB connection id is 15
4Server version: 10.3.17-MariaDB-log MariaDB Server
5
6Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
7
8Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
9
10MariaDB [(none)]> use hellodb;
11Reading table information for completion of table and column names
12You can turn off this feature to get a quicker startup with -A
13
14Database changed
15MariaDB [hellodb]> select *from testlog;
16Empty set (0.000 sec)
17
18MariaDB [hellodb]>
当初手动执行这个存储过程,花费了40多s,但是有了主从复制关系后,会明显变的更慢:(2min应该是用的mysql8)
1#主服务器上执行
2call sp_testlog;
3
4MariaDB [hellodb]> call pro_testlog;
5Query OK, 99999 rows affected (25.180 sec)

花了2min才搞定:。。。(我的花费25s,老师的花费了2min)
1#这一项默认是0,已经启用了
2MariaDB [hellodb]> select @@sync_binlog;
3+---------------+
4| @@sync_binlog |
5+---------------+
6| 0 |
7+---------------+
81 row in set (0.000 sec)
9
10
11
12#这一项,写事务日志时,这个工作模式是不一样的:
13set global innodb_flush_log_at_trx_commit=2
14#vim /etc/my.cnf.d/mariadb-server.cnf
15……
16innodb_flush_log_at_trx_commit=2
17
18
19
20#这个步骤2个几点都要设置!
21#vim /etc/my.cnf.d/mariadb-server.cnf #这个步骤2个几点都要设置!
22……
23innodb_flush_log_at_trx_commit=2

然后重启主从mariadb服务:
1systemctl restart mariadb
如果遇到在从服务器上执行show slave status\G报错的话,就执行下如下命令:(或者等待60s后也可以的)
1MariaDB [(none)]> slave stop;
2MariaDB [(none)]> slave start;

来再次测试下:
主服务器:
1MariaDB [hellodb]> call pro_testlog;
2Query OK, 99999 rows affected (5.856 sec)
从服务器:

能够明显看到,本次速度耗时5s。🤣
更好的方式:
用事务的方式:(快的飞起🤣)(0.969s)
1MariaDB [hellodb]> begin;call pro_testlog;commit;
2Query OK, 0 rows affected (0.000 sec)
3
4Query OK, 99999 rows affected (0.969 sec)
5
6Query OK, 0 rows affected (0.107 sec)
7
8MariaDB [hellodb]>
如何再增加一个新的从节点
给主服务器做全量备份,然后一样的操作。
主服务器:
1[root@mysql ~]# mysqldump -A -F --single-transaction --master-data=1 > /backup/all.sql
复制文件:
1[root@mysql ~]# scp /backup/all.sql root@192.168.1.83:/data
从服务器上执行:
1#安装mariadb
2[root@mysql-backup-2 ~]# dnf install mariadb-server -y
3
4#修改配置文件
5[root@mysql-backup-2 ~]# vim /etc/my.cnf.d/mariadb-server.cnf
6[mysqld]
7log_bin
8server-id=83
9read_only
10
11#重启mariadb服务
12[root@mysql-backup-2 ~]# systemctl restart mariadb
13
14
15#打开数据库备份文件
16[root@mysql-backup-2 ~]# vim /data/all.sql
17CHANGE MASTER TO
18MASTER_HOST='192.168.1.81',
19MASTER_USER='repluser',
20MASTER_PASSWORD='123456',
21MASTER_PORT=3306,
22MASTER_LOG_FILE='mariadb-bin.000005', MASTER_LOG_POS=389;
23
24#导入数据
25[root@mysql-backup-2 ~]# mysql < /data/all.sql
26
27#验证
28[root@mysql-backup-2 ~]# mysql
29Welcome to the MariaDB monitor. Commands end with ; or \g.
30Your MariaDB connection id is 9
31Server version: 10.3.17-MariaDB MariaDB Server
32
33Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
34
35Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
36
37MariaDB [(none)]> show databases;
38+--------------------+
39| Database |
40+--------------------+
41| hellodb |
42| information_schema |
43| mysql |
44| performance_schema |
45+--------------------+
464 rows in set (0.000 sec)
47
48MariaDB [(none)]>
49
50
51
52
53#先来看下状态
54MariaDB [(none)]> show slave status\G
55*************************** 1. row ***************************
56 Slave_IO_State:
57 Master_Host: 192.168.1.81
58 Master_User: repluser
59 Master_Port: 3306
60 Connect_Retry: 60
61 Master_Log_File: mariadb-bin.000005
62 Read_Master_Log_Pos: 389
63 Relay_Log_File: mariadb-relay-bin.000001
64 Relay_Log_Pos: 4
65 Relay_Master_Log_File: mariadb-bin.000005
66 Slave_IO_Running: No #这2个线程还没启用
67 Slave_SQL_Running: No
68……
69
70
71
72#启动线程
73MariaDB [(none)]> start slave;
74Query OK, 0 rows affected (0.001 sec)
75#再次确认
76MariaDB [(none)]> show slave status\G
77*************************** 1. row ***************************
78 Slave_IO_State: Waiting for master to send event
79 Master_Host: 192.168.1.81
80 Master_User: repluser
81 Master_Port: 3306
82 Connect_Retry: 60
83 Master_Log_File: mariadb-bin.000005
84 Read_Master_Log_Pos: 389
85 Relay_Log_File: mariadb-relay-bin.000002
86 Relay_Log_Pos: 557
87 Relay_Master_Log_File: mariadb-bin.000005
88 Slave_IO_Running: Yes #ok了
89 Slave_SQL_Running: Yes
90 Replicate_Do_DB:
91 Replicate_Ignore_DB:
92 Replicate_Do_Table:
93 Replicate_Ignore_Table:
94 Replicate_Wild_Do_Table:
95 Replicate_Wild_Ignore_Table:
96 Last_Errno: 0
97 Last_Error:
98 Skip_Counter: 0
99 Exec_Master_Log_Pos: 389
100 Relay_Log_Space: 868
101 Until_Condition: None
102 Until_Log_File:
103 Until_Log_Pos: 0
104 Master_SSL_Allowed: No
105 Master_SSL_CA_File:
106 Master_SSL_CA_Path:
107 Master_SSL_Cert:
108 Master_SSL_Cipher:
109 Master_SSL_Key:
110 Seconds_Behind_Master: 0
111 Master_SSL_Verify_Server_Cert: No
112 Last_IO_Errno: 0
113 Last_IO_Error:
114 Last_SQL_Errno: 0
115 Last_SQL_Error:
116 Replicate_Ignore_Server_Ids:
117 Master_Server_Id: 81
118 Master_SSL_Crl:
119 Master_SSL_Crlpath:
120 Using_Gtid: No
121 Gtid_IO_Pos:
122 Replicate_Do_Domain_Ids:
123 Replicate_Ignore_Domain_Ids:
124 Parallel_Mode: conservative
125 SQL_Delay: 0
126 SQL_Remaining_Delay: NULL
127 Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
128 Slave_DDL_Groups: 0
129Slave_Non_Transactional_Groups: 0
130 Slave_Transactional_Groups: 0
1311 row in set (0.000 sec)
132
133MariaDB [(none)]>
134
135MariaDB [(none)]> show processlist;
136+----+-------------+-----------+------+-----------+------+-----------------------------------------------------------------------------+------------------+----------+
137| Id | User | Host | db | Command | Time | State | Info | Progress |
138+----+-------------+-----------+------+-----------+------+-----------------------------------------------------------------------------+------------------+----------+
139| 2 | system user | | NULL | Daemon | NULL | InnoDB purge worker | NULL | 0.000 |
140| 3 | system user | | NULL | Daemon | NULL | InnoDB purge worker | NULL | 0.000 |
141| 4 | system user | | NULL | Daemon | NULL | InnoDB purge worker | NULL | 0.000 |
142| 1 | system user | | NULL | Daemon | NULL | InnoDB purge coordinator | NULL | 0.000 |
143| 5 | system user | | NULL | Daemon | NULL | InnoDB shutdown handler | NULL | 0.000 |
144| 9 | root | localhost | NULL | Query | 0 | Init | show processlist | 0.000 |
145| 10 | system user | | NULL | Slave_IO | 33 | Waiting for master to send event | NULL | 0.000 |
146| 11 | system user | | NULL | Slave_SQL | 33 | Slave has read all relay log; waiting for the slave I/O thread to update it | NULL | 0.000 |
147+----+-------------+-----------+------+-----------+------+-----------------------------------------------------------------------------+------------------+----------+
1488 rows in set (0.000 sec)
149
150MariaDB [(none)]>
151
152
153
154
155#现在尝试在主服务器上新创建一个数据库
156MariaDB [(none)]> use hellodb;
157Reading table information for completion of table and column names
158You can turn off this feature to get a quicker startup with -A
159
160Database changed
161MariaDB [hellodb]> insert teachers (name,age,gender)values('mage',30,'M');
162Query OK, 1 row affected (0.000 sec)
163
164
165#再从服务器上验证
166#从服务器1
167MariaDB [(none)]> use hellodb;
168Reading table information for completion of table and column names
169You can turn off this feature to get a quicker startup with -A
170
171Database changed
172MariaDB [hellodb]> select *from hellodb.teachers;
173+-----+---------------+-----+--------+
174| TID | Name | Age | Gender |
175+-----+---------------+-----+--------+
176| 1 | Song Jiang | 45 | M |
177| 2 | Zhang Sanfeng | 94 | M |
178| 3 | Miejue Shitai | 77 | F |
179| 4 | Lin Chaoying | 93 | F |
180| 5 | mage | 30 | M |
181+-----+---------------+-----+--------+
1825 rows in set (0.000 sec)
183
184MariaDB [hellodb]>
185#从服务器2
186MariaDB [(none)]> use hellodb;
187Reading table information for completion of table and column names
188You can turn off this feature to get a quicker startup with -A
189
190Database changed
191MariaDB [hellodb]> select *from hellodb.teachers;
192+-----+---------------+-----+--------+
193| TID | Name | Age | Gender |
194+-----+---------------+-----+--------+
195| 1 | Song Jiang | 45 | M |
196| 2 | Zhang Sanfeng | 94 | M |
197| 3 | Miejue Shitai | 77 | F |
198| 4 | Lin Chaoying | 93 | F |
199| 5 | mage | 30 | M |
200+-----+---------------+-----+--------+
2015 rows in set (0.000 sec)
202
203MariaDB [hellodb]>
204#符合预期,数据已经同步过来了。
来模拟下这个场景:选举新的从为主
1在主服务器上执行这个命令:
2call pro_testlog;
3
4然后对主服务器断电,那么2个从服务器就会进行选举新的主了。

那么问题来了,82和83 2个从服务器,你提升谁成为主服务器呢?
要提升谁,就要确认谁的数据同步的最多。

这2个值数值是一样的。
那就随便了。
当然看这里的位置也行:

如何让82成为新的主呢
手工打开它的二级日志:
1[root@mysql-backup ~]# vim /etc/my.cnf.d/mariadb-server.cnf
2log-bin
3
4#并且ready-only日志开关关掉。

重启数据库服务:
1[root@mysql-backup ~]# systemctl restart mariadb
自己身上还有之前残留的从服务器信息:
1MariaDB [(none)]> show slave status\G

所以要把这个从信息去掉
关闭这2个线程:
1MariaDB [(none)]> stop slave;
2Query OK, 0 rows affected (0.001 sec)
在从节点清楚信息:
1MariaDB [(none)]> reset slave;
2Query OK, 0 rows affected (0.001 sec)
3#从服务器清除master.info ,relay-log.info, relay log ,开始新的relay log
删除后:

删除前:

要想彻底删除干净,就加个all:
1MariaDB [(none)]> reset slave all;
2Query OK, 0 rows affected (0.000 sec)
3
4MariaDB [(none)]> show slave status\G #这里的东西就没了
5Empty set (0.000 sec)

此时,它就成为一台真正的独立服务器,并不成为任何人的从了。
在另一台83从上配置信息
1#目前指向的任然是旧主
2MariaDB [(none)]> show slave status\G
3*************************** 1. row ***************************
4 Slave_IO_State: Reconnecting after a failed master event read
5 Master_Host: 192.168.1.81
6 Master_User: repluser
7 Master_Port: 3306
8 Connect_Retry: 60
9 Master_Log_File: mariadb-bin.000005
10 Read_Master_Log_Pos: 25302076
11 Relay_Log_File: mariadb-relay-bin.000002
12 Relay_Log_Pos: 25302202
13 Relay_Master_Log_File: mariadb-bin.000005
14 Slave_IO_Running: Connecting
15 Slave_SQL_Running: Yes
16 Replicate_Do_DB:
17 Replicate_Ignore_DB:
18 Replicate_Do_Table:
19 Replicate_Ignore_Table:
20 Replicate_Wild_Do_Table:
21 Replicate_Wild_Ignore_Table:
22 Last_Errno: 0
23 Last_Error:
24 Skip_Counter: 0
25 Exec_Master_Log_Pos: 25302034
26 Relay_Log_Space: 25302555
27 Until_Condition: None
28 Until_Log_File:
29 Until_Log_Pos: 0
30 Master_SSL_Allowed: No
31 Master_SSL_CA_File:
32 Master_SSL_CA_Path:
33 Master_SSL_Cert:
34 Master_SSL_Cipher:
35 Master_SSL_Key:
36 Seconds_Behind_Master: NULL
37 Master_SSL_Verify_Server_Cert: No
38 Last_IO_Errno: 2003
39 Last_IO_Error: error reconnecting to master 'repluser@192.168.1.81:3306' - retry-time: 60 maximum-retries: 86400 message: Can't connect to MySQL server on '192.168.1.81' (111 "Connection refused")
40 Last_SQL_Errno: 0
41 Last_SQL_Error:
42 Replicate_Ignore_Server_Ids:
43 Master_Server_Id: 81
44 Master_SSL_Crl:
45 Master_SSL_Crlpath:
46 Using_Gtid: No
47 Gtid_IO_Pos:
48 Replicate_Do_Domain_Ids:
49 Replicate_Ignore_Domain_Ids:
50 Parallel_Mode: conservative
51 SQL_Delay: 0
52 SQL_Remaining_Delay: NULL
53 Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
54 Slave_DDL_Groups: 0
55Slave_Non_Transactional_Groups: 0
56 Slave_Transactional_Groups: 92424
571 row in set (0.000 sec)
如何改变他的新主人,将82作为他的新主人
1#关闭2个线程
2MariaDB [(none)]> stop slave;
3Query OK, 0 rows affected (0.001 sec)
4MariaDB [(none)]> show slave status\G
5*************************** 1. row ***************************
6 Slave_IO_State:
7 Master_Host: 192.168.1.81
8 Master_User: repluser
9 Master_Port: 3306
10 Connect_Retry: 60
11 Master_Log_File: mariadb-bin.000005
12 Read_Master_Log_Pos: 25302076
13 Relay_Log_File: mariadb-relay-bin.000002
14 Relay_Log_Pos: 25302202
15 Relay_Master_Log_File: mariadb-bin.000005
16 Slave_IO_Running: No
17 Slave_SQL_Running: No
18
19
20
21#把刚才的同步信息清理掉
22MariaDB [(none)]> reset slave all;
23Query OK, 0 rows affected (0.002 sec)
24
25MariaDB [(none)]> show slave status\G
26Empty set (0.000 sec)
27
28
29
30#重新建立新的主关系
31本身我们看到那个数据位置是一样的,那么这里就不做复制了。(否则是要备份复制数据的)
32要指定复制的账号和位置;
33复制的账号之前已经复制过来了;
34MariaDB [(none)]> select user,host from mysql.user;
35+----------+-------------+
36| user | host |
37+----------+-------------+
38| root | 127.0.0.1 |
39| repluser | 192.168.1.% |
40| root | ::1 |
41| root | localhost |
42| root | mysql |
43+----------+-------------+
445 rows in set (0.000 sec)
45
46
47MariaDB [(none)]> show master logs;
48+--------------------+-----------+
49| Log_name | File_size |
50+--------------------+-----------+
51| mariadb-bin.000001 | 28210 |
52| mariadb-bin.000002 | 493926 |
53| mariadb-bin.000003 | 412 |
54| mariadb-bin.000004 | 367 |
55| mariadb-bin.000005 | 367 |
56| mariadb-bin.000006 | 367 |
57| mariadb-bin.000007 | 344 |
58+--------------------+-----------+
597 rows in set (0.000 sec)
60
61
62
63#在83上使用复制信息
64CHANGE MASTER TO
65MASTER_HOST='192.168.1.82',
66MASTER_USER='repluser',
67MASTER_PASSWORD='123456',
68MASTER_PORT=3306,
69MASTER_LOG_FILE='mariadb-bin.000007',
70MASTER_LOG_POS=344;
71
72MariaDB [(none)]> CHANGE MASTER TO
73 -> MASTER_HOST='192.168.1.82',
74 -> MASTER_USER='repluser',
75 -> MASTER_PASSWORD='123456',
76 -> MASTER_PORT=3306,
77 -> MASTER_LOG_FILE='mariadb-bin.000007',
78 -> MASTER_LOG_POS=344;
79Query OK, 0 rows affected (0.016 sec)
80
81
82
83
84#启用2个线程
85MariaDB [(none)]> start slave;
86Query OK, 0 rows affected (0.001 sec)
87
88
89
90#查看下
91MariaDB [(none)]> show slave status\G
92*************************** 1. row ***************************
93 Slave_IO_State: Waiting for master to send event
94 Master_Host: 192.168.1.82
95 Master_User: repluser
96 Master_Port: 3306
97 Connect_Retry: 60
98 Master_Log_File: mariadb-bin.000007
99 Read_Master_Log_Pos: 344
100 Relay_Log_File: mariadb-relay-bin.000002
101 Relay_Log_Pos: 557
102 Relay_Master_Log_File: mariadb-bin.000007
103 Slave_IO_Running: Yes
104 Slave_SQL_Running: Yes
验证下:
1#82主服务器上创建db2
2MariaDB [(none)]> create database db2;
3Query OK, 1 row affected (0.000 sec)
4
5
6#83从服务器上确认(符合预期)
7MariaDB [(none)]> show databases;
8+--------------------+
9| Database |
10+--------------------+
11| db2 |
12| hellodb |
13| information_schema |
14| mysql |
15| performance_schema |
16+--------------------+
175 rows in set (0.000 sec)
以上,新主就提升好了。
这种方法理论可行,但实际上实施起来可行新很差。
好像有些麻烦哈,哈哈哈。。。。
那么有没有什么更简洁的方式呢???
mha–自动提升。
The end。
6.1.3 主从复制相关
1、限制从服务器为只读
1read_only=ON
2#注意:此限制对拥有SUPER权限的用户均无效
3
4
5##配置过程
6vim /etc/my.cnf.d/mariadb-server.cnf
7[mysqld]
8……
9read_only
10
11systemctl restart mariadb
12
13MariaDB [(none)]> select @@read_only;
14+-------------+
15| @@read_only |
16+-------------+
17| 1 |
18+-------------+
191 row in set (0.000 sec)
注意:以下命令会阻止所有用户, 包括主服务器复制的更新
1FLUSH TABLES WITH READ LOCK;
2、在从节点清除信息
注意:以下都需要先 STOP SLAVE
1RESET SLAVE #从服务器清除master.info ,relay-log.info, relay log ,开始新的relay log
2RESET SLAVE ALL #清除所有从服务器上设置的主服务器同步信息,如HOST,PORT, USER和
3PASSWORD 等
6.1.5 主主复制
主主复制:两个节点,都可以更新数据,并且互为主从
容易产生的问题:数据不一致;因此慎用
考虑要点:自动增长id
配置一个节点使用奇数id
1auto_increment_offset=1 #开始点
2auto_increment_increment=2 #增长幅度
另一个节点使用偶数id
1auto_increment_offset=2
2auto_increment_increment=2
主主复制的配置步骤:
(1) 各节点使用一个惟一server_id
(2) 都启动binary log和relay log
(3) 创建拥有复制权限的用户账号
(4) 定义自动增长id字段的数值范围各为奇偶
(5) 均把对方指定为主节点,并启动复制线程
文档步骤
范例:实现两个节点的主主复制模型
1#在第一个master节点上实现
2[root@master1 ~]#vim /etc/my.cnf.d/mariadb-server.cnf
3[mysqld]
4server-id=8
5log-bin
6auto_increment_offset=1 #开始点
7auto_increment_increment=2 #增长幅度
8
9[root@master1 ~]#systemctl start mariadb
10[root@master1 ~]#mysql
11MariaDB [(none)]>show master logs;
12+--------------------+-----------+
13| Log_name | File_size |
14+--------------------+-----------+
15| mariadb-bin.000001 | 28303 |
16| mariadb-bin.000002 | 386 |
17+--------------------+-----------+
182 rows in set (0.000 sec)
19
20
21MariaDB [(none)]> grant replication slave on *.* to repluser@'192.168.100.%'
22identified by 'magedu';
23
24
25
26
27#在第二个master节点上实现
28[rootmaster2 ~]#vim /etc/my.cnf.d/mariadb-server.cnf
29[mysqld]
30server-id=18
31log-bin
32auto_increment_offset=2 #开始点
33auto_increment_increment=2 #增长幅度
34[root@master2 ~]#systemctl start mariadb
35
36[root@master2 ~]#mysql
37MariaDB [(none)]> CHANGE MASTER TO
38 -> MASTER_HOST='192.168.100.8',
39 -> MASTER_USER='repluser',
40 -> MASTER_PASSWORD='magedu',
41 -> MASTER_PORT=3306,
42 -> MASTER_LOG_FILE='mariadb-bin.000002',
43 -> MASTER_LOG_POS=386;
44Query OK, 0 rows affected (0.019 sec)
45MariaDB [(none)]> start slave;
46Query OK, 0 rows affected (0.003 sec)
47MariaDB [(none)]> show master logs; #查看二进制位置
48+--------------------+-----------+
49| Log_name | File_size |
50+--------------------+-----------+
51| mariadb-bin.000001 | 28303 |
52| mariadb-bin.000002 | 344 |
53+--------------------+-----------+
542 rows in set (0.001 sec)
55
56
57
58
59#在第一个master节点上实现
60MariaDB [(none)]> CHANGE MASTER TO
61 -> MASTER_HOST='192.168.100.18',
62 -> MASTER_USER='repluser',
63 -> MASTER_PASSWORD='magedu',
64 -> MASTER_PORT=3306,
65 -> MASTER_LOG_FILE='mariadb-bin.000002',
66 -> MASTER_LOG_POS=344;
67Query OK, 0 rows affected (0.007 sec)
68MariaDB [(none)]> start slave;
69Query OK, 0 rows affected (0.002 sec)
70MariaDB [db1]> create table t1(id int auto_increment primary key,name char(10));
71
72
73#两个节点分别插入数据
74#在第一个节点上执行
75MariaDB [db1]> create database db1;
76MariaDB [db1]> insert t1 (name) values('user1');
77#在第二个节点上执行
78MariaDB [db1]> insert t1 (name) values('user2');
79#两个节点同时插入数据
80MariaDB [db1]> insert t1 (name) values('userX');
81MariaDB [db1]> select * from t1;
82+----+-------+
83| id | name |
84+----+-------+
85| 1 | user1 |
86| 2 | user2 |
87| 3 | userX |
88| 4 | userX |
89+----+-------+
904 rows in set (0.001 sec)
91
92
93
94
95
96#两个节点同时创建数据库,发生复制冲突
97MariaDB [db1]> create database db2;
98MariaDB [db1]> show slave status\G
99*************************** 1. row ***************************
100 Slave_IO_State: Waiting for master to send event
101 Master_Host: 192.168.100.18
102 Master_User: repluser
103 Master_Port: 3306
104 Connect_Retry: 60
105 Master_Log_File: mariadb-bin.000002
106 Read_Master_Log_Pos: 1029
107 Relay_Log_File: mariadb-relay-bin.000002
108 Relay_Log_Pos: 1110
109 Relay_Master_Log_File: mariadb-bin.000002
110 Slave_IO_Running: Yes
111 Slave_SQL_Running: No
112 Replicate_Do_DB:
113 Replicate_Ignore_DB:
114 Replicate_Do_Table:
115 Replicate_Ignore_Table:
116 Replicate_Wild_Do_Table:
117 Replicate_Wild_Ignore_Table:
118 Last_Errno: 1007
119 Last_Error: Error 'Can't create database 'db2'; database
120exists' on query. Default database: 'db2'. Query: 'create database db2'
121 Skip_Counter: 0
122 Exec_Master_Log_Pos: 897
123 Relay_Log_Space: 1553
124 Until_Condition: None
125 Until_Log_File:
126 Until_Log_Pos: 0
127 Master_SSL_Allowed: No
128 Master_SSL_CA_File:
129 Master_SSL_CA_Path:
130 Master_SSL_Cert:
131 Master_SSL_Cipher:
132 Master_SSL_Key:
133 Seconds_Behind_Master: NULL
134Master_SSL_Verify_Server_Cert: No
135 Last_IO_Errno: 0
136 Last_IO_Error:
137 Last_SQL_Errno: 1007
138 Last_SQL_Error: Error 'Can't create database 'db2'; database
139exists' on query. Default database: 'db2'. Query: 'create database db2'
140 Replicate_Ignore_Server_Ids:
141 Master_Server_Id: 18
142 Master_SSL_Crl:
143 Master_SSL_Crlpath:
144 Using_Gtid: No
145 Gtid_IO_Pos:
146 Replicate_Do_Domain_Ids:
147 Replicate_Ignore_Domain_Ids:
148 Parallel_Mode: conservative
149 SQL_Delay: 0
150 SQL_Remaining_Delay: NULL
151 Slave_SQL_Running_State:
152 Slave_DDL_Groups: 2
153Slave_Non_Transactional_Groups: 0
154 Slave_Transactional_Groups: 2
1551 row in set (0.003 sec)
范例:主主复制(测试成功)-2024.12.8
自己测试过程
以下将测试主-主 mysql情况。
- 修改2台主机名称,方便区分:
1192.168.1.81 master1
2192.168.1.82 master2
3
4#都是centos8环境
5CentOS Linux release 8.1.1911 (Core)
610.3.17-MariaDB MariaDB Server
- 这里的主主配置和单主配置是类似的
主主复制可能存在主键冲突问题。
- 保持2台服务器为干净数据
1rm -rf /var/lib/mysql/
2dnf remove -y mariadb-server
3dnf install -y mariadb-server
4systemctl enable --now mariadb
在第一个master节点上实现
1[root@master1 ~]# vim /etc/my.cnf.d/mariadb-server.cnf
2[mysqld]
3server-id=81
4log-bin
5auto_increment_offset=1
6auto_increment_increment=2
7
8
9#关键数据就2行,哪个自动增长其实加和不加都不是必须得,这里是为了看效果加上的。(实际工作里,另一个主是当从来用的)
10
11
12#重启数据库
13[root@master1 ~]# systemctl restart mariadb
14
15
16
17#创建个授权账号
18MariaDB [(none)]> grant replication slave on *.* to repluser@'192.168.1.%' identified by '123456';
19Query OK, 0 rows affected (0.000 sec)
20
21#看下位置
22MariaDB [(none)]> show master logs;
23+--------------------+-----------+
24| Log_name | File_size |
25+--------------------+-----------+
26| mariadb-bin.000001 | 585 |
27| mariadb-bin.000002 | 389 | #这里
28+--------------------+-----------+
292 rows in set (0.000 sec)
30
31
32#备份数据
33[root@master1 ~]# mysqldump -A -F --single-transaction --master-data=1 > /data/all-`date +%F`.sql
34[root@master1 ~]# ll /data/all-2024-12-07.sql
35-rw-r--r--. 1 root root 487922 Dec 7 11:01 /data/all-2024-12-07.sql
36
37
38#拷贝备份文件到master2
39[root@master1 ~]# scp /data/all-2024-12-07.sql root@192.168.1.82:/data
40root@192.168.1.82's password:
41all-2024-12-07.sql 100% 476KB 64.7MB/s 00:00
42[root@master1 ~]#
在第二个master节点上实现
1#修改配置文件
2[root@master1 ~]# vim /etc/my.cnf.d/mariadb-server.cnf
3[mysqld]
4server-id=82
5log-bin
6auto_increment_offset=2
7auto_increment_increment=2
8
9#这个主节点也是必须要启用二进制日志的。
10
11
12#重启数据库服务
13[root@master2 ~]# systemctl restart mariadb
14
15
16
17#编辑刚才复制过来的二进制日志文件
18[root@master2 ~]# vim /data/all-2024-12-07.sql
19MASTER_HOST='192.168.1.81',
20MASTER_USER='repluser',
21MASTER_PASSWORD='123456',
22MASTER_PORT=3306,
23
24
25CHANGE MASTER TO
26MASTER_HOST='192.168.1.81',
27MASTER_USER='repluser',
28MASTER_PASSWORD='123456',
29MASTER_PORT=3306,
30MASTER_LOG_FILE='mariadb-bin.000003', MASTER_LOG_POS=389;
31
32#复制的位置是自动生成的。
33
34
35
36#但此时的导入可能会有一个缺点,可能会生成大量的二级日志
37#因此,可以考虑先进入暂时关闭二级日志
38MariaDB [(none)]> set sql_log_bin=0;
39Query OK, 0 rows affected (0.000 sec)
40
41MariaDB [(none)]> show master logs;
42+--------------------+-----------+
43| Log_name | File_size |
44+--------------------+-----------+
45| mariadb-bin.000001 | 330 |
46+--------------------+-----------+
471 row in set (0.000 sec)
48
49MariaDB [(none)]> source /data/all-2024-12-07.sql
50MariaDB [mysql]> set sql_log_bin=1;
51Query OK, 0 rows affected (0.000 sec)
52
53
54
55MariaDB [mysql]> show databases;
56+--------------------+
57| Database |
58+--------------------+
59| hellodb |
60| information_schema |
61| mysql |
62| performance_schema |
63+--------------------+
644 rows in set (0.000 sec)
65
66MariaDB [mysql]>
67#到此,数据库是还原过来了。
68
69
70
71
72
73#因为之前master1备份是在创建账号之后做的,因此master2上这个复制账号也是存在的
74MariaDB [mysql]> select u
75+----------+-------------
76| user | host
77+----------+-------------
78| root | 127.0.0.1
79| repluser | 192.168.1.%
80| root | ::1
81| root | localhost
82| root | master1
83+----------+-------------
845 rows in set (0.000 sec)
85
86
87#开启复制线程
88MariaDB [mysql]> show slave status\G
89*************************** 1. row ***************************
90 Slave_IO_State:
91 Master_Host: 192.168.1.81
92 Master_User: repluser
93 Master_Port: 3306
94 Connect_Retry: 60
95 Master_Log_File: mariadb-bin.000003
96 Read_Master_Log_Pos: 389
97 Relay_Log_File: mariadb-relay-bin.000001
98 Relay_Log_Pos: 4
99 Relay_Master_Log_File: mariadb-bin.000003
100 Slave_IO_Running: No
101 Slave_SQL_Running: No
102
103MariaDB [mysql]> start slave;
104Query OK, 0 rows affected (0.001 sec)
105
106MariaDB [mysql]> show slave status\G
107*************************** 1. row ***************************
108 Slave_IO_State: Waiting for master to send event
109 Master_Host: 192.168.1.81
110 Master_User: repluser
111 Master_Port: 3306
112 Connect_Retry: 60
113 Master_Log_File: mariadb-bin.000003
114 Read_Master_Log_Pos: 389
115 Relay_Log_File: mariadb-relay-bin.000002
116 Relay_Log_Pos: 557
117 Relay_Master_Log_File: mariadb-bin.000003
118 Slave_IO_Running: Yes
119 Slave_SQL_Running: Yes
120#到此,我们实现了单向的复制(master1-->mater2)
121
122
123#再次确认这个要复制的位置
124#master2
125MariaDB [mysql]> show master logs;
126+--------------------+-----------+
127| Log_name | File_size |
128+--------------------+-----------+
129| mariadb-bin.000001 | 330 |
130+--------------------+-----------+
1311 row in set (0.000 sec)
132
133
134
135
136#先测试下单向复制成功么?
137#在master1上创建数据库db1
138MariaDB [(none)]> create database db1;
139Query OK, 1 row affected (0.001 sec)
140
141MariaDB [(none)]> show databases;
142+--------------------+
143| Database |
144+--------------------+
145| db1 |
146| hellodb |
147| information_schema |
148| mysql |
149| performance_schema |
150+--------------------+
1515 rows in set (0.000 sec)
152
153#在maste2上确认
154MariaDB [mysql]> show master logs;
155+--------------------+-----------+
156| Log_name | File_size |
157+--------------------+-----------+
158| mariadb-bin.000001 | 330 |
159+--------------------+-----------+
1601 row in set (0.000 sec)
161
162MariaDB [mysql]>
163MariaDB [mysql]>
164MariaDB [mysql]> show databases;
165+--------------------+
166| Database |
167+--------------------+
168| db1 |
169| hellodb |
170| information_schema |
171| mysql |
172| performance_schema |
173+--------------------+
1745 rows in set (0.000 sec)
175
176MariaDB [mysql]> show master logs;
177+--------------------+-----------+
178| Log_name | File_size |
179+--------------------+-----------+
180| mariadb-bin.000001 | 330 |
181+--------------------+-----------+
1821 row in set (0.000 sec)
183
184MariaDB [mysql]>
185##但是,发现了一个神奇的现象,就是master2这里有数据同步过来了,但是二级日志没发生变化,这是为什么呢?
186数据库复制的时候,是利用了3个线程来实现的。
187我的二级日志没有增长,但是我的数据库却增长过来了。

我的二级日志文件只记录本机收到的对数据库的操作,从relay log里传来的东西不进行记录!
继续配置
在master1上执行
在master2上查看下内容,并编辑代码:
1#master2
2MariaDB [(none)]> show master logs;
3+--------------------+-----------+
4| Log_name | File_size |
5+--------------------+-----------+
6| mariadb-bin.000001 | 330 |
7+--------------------+-----------+
81 row in set (0.000 sec)
9
10
11#编辑好的内容
12CHANGE MASTER TO
13MASTER_HOST='192.168.1.82',
14MASTER_USER='repluser',
15MASTER_PASSWORD='123456',
16MASTER_PORT=3306,
17MASTER_LOG_FILE='mariadb-bin.000001',
18MASTER_LOG_POS=330;
先来master1上查看下:
1#目前自己是个纯纯的主
2MariaDB [(none)]> show slave status\G
3Empty set (0.000 sec)
4
5MariaDB [(none)]> show master logs;
6+--------------------+-----------+
7| Log_name | File_size |
8+--------------------+-----------+
9| mariadb-bin.000001 | 585 |
10| mariadb-bin.000002 | 438 |
11| mariadb-bin.000003 | 521 |
12+--------------------+-----------+
133 rows in set (0.000 sec)
在master1上执行:
1CHANGE MASTER TO
2MASTER_HOST='192.168.1.82',
3MASTER_USER='repluser',
4MASTER_PASSWORD='123456',
5MASTER_PORT=3306,
6MASTER_LOG_FILE='mariadb-bin.000001',
7MASTER_LOG_POS=330;
8
9MariaDB [(none)]> CHANGE MASTER TO
10 -> MASTER_HOST='192.168.1.82',
11 -> MASTER_USER='repluser',
12 -> MASTER_PASSWORD='123456',
13 -> MASTER_PORT=3306,
14 -> MASTER_LOG_FILE='mariadb-bin.000001',
15 -> MASTER_LOG_POS=330;
16Query OK, 0 rows affected (0.003 sec)
17
18
19#开启2个线程
20MariaDB [(none)]> start slave;
21Query OK, 0 rows affected (0.014 sec)
验证下:
1MariaDB [(none)]> show slave status\G
2*************************** 1. row ***************************
3 Slave_IO_State: Connecting to master
4 Master_Host: 192.168.1.82
5 Master_User: repluser
6 Master_Port: 3306
7 Connect_Retry: 60
8 Master_Log_File: mariadb-bin.000001
9 Read_Master_Log_Pos: 330
10 Relay_Log_File: mariadb-relay-bin.000001
11 Relay_Log_Pos: 4
12 Relay_Master_Log_File: mariadb-bin.000001
13 Slave_IO_Running: Connecting
14 Slave_SQL_Running: Yes
15 Replicate_Do_DB:
16 Replicate_Ignore_DB:
17 Replicate_Do_Table:
18 Replicate_Ignore_Table:
19 Replicate_Wild_Do_Table:
20 Replicate_Wild_Ignore_Table:
21 Last_Errno: 0
22 Last_Error:
23 Skip_Counter: 0
24 Exec_Master_Log_Pos: 330
25 Relay_Log_Space: 256
26 Until_Condition: None
27 Until_Log_File:
28 Until_Log_Pos: 0
29 Master_SSL_Allowed: No
30 Master_SSL_CA_File:
31 Master_SSL_CA_Path:
32 Master_SSL_Cert:
33 Master_SSL_Cipher:
34 Master_SSL_Key:
35 Seconds_Behind_Master: NULL
36 Master_SSL_Verify_Server_Cert: No
37 Last_IO_Errno: 2013
38 Last_IO_Error: error connecting to master 'repluser@192.168.1.82:3306' - retry-time: 60 maximum-retries: 86400 message: Lost connection to MySQL server at 'reading initial communication packet', system error: 0 "Internal error/check (Not system error)"
39 Last_SQL_Errno: 0
40 Last_SQL_Error:
41 Replicate_Ignore_Server_Ids:
42 Master_Server_Id: 0
43 Master_SSL_Crl:
44 Master_SSL_Crlpath:
45 Using_Gtid: No
46 Gtid_IO_Pos:
47 Replicate_Do_Domain_Ids:
48 Replicate_Ignore_Domain_Ids:
49 Parallel_Mode: conservative
50 SQL_Delay: 0
51 SQL_Remaining_Delay: NULL
52 Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
53 Slave_DDL_Groups: 0
54Slave_Non_Transactional_Groups: 0
55 Slave_Transactional_Groups: 0
561 row in set (0.000 sec)
57
58MariaDB [(none)]>
咦,报错了。。。
可能还是数据库两边复制不同步导致的。🤣
重新再把数据库重新备份下:
master1:
1MariaDB [(none)]> show master logs;
2+--------------------+-----------+
3| Log_name | File_size |
4+--------------------+-----------+
5| mariadb-bin.000001 | 585 |
6| mariadb-bin.000002 | 438 |
7| mariadb-bin.000003 | 653 |
8+--------------------+-----------+
93 rows in set (0.000 sec)
10
11
12
13#重新备份下数据库:
14[root@master1 ~]# mysqldump -A -F --single-transaction --master-data=1 > /data/all-`date +%F`.sql
15[root@master1 ~]# scp /data/all-2024-12-08.sql root@192.168.1.82:/data
16root@192.168.1.82's password:
17all-2024-12-08.sql 100% 477KB 104.8MB/s 00:00
18[root@master1 ~]#
在master2上重新还原下:
1[root@master2 ~]# mysql
2Welcome to the MariaDB monitor. Commands end with ; or \g.
3Your MariaDB connection id is 22
4Server version: 10.3.17-MariaDB-log MariaDB Server
5
6Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
7
8Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
9
10#先停掉二级日志
11MariaDB [(none)]> set sql_log_bin=0;
12Query OK, 0 rows affected (0.000 sec)
13
14
15
16#把刚复制过来的文件恢复下
17MariaDB [(none)]> source /data/all-2024-12-08.sql
18
19
20MariaDB [mysql]> show master logs;
21+--------------------+-----------+
22| Log_name | File_size |
23+--------------------+-----------+
24| mariadb-bin.000001 | 330 |
25+--------------------+-----------+
261 row in set (0.000 sec)
27
28MariaDB [mysql]> set sql_log_bin=1;
29Query OK, 0 rows affected (0.000 sec)
30
31
32#数据库重新启动下
33[root@master2 ~]# systemctl restart mariadb
34#我们重新再来一遍,把这个数据库彻底还原下
35[root@master2 ~]# mysql
36Welcome to the MariaDB monitor. Commands end with ; or \g.
37Your MariaDB connection id is 13
38Server version: 10.3.17-MariaDB-log MariaDB Server
39
40Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
41
42Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
43
44MariaDB [(none)]> set sql_log_bin=0;
45Query OK, 0 rows affected (0.000 sec)
46
47MariaDB [(none)]> source /data/all-2024-12-08.sql
48
49
50MariaDB [mysql]> show master logs;
51+--------------------+-----------+
52| Log_name | File_size |
53+--------------------+-----------+
54| mariadb-bin.000001 | 353 |
55| mariadb-bin.000002 | 330 |
56+--------------------+-----------+
572 rows in set (0.000 sec)
58
59MariaDB [mysql]> set sql_log_bin=1;
60Query OK, 0 rows affected (0.000 sec)
61#此时,两边的数据库是一模一样的了。
62
63
64
65
66
67
68#master2
69MariaDB [mysql]> show slave status\G
70*************************** 1. row ***************************
71 Slave_IO_State: Waiting for master to send event
72 Master_Host: 192.168.1.81
73 Master_User: repluser
74 Master_Port: 3306
75 Connect_Retry: 60
76 Master_Log_File: mariadb-bin.000004
77 Read_Master_Log_Pos: 389
78 Relay_Log_File: mariadb-relay-bin.000006
79 Relay_Log_Pos: 557
80 Relay_Master_Log_File: mariadb-bin.000004
81 Slave_IO_Running: Yes
82 Slave_SQL_Running: Yes
83 Replicate_Do_DB:
84 Replicate_Ignore_DB:
85 Replicate_Do_Table:
86 Replicate_Ignore_Table:
87 Replicate_Wild_Do_Table:
88 Replicate_Wild_Ignore_Table:
89 Last_Errno: 0
90 Last_Error:
91 Skip_Counter: 0
92 Exec_Master_Log_Pos: 389
93 Relay_Log_Space: 868
94 Until_Condition: None
95 Until_Log_File:
96 Until_Log_Pos: 0
97 Master_SSL_Allowed: No
98 Master_SSL_CA_File:
99 Master_SSL_CA_Path:
100 Master_SSL_Cert:
101 Master_SSL_Cipher:
102 Master_SSL_Key:
103 Seconds_Behind_Master: 0
104 Master_SSL_Verify_Server_Cert: No
105 Last_IO_Errno: 0
106 Last_IO_Error:
107 Last_SQL_Errno: 0
108 Last_SQL_Error:
109 Replicate_Ignore_Server_Ids:
110 Master_Server_Id: 81
111 Master_SSL_Crl:
112 Master_SSL_Crlpath:
113 Using_Gtid: No
114 Gtid_IO_Pos:
115 Replicate_Do_Domain_Ids:
116 Replicate_Ignore_Domain_Ids:
117 Parallel_Mode: conservative
118 SQL_Delay: 0
119 SQL_Remaining_Delay: NULL
120 Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
121 Slave_DDL_Groups: 0
122Slave_Non_Transactional_Groups: 0
123 Slave_Transactional_Groups: 0
1241 row in set (0.000 sec)
125
126MariaDB [mysql]>
127
128
129#master1
130MariaDB [(none)]> show master logs;
131+--------------------+-----------+
132| Log_name | File_size |
133+--------------------+-----------+
134| mariadb-bin.000001 | 585 |
135| mariadb-bin.000002 | 438 |
136| mariadb-bin.000003 | 702 |
137| mariadb-bin.000004 | 389 |
138+--------------------+-----------+
1394 rows in set (0.000 sec)
在master2上操作:
1MariaDB [(none)]> show master logs;
2+--------------------+-----------+
3| Log_name | File_size |
4+--------------------+-----------+
5| mariadb-bin.000001 | 585 |
6| mariadb-bin.000002 | 438 |
7| mariadb-bin.000003 | 702 |
8| mariadb-bin.000004 | 389 |
9+--------------------+-----------+
104 rows in set (0.000 sec)
11
12MariaDB [(none)]> show slave status\G
13*************************** 1. row ***************************
14 Slave_IO_State: Waiting for master to send event
15 Master_Host: 192.168.1.82
16 Master_User: repluser
17 Master_Port: 3306
18 Connect_Retry: 60
19 Master_Log_File: mariadb-bin.000002
20 Read_Master_Log_Pos: 330
21 Relay_Log_File: mariadb-relay-bin.000004
22 Relay_Log_Pos: 631
23 Relay_Master_Log_File: mariadb-bin.000002
24 Slave_IO_Running: Yes
25 Slave_SQL_Running: Yes
26 Replicate_Do_DB:
27 Replicate_Ignore_DB:
28 Replicate_Do_Table:
29 Replicate_Ignore_Table:
30 Replicate_Wild_Do_Table:
31 Replicate_Wild_Ignore_Table:
32 Last_Errno: 0
33 Last_Error:
34 Skip_Counter: 0
35 Exec_Master_Log_Pos: 330
36 Relay_Log_Space: 1243
37 Until_Condition: None
38 Until_Log_File:
39 Until_Log_Pos: 0
40 Master_SSL_Allowed: No
41 Master_SSL_CA_File:
42 Master_SSL_CA_Path:
43 Master_SSL_Cert:
44 Master_SSL_Cipher:
45 Master_SSL_Key:
46 Seconds_Behind_Master: 0
47 Master_SSL_Verify_Server_Cert: No
48 Last_IO_Errno: 0
49 Last_IO_Error:
50 Last_SQL_Errno: 0
51 Last_SQL_Error:
52 Replicate_Ignore_Server_Ids:
53 Master_Server_Id: 82
54 Master_SSL_Crl:
55 Master_SSL_Crlpath:
56 Using_Gtid: No
57 Gtid_IO_Pos:
58 Replicate_Do_Domain_Ids:
59 Replicate_Ignore_Domain_Ids:
60 Parallel_Mode: conservative
61 SQL_Delay: 0
62 SQL_Remaining_Delay: NULL
63 Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
64 Slave_DDL_Groups: 0
65Slave_Non_Transactional_Groups: 0
66 Slave_Transactional_Groups: 0
671 row in set (0.000 sec)
68
69MariaDB [(none)]>
我这里好了,老师的还有问题。
我跟着老师重新再做下:
1#master1。停服务器,删除配置信息
2MariaDB [(none)]> stop slave;
3Query OK, 0 rows affected (0.001 sec)
4
5MariaDB [(none)]> reset slave all;
6Query OK, 0 rows affected (0.000 sec)
7
8MariaDB [(none)]> show slave status\G
9Empty set (0.000 sec)
10
11
12
13
14#重新建立复制关系
15CHANGE MASTER TO
16MASTER_HOST='192.168.1.82',
17MASTER_USER='repluser',
18MASTER_PASSWORD='123456',
19MASTER_PORT=3306,
20MASTER_LOG_FILE='mariadb-bin.000002',
21MASTER_LOG_POS=330;
22
23MariaDB [(none)]> CHANGE MASTER TO
24 -> MASTER_HOST='192.168.1.82',
25 -> MASTER_USER='repluser',
26 -> MASTER_PASSWORD='123456',
27 -> MASTER_PORT=3306,
28 -> MASTER_LOG_FILE='mariadb-bin.000002',
29 -> MASTER_LOG_POS=330;
30Query OK, 0 rows affected (0.003 sec)
31
32MariaDB [(none)]> show slave status\G
33*************************** 1. row ***************************
34 Slave_IO_State:
35 Master_Host: 192.168.1.82
36 Master_User: repluser
37 Master_Port: 3306
38 Connect_Retry: 60
39 Master_Log_File: mariadb-bin.000002
40 Read_Master_Log_Pos: 330
41 Relay_Log_File: mariadb-relay-bin.000001
42 Relay_Log_Pos: 4
43 Relay_Master_Log_File: mariadb-bin.000002
44 Slave_IO_Running: No
45 Slave_SQL_Running: No
46 Replicate_Do_DB:
47 Replicate_Ignore_DB:
48 Replicate_Do_Table:
49 Replicate_Ignore_Table:
50 Replicate_Wild_Do_Table:
51 Replicate_Wild_Ignore_Table:
52 Last_Errno: 0
53 Last_Error:
54 Skip_Counter: 0
55 Exec_Master_Log_Pos: 330
56 Relay_Log_Space: 256
57 Until_Condition: None
58 Until_Log_File:
59 Until_Log_Pos: 0
60 Master_SSL_Allowed: No
61 Master_SSL_CA_File:
62 Master_SSL_CA_Path:
63 Master_SSL_Cert:
64 Master_SSL_Cipher:
65 Master_SSL_Key:
66 Seconds_Behind_Master: NULL
67 Master_SSL_Verify_Server_Cert: No
68 Last_IO_Errno: 0
69 Last_IO_Error:
70 Last_SQL_Errno: 0
71 Last_SQL_Error:
72 Replicate_Ignore_Server_Ids:
73 Master_Server_Id: 82
74 Master_SSL_Crl:
75 Master_SSL_Crlpath:
76 Using_Gtid: No
77 Gtid_IO_Pos:
78 Replicate_Do_Domain_Ids:
79 Replicate_Ignore_Domain_Ids:
80 Parallel_Mode: conservative
81 SQL_Delay: 0
82 SQL_Remaining_Delay: NULL
83 Slave_SQL_Running_State:
84 Slave_DDL_Groups: 0
85Slave_Non_Transactional_Groups: 0
86 Slave_Transactional_Groups: 0
871 row in set (0.000 sec)
88
89MariaDB [(none)]> start slave;
90Query OK, 0 rows affected (0.001 sec)
91
92MariaDB [(none)]> show slave status\G
93*************************** 1. row ***************************
94 Slave_IO_State: Waiting for master to send event
95 Master_Host: 192.168.1.82
96 Master_User: repluser
97 Master_Port: 3306
98 Connect_Retry: 60
99 Master_Log_File: mariadb-bin.000002
100 Read_Master_Log_Pos: 330
101 Relay_Log_File: mariadb-relay-bin.000002
102 Relay_Log_Pos: 557
103 Relay_Master_Log_File: mariadb-bin.000002
104 Slave_IO_Running: Yes
105 Slave_SQL_Running: Yes
106 Replicate_Do_DB:
107 Replicate_Ignore_DB:
108 Replicate_Do_Table:
109 Replicate_Ignore_Table:
110 Replicate_Wild_Do_Table:
111 Replicate_Wild_Ignore_Table:
112 Last_Errno: 0
113 Last_Error:
114 Skip_Counter: 0
115 Exec_Master_Log_Pos: 330
116 Relay_Log_Space: 868
117 Until_Condition: None
118 Until_Log_File:
119 Until_Log_Pos: 0
120 Master_SSL_Allowed: No
121 Master_SSL_CA_File:
122 Master_SSL_CA_Path:
123 Master_SSL_Cert:
124 Master_SSL_Cipher:
125 Master_SSL_Key:
126 Seconds_Behind_Master: 0
127 Master_SSL_Verify_Server_Cert: No
128 Last_IO_Errno: 0
129 Last_IO_Error:
130 Last_SQL_Errno: 0
131 Last_SQL_Error:
132 Replicate_Ignore_Server_Ids:
133 Master_Server_Id: 82
134 Master_SSL_Crl:
135 Master_SSL_Crlpath:
136 Using_Gtid: No
137 Gtid_IO_Pos:
138 Replicate_Do_Domain_Ids:
139 Replicate_Ignore_Domain_Ids:
140 Parallel_Mode: conservative
141 SQL_Delay: 0
142 SQL_Remaining_Delay: NULL
143 Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
144 Slave_DDL_Groups: 0
145Slave_Non_Transactional_Groups: 0
146 Slave_Transactional_Groups: 0
1471 row in set (0.000 sec)
148
149MariaDB [(none)]>
可以看到,这会彻底好了,符合预期。
此时,完成了双主的配置。
测试
master2:
1MariaDB [(none)]> show databases;
2+--------------------+
3| Database |
4+--------------------+
5| db1 |
6| db2 |
7| hellodb |
8| information_schema |
9| mysql |
10| performance_schema |
11+--------------------+
126 rows in set (0.000 sec)
13
14MariaDB [(none)]> create database db3;
15Query OK, 1 row affected (0.000 sec)
16
17MariaDB [(none)]> show databases;
18+--------------------+
19| Database |
20+--------------------+
21| db1 |
22| db2 |
23| db3 |
24| hellodb |
25| information_schema |
26| mysql |
27| performance_schema |
28+--------------------+
297 rows in set (0.000 sec)
30
31MariaDB [(none)]>
32
33
34
35#master1验证
36MariaDB [(none)]> show databases;
37+--------------------+
38| Database |
39+--------------------+
40| db1 |
41| db2 |
42| db3 |
43| hellodb |
44| information_schema |
45| mysql |
46| performance_schema |
47+--------------------+
487 rows in set (0.000 sec)
49
50MariaDB [(none)]>
同理可测试mater1–>master2的效果。
如果出现两边数据库不一致情况,该怎么办呢?
笨方法2:重新来一遍。
办法2:把其中1台临时关闭二进制日志,然后手动创建,再开启二进制日志。
验证下那个id问题
在master1:
1#创建一个测试表
2use hellodb;
3
4MariaDB [hellodb]> create table test(id int auto_increment primary key,name char(10));
5Query OK, 0 rows affected (0.002 sec)
因为复制关系,另一台机器上这个表也被复制过来了:
1#master1
2MariaDB [hellodb]> show tables;
3+-------------------+
4| Tables_in_hellodb |
5+-------------------+
6| classes |
7| coc |
8| courses |
9| scores |
10| students |
11| teachers |
12| test |
13| toc |
14+-------------------+
158 rows in set (0.000 sec)
16
17MariaDB [hellodb]> select *from test;
18Empty set (0.000 sec)
19
20
21#master2
22MariaDB [(none)]> use hellodb;
23Reading table information for completion of table and column names
24You can turn off this feature to get a quicker startup with -A
25
26Database changed
27MariaDB [hellodb]> show tables;
28+-------------------+
29| Tables_in_hellodb |
30+-------------------+
31| classes |
32| coc |
33| courses |
34| scores |
35| students |
36| teachers |
37| test |
38| toc |
39+-------------------+
408 rows in set (0.000 sec)
41MariaDB [hellodb]> select *from test;
42Empty set (0.000 sec)
在master1插入信息:
1MariaDB [hellodb]> insert test(name)values('a');
2Query OK, 1 row affected (0.001 sec)
3
4MariaDB [hellodb]> select *from test;
5+----+------+
6| id | name |
7+----+------+
8| 1 | a |
9+----+------+
101 row in set (0.000 sec)
11
12#当然master2上数据也过来了
13MariaDB [hellodb]> select *from test;
14+----+------+
15| id | name |
16+----+------+
17| 1 | a |
18+----+------+
191 row in set (0.000 sec)
在master2插入信息:
1MariaDB [hellodb]> insert test(name)values('b');
2Query OK, 1 row affected (0.001 sec)
3
4MariaDB [hellodb]> select *from test;
5+----+------+
6| id | name |
7+----+------+
8| 1 | a |
9| 2 | b |
10+----+------+
112 rows in set (0.000 sec)
12
13
14#当然master1上数据也过来了
15MariaDB [hellodb]> select *from test;
16+----+------+
17| id | name |
18+----+------+
19| 1 | a |
20| 2 | b |
21+----+------+
222 rows in set (0.000 sec)
模拟2个人同时干:(利用xshell同时给2个终端发送一条相同的命令)
1insert test(name)values('c');

都让你成功,错峰解决。
请问这个的结果呢?(是奇数)
1#master1上执行
2MariaDB [hellodb]> insert test(name)values('d'),('e'),('f');
3Query OK, 3 rows affected (0.001 sec)
4Records: 3 Duplicates: 0 Warnings: 0
5
6MariaDB [hellodb]> select *from test;
7+----+------+
8| id | name |
9+----+------+
10| 1 | a |
11| 2 | b |
12| 3 | c |
13| 4 | c |
14| 5 | d |
15| 7 | e |
16| 9 | f |
17+----+------+
187 rows in set (0.000 sec)
19
20MariaDB [hellodb]>
21
22
23#master2
24MariaDB [hellodb]> select *from test;
25+----+------+
26| id | name |
27+----+------+
28| 1 | a |
29| 2 | b |
30| 3 | c |
31| 4 | c |
32| 5 | d |
33| 7 | e |
34| 9 | f |
35+----+------+
367 rows in set (0.000 sec)
37
38MariaDB [hellodb]>
master2上:(是偶数)
1MariaDB [hellodb]> insert test(name)values('dd'),('ee'),('ff');
2Query OK, 3 rows affected (0.001 sec)
3Records: 3 Duplicates: 0 Warnings: 0
4
5MariaDB [hellodb]> select *from test;
6+----+------+
7| id | name |
8+----+------+
9| 1 | a |
10| 2 | b |
11| 3 | c |
12| 4 | c |
13| 5 | d |
14| 7 | e |
15| 9 | f |
16| 10 | dd |
17| 12 | ee |
18| 14 | ff |
19+----+------+
2010 rows in set (0.000 sec)
21
22MariaDB [hellodb]>
23
24
25
26#master1
27MariaDB [hellodb]> select *from test;
28+----+------+
29| id | name |
30+----+------+
31| 1 | a |
32| 2 | b |
33| 3 | c |
34| 4 | c |
35| 5 | d |
36| 7 | e |
37| 9 | f |
38| 10 | dd |
39| 12 | ee |
40| 14 | ff |
41+----+------+
4210 rows in set (0.000 sec)
结论:
这个id只会往上涨,不会给你塞缝里。😂
自己可以填坑:
1MariaDB [hellodb]> insert test values(6,'x');
2Query OK, 1 row affected (0.001 sec)
3
4MariaDB [hellodb]> select *from test;
5+----+------+
6| id | name |
7+----+------+
8| 1 | a |
9| 2 | b |
10| 3 | c |
11| 4 | c |
12| 5 | d |
13| 6 | x |
14| 7 | e |
15| 9 | f |
16| 10 | dd |
17| 12 | ee |
18| 14 | ff |
19+----+------+
2011 rows in set (0.000 sec)
21
22MariaDB [hellodb]>
结论
双主看起来很美,但实际上有严重的可能产生冲突的情况存在。
例如:我两边同时创建数据库
1#master1
2MariaDB [hellodb]> create database testdb1;
3Query OK, 1 row affected (0.000 sec)
4
5
6#master2
7MariaDB [hellodb]> create database testdb1;
8Query OK, 1 row affected (0.001 sec)
复制的时候是异步复制,复制时间间隔很长。
实际使用姿势:
一个当主,一个当从。
配的时候这么配没错,但是用的时候要一主一从这么使用。(读写分离)
The end。
6.2 MySQL 中间件代理服务器
6.3 MySQL高可用
7、性能优化
关于我
我的博客主旨:
- 排版美观,语言精炼;
- 文档即手册,步骤明细,拒绝埋坑,提供源码;
- 本人实战文档都是亲测成功的,各位小伙伴在实际操作过程中如有什么疑问,可随时联系本人帮您解决问题,让我们一起进步!
🍀 微信二维码 x2675263825 (舍得), qq:2675263825。

🍀 微信公众号 《云原生架构师实战》

🍀 个人博客站点

🍀 csdn https://blog.csdn.net/weixin_39246554?spm=1010.2135.3001.5421

🍀 知乎 https://www.zhihu.com/people/foryouone

最后
好了,关于本次就到这里了,感谢大家阅读,最后祝大家生活快乐,每天都过的有意义哦,我们下期见!

