数据库学习

第一章数据库的介绍

1.什么是数据?

在一个网站中,哪些可以被称之为数据?
咱们认为的数据:
文字、数字、符号、表格、图片、视频。。。。。
计算机认为的数据:
二进制(机器语言)

用来登录的数据有哪些? 用户,密码 和 评论类 的数据有什么不一样吗?

用户 、密码该怎么存?
txt
excel
word

1亿用户信息该怎么存?

如果用以上方式会遇到什么问题?
不安全、查找不方便、管理、限制。

2.数据库管理系统(软件:DBMS)

2.1 数据库的发展历程

第一时代架构 : RDBMS时代
什么是RDBMS?
关系型数据库关系系统:Oracle 、 MSSQL 、 IBM DB2

第二时代架构: RDBMS(MySQL、PG、云数据库) + NoSQL(Not ONLY SQL)时代
数据量、业务量随着互联网的发展,变的越来越大。所以传统的RDBMS已经不能承载所有业务需求了。
NoSQL :MongoDB 、ES 、Redis

第三时代架构:
NewSQL 分布式数据库时代
Aliyun: PolarDB
Pincap: TiDB

2.2 了解实时数据库行业动态

问大家一个问题: 怎么去了解运维行业动态?
<1. 相关站点 : itpub 、 简书、csdn、51cto。
<2. 看招聘需求 :boss 、 拉钩。
❤️. 跟着软件版本走,关注比较活跃的软件。
<4. 加入一些社群和圈子。

数据库行业动态?

<1.
https://db-engines.com/en/ranking

面试题:
请你介绍以下你熟悉的数据库产品?
RDBMS : 关系型 Oracle 、MySQL、MSSQL、PG、DB2
NoSQL : 非关系型 MongoDB 、ES 、Redis
云产品: RDS 、 TDSQL
NewSQL: polarDB 、TiDB

你们公司都用了什么数据库产品?
注意: 一般用了云产品的话,很少自建数据库。
我们建议: 
		RDBMS : 关系型     Oracle 、MySQL、MSSQL、PG、DB2 (最多两种)
        NoSQL : 非关系型   MongoDB 、ES 、Redis (一般互联网公司都有)

<2. http://www.itdks.com/

❤️. 亲自去参加数据库大会。

3.数据库行业-岗位

3.1 方向

(1) 中级运维DBA
(2) 数据库技术支持(云厂商)

开发DBA :
1-2 开发语言 ,了解业务、 高级开发能力(建模、存储过程、函数、触发器、事件、视图。。。)
数据库架构师
解决方案工程师

参考: https://www.jianshu.com/p/e5f65344227b

3.2 职业素养和岗位要求

人品 : 三观要正。
不要出现恶意删库事件。
严谨:
理论支撑
实践检验
反复斟酌

收起你的好奇心!!!
提前登录号,用户、地址、端口脱敏。

细心(态度):
把最简单的事情做的最漂亮、最专业的。

分享心:
写文章、写博客、录视频发布到互联网。

熟悉Linux操作系统 :
基础命令(目录文件、用户权限、磁盘、性能指标命令)
服务管理(LNMPT 、Ansible、zabbix监控)
shell 、Python(以后扩展)、JAVA(以后扩展)、C++(以后扩展)
云计算(Docker、K8s)
数据库知识: 思维导图。
熟悉行业 : 把控行业实时动态
熟悉业务:产品功能+用户行为。
拥抱 开源、源码。

第二章节 MySQL介绍和安装

1.MySQL 产品线

1.1 分支
Oracle
MariaDB
Percona

2.MySQL 企业版本选择

2.1 分支

E : 企业版 (收费),可以下载30天试用
C : 社区版 (开源)

2.2 社区版选择

免费服务期限: 1-5年
扩展服务期限: 6-10年

5.7 :一般建议升级到最新版本,5.7.18-5.7.30 最好是双数版。
5.6 :一般建议选用GA6-12月区间,5.6.34-max,最好是双数版本。
8.0 :一般建议使用8.0.18+

2.3 获取数据库软件

https://downloads.mysql.com/archives/community/

3.手撕 安装 MySQL 5.7.28 二进制版本

3.1 克隆虚拟机

IP: 10.0.0.51/24
hostname: db01
防火墙关闭
selinux关闭

3.2 清理历史环境

yum remove -y mariadb-libs
\rm -rf /etc/my.cnf*

3.3 创建用户

useradd mysql

3.4创建相关目录并授权

mkdir -p /data/app /data/3306/data /data/3306/logs
chown -R mysql.mysql /data

3.5上传 5.7.28 软件至/data/app,并解压、软连接

[root@db01 ~]# cd /data/app
[root@db01 app]# tar xf mysql-5.7.28-linux-glibc2.12-x86_64.tar.gz
[root@db01 app]# ln -s mysql-5.7.28-linux-glibc2.12-x86_64 mysql

3.6设置环境变量

vim /etc/profile

添加最后一行

export PATH=/data/app/mysql/bin:$PATH

#生效配置:
source /etc/profile

3.7安装关键依赖软件包

yum install -y libaio-devel

3.8初始化数据(建库)

/data/app/mysql/bin/mysqld --initialize-insecure --user=mysql --basedir=/data/app/mysql --datadir=/data/3306/data

命令作用:
将数据启动所需要的系统数据(/data/3306/data)

参数介绍:
–initialize-insecure 初始化核心参数(必加)
–user=mysql 初始化用户和组
–basedir=/data/app/mysql 软件安装目录
–datadir=/data/3306/data 数据存放位置

彩蛋1:

5.7 版本初始化参数介绍:

​ 初始化 不安全
​ --initialize-insecure
​ 说明:
​ 初始化完成后是无密码的。

--initialize : 安全的初始化方式	
说明:
	1. 自动生成临时密码,第一次使用时需要修改此密码
	2. 4种密码复杂度,12位。

彩蛋2:

5.7 初始化命令:

 /data/app/mysql/bin/mysqld --initialize-insecure --user=mysql basedir=/data/app/mysql --datadir=/data/3306/data

5.6初始化区别

/data/app/mysql56/scripts/mysql_install_db --user=mysql --basedir=/data/app/mysql --datadir=/data/3306/data

3.9准备启动脚本

[root@db01 data]# cp /data/app/mysql/support-files/mysql.server /etc/init.d/mysqld

3.10准备配置文件

[root@db01 data]# vim /etc/my.cnf
[mysqld]
user=mysql
basedir=/data/app/mysql
datadir=/data/3306/data
socket=/tmp/mysql.sock
[mysql]
socket=/tmp/mysql.sock

3.11 启动数据库

[root@db01 data]# /etc/init.d/mysqld start
Starting MySQL. SUCCESS! 

[root@db01 data]# service mysqld restart
Shutting down MySQL.. SUCCESS! 
Starting MySQL. SUCCESS!

3.12 使用systemd管理mysql

[root@db01 data]# chkconfig --add mysqld
[root@db01 data]# /etc/init.d/mysqld stop
Shutting down MySQL.. SUCCESS!
[root@db01 data]# systemctl start mysqld
[root@db01 data]# mysql
[root@db01 data]# ps -ef |grep mysqld
root      17275      1  0 16:00 ?        00:00:00 /bin/sh /data/app/mysql/bin/mysqld_safe --datadir=/data/3306/data --pid-file=/data/3306/data/db01.pid
mysql     17416  17275  4 16:00 ?        00:00:00 /data/app/mysql/bin/mysqld --basedir=/data/app/mysql --datadir=/data/3306/data --plugin-dir=/data/app/mysql/lib/plugin --user=mysql --log-error=db01.err --pid-file=/data/3306/data/db01.pid --socket=/tmp/mysql.sock
root      17448  16288  0 16:00 pts/1    00:00:00 grep --color=auto mysqld
[root@db01 data]# 
[root@db01 data]# netstat -tulnp |grep 3306
tcp6       0      0 :::3306                 :::*                    LISTEN      17416/mysqld        
[root@db01 data]# systemctl stop  mysqld
[root@db01 data]# netstat -tulnp |grep 3306

3.13 基于initialize模式,修改临时密码

[root@db01 data]# mysqladmin -uroot -p password 123
Enter password:

彩蛋: 如果启动报错,如何排查?

[root@db01 data]# /etc/init.d/mysqld start

Starting MySQL.Logging to ‘/data/3306/data/db01.err’.
. ERROR! The server quit without updating PID file (/data/3306/data/db01.pid).

vim /data/3306/data/db01.err

—》 从后往前排查 [ERROR]信息。
2020-06-29T07:32:32.533458Z 0 [ERROR] InnoDB: The innodb_system data file ‘ibdata1’ must be writable
2020-06-29T07:32:32.533512Z 0 [ERROR] InnoDB: The innodb_system data file ‘ibdata1’ must be writable
2020-06-29T07:32:32.533523Z 0 [ERROR] InnoDB: Plugin initialization aborted with error Generic error
2020-06-29T07:32:33.139530Z 0 [ERROR] Plugin ‘InnoDB’ init function returned error.
2020-06-29T07:32:33.139840Z 0 [ERROR] Plugin ‘InnoDB’ registration as a STORAGE ENGINE failed.
2020-06-29T07:32:33.140017Z 0 [ERROR] Failed to initialize builtin plugins.
2020-06-29T07:32:33.140055Z 0 [ERROR] Aborting

—》 得到结果: 权限问题

第三章 :MySQL 基础管理

1.用户管理

1.1 作用

Linux :
登录系统
管理操作系统对象(文件)

MySQL :
登录数据库
管理数据库对象(表)

1.2 用户的定义方式(长成啥样子?)

Linux :
用户名: 字母、数字、特殊符号等组合
MySQL :
用户名@‘白名单’

白名单?
一个或者多个IP的列表。作用是,在列表中存在的IP才能连接数据库。
oldguo@‘localhost’
oldguo@‘10.0.0.52’
oldguo@‘10.0.0.%’
oldguo@‘10.0.0.5%’
oldguo@‘10.0.0.0/255.255.254.0’
oldguo@’%’

1.3 用户的管理

1.3.1 查询:

mysql> select user,host from mysql.user;
±--------------±----------+
| user | host |
±--------------±----------+
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
±--------------±----------+

mysql> select user,host,authentication_string ,plugin from mysql.user;
±--------------±----------±------------------------------------------±----------------------+
| user | host | authentication_string | plugin |
±--------------±----------±------------------------------------------±----------------------+
| root | localhost | *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 | mysql_native_password |
| mysql.session | localhost | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password |
| mysql.sys | localhost | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password |
±--------------±----------±------------------------------------------±----------------------+
3 rows in set (0.00 sec)

如果记不住以上单词,可以执行以下命令获得

mysql> desc mysql.user;

1.3.2 创建:

需求: 通过 oldguo 用户,密码123 ,从10网段任意地址登陆MySQL
mysql> create user oldguo@‘10.0.0.%’ identified by ‘123’;
mysql> select user,host,authentication_string ,plugin from mysql.user;
±--------------±----------±------------------------------------------±----------------------+
| user | host | authentication_string | plugin |
±--------------±----------±------------------------------------------±----------------------+
| root | localhost | *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 | mysql_native_password |
| mysql.session | localhost | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password |
| mysql.sys | localhost | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password |
| oldguo | 10.0.0.% | *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 | mysql_native_password |
±--------------±----------±------------------------------------------±----------------------+

1.3.3 修改用户

mysql> alter user oldguo@‘10.0.0.%’ identified by ‘123456’;
Query OK, 0 rows affected (0.00 sec)

mysql> select user,host,authentication_string ,plugin from mysql.user;
±--------------±----------±------------------------------------------±----------------------+
| user | host | authentication_string | plugin |
±--------------±----------±------------------------------------------±----------------------+
| root | localhost | *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 | mysql_native_password |
| mysql.session | localhost | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password |
| mysql.sys | localhost | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password |
| oldguo | 10.0.0.% | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 | mysql_native_password |
±--------------±----------±------------------------------------------±----------------------+
4 rows in set (0.00 sec)

1.3.4 删除用户

mysql> drop user oldguo@‘10.0.0.%’;
Query OK, 0 rows affected (0.00 sec)

mysql> select user,host,authentication_string ,plugin from mysql.user;
±--------------±----------±------------------------------------------±----------------------+
| user | host | authentication_string | plugin |
±--------------±----------±------------------------------------------±----------------------+
| root | localhost | *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 | mysql_native_password |
| mysql.session | localhost | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password |
| mysql.sys | localhost | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password |
±--------------±----------±------------------------------------------±----------------------+
3 rows in set (0.00 sec)

2.权限管理

2.1 作用

控制用户,能够对数据库对象,做哪些操作.

2.2 定义方式

Linux 权限: r w x
MySQL 权限: 命令即权限。
mysql> show privileges; —》 查看MySQL中的权限列表
Alter
Alter routine
Create
Create routine
Create temporary tables
Create view
Create user
Delete
Drop
Event
Execute
File
Grant option
Index
Insert
Lock tables
Process
Proxy
References
Reload
Replication client
Replication slave
Select
Show databases
Show view
Shutdown
Super
Trigger
Create tablespace
Update
Usage

说明:
特殊的权限ALL:代表了以上所有权限结合,除了Grant option(给别人授权的功能)。
一般管理员用户会具备ALL,其他普通用户按需提供相应权限,一般DROP种类的权限不会给普通用户。

2.3 权限的管理

2.3.1 权限查询

MySQL中权限是属于用户的属性。
mysql> show grants for root@‘localhost’;
GRANT ALL PRIVILEGES ON . TO ‘root’@‘localhost’ WITH GRANT OPTION

2.3.2 授权

GRANT 权限 ON 作用范围 TO 用户 IDENTIFIED BY ‘密码’;

作用范围 ?
. : 全局范围 chmod -R /
wordpress.* : 单库范围 chmod -R /wordpress
wordpress.t1:单表范围 chmod -R /wordpress/a.txt

管理员用户授权:
mysql> grant all on . to oldboy@‘10.0.0.%’ identified by ‘123’;
普通用户授权:
mysql> grant select,update,delete,insert on test.* to test@‘10.0.0.%’ idenfied by ‘123’;

2.3.3 回收

注意: 不能通过重复授权修改权限,因为授权都是相加的关系。
mysql> revoke delete on test.* from ‘test’@‘10.0.0.%’;

===================================
课间休息: 17:16 ~ 17:30

===================================

2.3.4 彩蛋 8.0 版本之后在 用户、权限管理方面的变化

<1. 必须先建好用户,再授权,grant 命令不再支持自动建用户,不支持设置密码。
<2. 建用户,密码加密插件发生变化,改为 :caching_sha2_password,有很多场景,修改修改为: mysql_native_password
比如: 第三方工具、主从、高可用、备份软件等。。。
mysql> alter user oldboy@‘10.0.0.%’ identified with mysql_native_password by ‘123’;
❤️. 8.0 加入了role(角色)的概念。就是权限的组合。

3.MySQL 连接管理

3.1 自带客户端命令

mysql 命令的使用

-u    用户名
-p    密码
-S    Socket文件
-h    IP地址 
-P    端口号
-e    免交互执行命令
<     导入SQL脚本

IP地址连接串 (tcpip连接方法)

IP Port user passwd
mysql -u用户 -p密码 -h地址 -P端口
前提:
1. IP和端口正确的。
2. 提前创建好可以远程登录的用户

[root@db01 data]# mysql -uoldboy -p123 -h10.0.0.51 -P3306
[root@db01 data]# mysql -uoldboy -p123 -h10.0.0.51 

本地Socket文件

前提:
1、 设置正确的Socket文件位置
2、 提前创建好localhost相关用户
3、 只提供给数据库本地连接的特殊方法

[root@db01 data]# mysql -uroot -p -S /tmp/mysql.sock 

3.2 开发工具

sqlyog
navicat
workbench

3.3 应用连接

4. 初始化配置文件

4.1 作用

<1. 影响到数据库的启动、日常工作。
<2. 影响到客户端连接(本地服务器上发起的)。

4.2 文件格式

[root@db01 ~]# cat /etc/my.cnf 
[mysqld]
user=mysql
basedir=/data/app/mysql
datadir=/data/3306/data
socket=/tmp/mysql.sock
[mysql]
socket=/tmp/mysql.sock

[标签项] : 用来表示不同的程序
服务端: [mysqld] [mysqld_safe] [server]
客户端: [mysql] [mysqldump] [client]
配置=xxx : 设置的参数键值对
user=mysql # 数据库管理用户
basedir=/data/app/mysql # 程序路径
datadir=/data/3306/data # 数据路径
socket=/tmp/mysql.sock # socket文件位置

4.3 配置文件读取顺序

默认配置文件读取顺序

[root@db01 ~]# mysqld --help --verbose |grep my.cnf
/etc/my.cnf —》 /etc/mysql/my.cnf —》 /usr/local/mysql/etc/my.cnf ----》 ~/.my.cnf
建议: 每个数据库保留一个配置文件。
彩蛋:
如果有多个配置文件,例如
/etc/my.cnf —> port=3306
~/.my.cnf —> port=3308
数据库启动时,port是多少?

手工定义配置文件读取路径

mysqld --defaults-file=/opt/my1.cnf &
mysqld_safe --defaults-file=/opt/my2.cnf &

4.4 root本地管理员的密码忘记?

<1. 停数据库

[root@db01 tmp]# /etc/init.d/mysqld stop
Shutting down MySQL… SUCCESS!
[root@db01 tmp]#

<2. 启动数据库到“安全”模式

mysqld_safe --skip-grant-tables --skip-networking &

参数作用:
–skip-grant-tables : 跳过授权表,不开启验证功能。
–skip-networking : 阻止所有TCP/IP网络连接。

❤️. 改密码

mysql> flush privileges;
mysql> alter user root@‘localhost’ identified by ‘123456’;

<4. 重启至正常模式

[root@db01 tmp]# /etc/init.d/mysqld restart

5. MySQL的启动关闭

见图。

6. 多实例应用

6.1 创建相关目录

[root@db01 ~]# mkdir -p /data/330{7…9}/data /data/330{7…9}/logs

6.2 准备配置文件

cat >/data/3307/my.cnf < [mysqld]
user=mysql
basedir=/data/app/mysql
datadir=/data/3307/data
server_id=7
port=3307
log_bin=/data/3307/logs/mysql-bin
socket=/tmp/mysql3307.sock
EOF

cat >/data/3308/my.cnf < [mysqld]
user=mysql
basedir=/data/app/mysql
datadir=/data/3308/data
server_id=8
port=3308
log_bin=/data/3308/logs/mysql-bin
socket=/tmp/mysql3308.sock
EOF

cat >/data/3309/my.cnf < [mysqld]
user=mysql
basedir=/data/app/mysql
datadir=/data/3309/data
server_id=9
port=3309
log_bin=/data/3309/logs/mysql-bin
socket=/tmp/mysql3309.sock
EOF

6.3 授权

[root@db01 ~]# chown -R mysql. /data/*

6.4 初始化数据

mv /etc/my.cnf /etc/my.cnf.bak

mysqld --initialize-insecure --user=mysql --basedir=/data/app/mysql --datadir=/data/3307/data
mysqld --initialize-insecure --user=mysql --basedir=/data/app/mysql --datadir=/data/3308/data
mysqld --initialize-insecure --user=mysql --basedir=/data/app/mysql --datadir=/data/3309/data

mv /etc/my.cnf.bak /etc/my.cnf

6.5 启动多实例

[root@db01 ~]# mysqld_safe --defaults-file=/data/3307/my.cnf &
[root@db01 ~]# mysqld_safe --defaults-file=/data/3308/my.cnf &
[root@db01 ~]# mysqld_safe --defaults-file=/data/3309/my.cnf &

6.7 使用navicat连接多实例

mysql -S /tmp/mysql3307.sock
grant all on . to root@‘10.0.0.%’ identified by ‘123’;
mysql -S /tmp/mysql3308.sock -e “grant all on . to root@‘10.0.0.%’ identified by ‘123’;”
mysql -S /tmp/mysql3309.sock -e “grant all on . to root@‘10.0.0.%’ identified by ‘123’;”

6.8 配置多实例systemd

cat > /etc/systemd/system/mysqld3307.service < [Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
ExecStart=/data/app/mysql/bin/mysqld --defaults-file=/data/3307/my.cnf
LimitNOFILE = 5000
EOF

cat > /etc/systemd/system/mysqld3308.service < [Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
ExecStart=/data/app/mysql/bin/mysqld --defaults-file=/data/3308/my.cnf
LimitNOFILE = 5000
EOF

cat > /etc/systemd/system/mysqld3309.service < [Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
ExecStart=/data/app/mysql/bin/mysqld --defaults-file=/data/3309/my.cnf
LimitNOFILE = 5000
EOF

[root@db01 ~]# pkill mysqld
[root@db01 ~]# systemctl start mysqld3307
[root@db01 ~]# systemctl start mysqld3308
[root@db01 ~]# systemctl start mysqld3309

7.彩蛋:多版本多实例应用

真实学生案例: 第一周工作

7.1 上传软件、解压、软连接

tar xf mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz
tar xf mysql-8.0.18-linux-glibc2.12-x86_64.tar.xz

ln -s mysql-8.0.18-linux-glibc2.12-x86_64 mysql80
ln -s mysql-5.6.46-linux-glibc2.12-x86_64 mysql56

7.2 创建相关目录

mkdir -p /data/331{7…8}/data /data/331{7…8}/logs

7.3 准备配置文件

cat >/data/3317/my.cnf < [mysqld]
user=mysql
basedir=/data/app/mysql56
datadir=/data/3317/data
server_id=17
port=3317
log_bin=/data/3317/logs/mysql-bin
socket=/tmp/mysql3317.sock
EOF

cat >/data/3318/my.cnf < [mysqld]
user=mysql
basedir=/data/app/mysql80
datadir=/data/3318/data
server_id=18
port=3318
log_bin=/data/3318/logs/mysql-bin
socket=/tmp/mysql3318.sock
EOF

7.4 授权

[root@db01 ~]# chown -R mysql. /data/*

7.5 初始化数据

mv /etc/my.cnf /etc/my.cnf.bak

vim /etc/profile
#注释环境变量:

export PATH=/data/app/mysql/bin:$PATH

最好重连一个Xshell窗口

[root@db01 ~]# mysql -V
-bash: mysql: command not found
[root@db01 ~]#

5.6初始化

/data/app/mysql56/scripts/mysql_install_db --user=mysql --basedir=/data/app/mysql56 --datadir=/data/3317/data

8.0初始化

/data/app/mysql80/bin/mysqld --initialize-insecure --user=mysql --basedir=/data/app/mysql80 --datadir=/data/3318/data

7.6 配置systemd管理

cat > /etc/systemd/system/mysqld3317.service < [Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
ExecStart=/data/app/mysql56/bin/mysqld --defaults-file=/data/3317/my.cnf
LimitNOFILE = 5000
EOF

cat > /etc/systemd/system/mysqld3318.service < [Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
ExecStart=/data/app/mysql80/bin/mysqld --defaults-file=/data/3318/my.cnf
LimitNOFILE = 5000
EOF

7.7 连接测试

[root@db01 app]# /data/app/mysql56/bin/mysql -S /tmp/mysql3317.sock
[root@db01 app]# /data/app/mysql80/bin/mysql -S /tmp/mysql3318.sock

8.彩蛋: MySQL 的升级、降级

1.升级

1.1 INPLACE就地

在一台服务器上,原版本升级到新版本。
风险较大。

建议 : 不管哪种方式升级,都应该先做备份。方便失败回退。

1.2 Mergeing(logical)迁移 ----> 建议

备份迁移
主从迁移

1.3 升级注意事项

Upgrade is only supported between General Availability (GA) releases.
Upgrade from MySQL 5.6 to 5.7 is supported. Upgrading to the latest release is recommended before upgrading to the next version. For example, upgrade to the latest MySQL 5.6 release before upgrading to MySQL 5.7.
Upgrade that skips versions is not supported. For example, upgrading directly from MySQL 5.5 to 5.7 is not supported.
Upgrade within a release series is supported. For example, upgrading from MySQL 5.7.x to 5.7.y is supported. Skipping a release is also supported. For example, upgrading from MySQL 5.7.x to 5.7.z is supported.

a. 支持GA版本之间升级
b. 5.6–> 5.7 ,先将5.6升级至最新版,再升级到5.7
c. 5.5 —> 5.7 ,先将5.5 升级至最新,再5.5—> 5.6最新,再5.6—>5.7 最新
d. 回退方案要提前考虑好,最好升级前要备份(特别是往8.0版本升级)。
e. 降低停机时间(停业务的时间),在业务不繁忙期间升级,做好足够的预演。

1.4 INPLACE 升级过程原理 (生产思路)

  1. 备份原数据库数据
    a. 安装新版本软件
    b. 关闭原数据库业务(挂维护页)
    c. 使用新版本软件 “挂” 旧版本数据启动(–skip-grant-tables ,–skip-networking)
    d. 升级 : 只是升级系统表。升级时间和数据量无关的。
    e. 正常重启数据库。
    f. 验证各项功能是否正常。
    g. 业务恢复。

1.5 5.6.46 ----> 5.7.28 Inplace 升级演练

a. 安装 新版本软件
略。

b. 停原库 (5.6.46)

  1. 快速关库功能关闭(优雅关闭、干净的关闭)

vim /data/3317/my.cnf

添加以下配置

innodb_fast_shutdown=0
[root@db01 data]# systemctl stop mysqld3317

c. 使用高版本软件挂低版本数据启动
[root@db01 data]# vim /data/3317/my.cnf
[mysqld]
user=mysql
basedir=/data/app/mysql
datadir=/data/3317/data
socket=/tmp/mysql3317.sock
port=3317
server_id=17
innodb_fast_shutdown=0

[root@db01 data]# /data/app/mysql/bin/mysqld_safe --defaults-file=/data/3317/my.cnf --skip-grant-tables --skip-networking &

d. 升级 (升级到8.0可以省略)
[root@db01 data]# /data/app/mysql/bin/mysql_upgrade -S /tmp/mysql3317.sock --force

e. 重启数据库到正常状态
[root@db01 data]# /data/app/mysql/bin/mysqladmin -S /tmp/mysql3317.sock shutdown

[root@db01 data]# vim /etc/systemd/system/mysqld3317.service

修改以下内容

ExecStart=/data/app/mysql/bin/mysqld --defaults-file=/data/3317/my.cnf

启动数据库

[root@db01 data]# systemctl start mysqld3317

连接查看

[root@db01 data]# /data/app/mysql/bin/mysql -S /tmp/mysql3317.sock

1.6 彩蛋: 将5.7 升级至 8.0

新特性:

1、 mysql-shell工具,8.0以后,可以调用这个命令,升级之前的预检查。
例子:
[root@db01 ~]# mysqlsh root:[email protected]:3306 -e “util.checkForServerUpgrade()”
2、升级时不再需要手工 mysql_upgrade
3、限制:升级前必须要备份。否则无法回退。

5.7.28 升级至 8.0.18 版本演练

a. 下载 8.0.18 版本的 mysql-shell,并安装 。
https://downloads.mysql.com/archives/
[root@db01 app]# yum install -y mysql-shell-8.0.18-1.el7.x86_64.rpm

b. 创建连接用户
[root@db01 data]# /data/app/mysql/bin/mysql -S /tmp/mysql3317.sock
mysql> grant all on . to root@‘10.0.0.%’ identified by ‘123’;
mysql> drop user root@‘127.0.0.1’;
mysql> drop user root@‘db01’;
mysql> drop user ‘’@‘db01’;
mysql> drop user ‘’@‘localhost’;
mysql> drop user root@’::1’;
mysql> select user,host from mysql.user;
±--------------±----------+
| user | host |
±--------------±----------+
| root | 10.0.0.% |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
±--------------±----------+

c. 预 检查
[root@db01 data]# mysqlsh root:[email protected]:3317 -e “util.checkForServerUpgrade()” >/tmp/up.log

d. 停原库(5.7.28)
vim /data/3317/my.cnf

添加以下配置

innodb_fast_shutdown=0
[root@db01 data]# systemctl stop mysqld3317

e. 使用高版本软件挂低版本数据启动
[root@db01 data]# vim /data/3317/my.cnf
[mysqld]
user=mysql
basedir=/data/app/mysql80
datadir=/data/3317/data
socket=/tmp/mysql3317.sock
port=3317
server_id=17
innodb_fast_shutdown=0

[root@db01 data]# /data/app/mysql80/bin/mysqld_safe --defaults-file=/data/3317/my.cnf --skip-grant-tables --skip-networking &

f. 重启数据库到正常状态
[root@db01 data]# /data/app/mysql80/bin/mysqladmin -S /tmp/mysql3317.sock shutdown

[root@db01 data]# vim /etc/systemd/system/mysqld3317.service

修改以下内容

ExecStart=/data/app/mysql80/bin/mysqld --defaults-file=/data/3317/my.cnf

启动数据库

[root@db01 data]# systemctl start mysqld3317

连接查看

[root@db01 data]# /data/app/mysql80/bin/mysql -S /tmp/mysql3317.sock

2.降级:

2.1 限制

官方解释:
https://dev.mysql.com/doc/refman/5.7/en/downgrade-paths.html
Downgrade from MySQL 5.7 to 5.6 is supported using the logical downgrade method.

https://dev.mysql.com/doc/refman/5.7/en/downgrade-binary-package.html#downgrade-procedure-inplace
In-place downgrade is supported for downgrades between GA releases within the same release series(5.7.y —> 5.7.x).

2.2

5.7.28 —》 5.7.10 inplace downgrade演练

原版本:
软件: 5.7.28 /data/app/mysql + 数据:/data/3306/data
目标版本: 5.7.10 /data/app/mysql5710

2.2.1. 安装 5.7.10 (低) 二进制版本

[root@db01 app]# ln -s mysql-5.7.10-linux-glibc2.5-x86_64 mysql5710

2.2.2. 针对5728版本(高)进行处理工作

https://dev.mysql.com/doc/refman/5.7/en/downgrading-to-previous-series.html

[root@db01 app]# cp /etc/my.cnf.bak /etc/my.cnf
[root@db01 app]# /etc/init.d/mysqld restart
[root@db01 app]# /data/app/mysql/bin/mysql -uroot -p123456 -S /tmp/mysql.sock

set sql_mode='STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' ;
set global sql_mode='STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' ;
select @@sql_mode;                              
ALTER TABLE mysql.proc MODIFY definer char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
ALTER TABLE mysql.event MODIFY definer char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
ALTER TABLE mysql.tables_priv MODIFY Grantor char(77) COLLATE utf8_bin NOT NULL DEFAULT '';
ALTER TABLE mysql.procs_priv MODIFY Grantor char(77) COLLATE utf8_bin NOT NULL DEFAULT '';

2.2.3. 优雅的关闭5.7.28(高)。

[root@db01 app]# /data/app/mysql/bin/mysql -uroot -p123456 -S /tmp/mysql.sock
set global innodb_fast_shutdown=0 ;

[root@db01 app]# /data/app/mysql/bin/mysqladmin  -uroot -p123456 shutdown

2.2.4. 删除ib_logfile*

[root@db01 mysql5710]# rm -rf /data/3306/data/ib_logfile*

2.2.5. 替换配置文件(替换成低版本)

[root@db01 mysql5710]# vim /etc/my.cnf
[mysqld]
user=mysql
basedir=/data/app/mysql5710
#basedir=/data/app/mysql
datadir=/data/3306/data
socket=/tmp/mysql.sock
[mysql]
socket=/tmp/mysql.sock

2.2.6. 低版本启动高版本数据库

/data/app/mysql5710/bin/mysqld --skip-grant-tables --skip-networking &

2.2.7. 执行upgrade

[root@db01 ~]# /data/app/mysql5710/bin/mysql_upgrade -uroot -p123456 --force

2.2.8 启动到正常模式

[root@db01 ~]# /etc/init.d/mysqld restart
Shutting down MySQL.. SUCCESS! 
Starting MySQL. SUCCESS! 

/data/app/mysql5710/bin/mysql -uroot -p123456 -S /tmp/mysql.sock

3.3  5.7.28 ---》 5.6.46       logical downgrade演练
2.3.0 恢复5.7.28 环境 
[root@db01 data]# pkill mysqld
[root@db01 data]# rm -rf /data/3306/data/*

恢复配置文件

[root@db01 data]# vim /etc/my.cnf
[mysqld]
user=mysql
basedir=/data/app/mysql
datadir=/data/3306/data
socket=/tmp/mysql.sock
[mysql]
socket=/tmp/mysql.sock

恢复环境变量

vim /etc/profile 
export PATH=/data/app/mysql/bin:$PATH
[root@db01 data]# source /etc/profile

[root@db01 data]# mysql -V
mysql  Ver 14.14 Distrib 5.7.28, for linux-glibc2.12 (x86_64) using  EditLine wrapper

初始化数据

mysqld --initialize-insecure --user=mysql --basedir=/data/app/mysql --datadir=/data/3306/data

启动数据库

[root@db01 data]# /etc/init.d/mysqld start
Starting MySQL.Logging to '/data/3306/data/db01.err'.
 SUCCESS! 

mysql> select version();
+-----------+
| version() |
+-----------+
| 5.7.28    |
+-----------+
1 row in set (0.00 sec)

2.3.1 安装5.6.46二进制版本软件
略。

2.3.2 处理5.7.28高版本数据

set sql_mode='STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' ;
set global sql_mode='STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' ;
select @@sql_mode;   
ALTER TABLE mysql.proc MODIFY definer char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
ALTER TABLE mysql.event MODIFY definer char(77) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '';
ALTER TABLE mysql.tables_priv MODIFY Grantor char(77) COLLATE utf8_bin NOT NULL DEFAULT '';
ALTER TABLE mysql.procs_priv MODIFY Grantor char(77) COLLATE utf8_bin NOT NULL DEFAULT '';
ALTER TABLE mysql.tables_priv MODIFY User char(16) NOT NULL default '';
ALTER TABLE mysql.columns_priv MODIFY User char(16) NOT NULL default '';
ALTER TABLE mysql.user MODIFY User char(16) NOT NULL default '';
ALTER TABLE mysql.db MODIFY User char(16) NOT NULL default '';
ALTER TABLE mysql.procs_priv MODIFY User char(16) binary DEFAULT '' NOT NULL;
ALTER TABLE mysql.user ADD Password char(41) character set latin1
collate latin1_bin NOT NULL default '' AFTER user;
UPDATE mysql.user SET password = authentication_string WHERE
LENGTH(authentication_string) = 41 AND plugin = 'mysql_native_password';
UPDATE mysql.user SET authentication_string = '' WHERE
LENGTH(authentication_string) = 41 AND plugin = 'mysql_native_password';
ALTER TABLE mysql.help_category ENGINE='MyISAM' STATS_PERSISTENT=DEFAULT;
ALTER TABLE mysql.help_keyword ENGINE='MyISAM' STATS_PERSISTENT=DEFAULT;
ALTER TABLE mysql.help_relation ENGINE='MyISAM' STATS_PERSISTENT=DEFAULT;
ALTER TABLE mysql.help_topic ENGINE='MyISAM' STATS_PERSISTENT=DEFAULT;
ALTER TABLE mysql.time_zone ENGINE='MyISAM' STATS_PERSISTENT=DEFAULT;
ALTER TABLE mysql.time_zone_leap_second ENGINE='MyISAM' STATS_PERSISTENT=DEFAULT;
ALTER TABLE mysql.time_zone_name ENGINE='MyISAM' STATS_PERSISTENT=DEFAULT;
ALTER TABLE mysql.time_zone_transition  ENGINE='MyISAM' STATS_PERSISTENT=DEFAULT;
ALTER TABLE mysql.time_zone_transition_type ENGINE='MyISAM' STATS_PERSISTENT=DEFAULT;
ALTER TABLE mysql.plugin ENGINE='MyISAM' STATS_PERSISTENT=DEFAULT;
ALTER TABLE mysql.servers ENGINE='MyISAM' STATS_PERSISTENT=DEFAULT;
ALTER TABLE mysql.user MODIFY plugin CHAR(64) COLLATE utf8_bin
DEFAULT 'mysql_native_password';
DROP DATABASE sys;

2.3.3. 逻辑全备5.7.28数据
[root@db01 ~]# mysqldump -A >/tmp/full.sql

2.3.4. 初始化一套5.6.46的空环境

[root@db01 ~]# vim /etc/profile
export PATH=/data/app/mysql56/bin:$PATH

[root@db01 ~]# source /etc/profile
[root@db01 ~]# mysql -V
mysql  Ver 14.14 Distrib 5.6.46, for linux-glibc2.12 (x86_64) using  EditLine wrapper

[root@db01 ~]# mv /etc/my.cnf /etc/my.cnf.bak
mv: overwrite ‘/etc/my.cnf.bak’? y

[root@db01 data]# rm -rf /data/3317/data/*

[root@db01 data]# /data/app/mysql56/scripts/mysql_install_db  --user=mysql --basedir=/data/app/mysql56 --datadir=/data/3317/data
[root@db01 data]# vim /etc/systemd/system/mysqld3317.service 
ExecStart=/data/app/mysql56/bin/mysqld --defaults-file=/data/3317/my.cnf

[root@db01 data]# systemctl daemon-reload
[root@db01 data]# systemctl start mysqld3317

2.3.5. 恢复备份数据到5.6.46中

[root@db01 data]# mysql -S /tmp/mysql3317.sock 
mysql> source /tmp/full.sql

第四章节 体系结构

1.C/S结构模型

Client :
Server :

2.实例

实例: mysqld守护进程+线程(M,IO,SQL,Purge…)+预分配的内存(独占)
公司: boss+员工(经理,干活的)+ 办公区

3.MySQL 核心体系结构(SQL语句的执行过程)

Server层 (实例层)
engine层 (存储层)
和磁盘交互。相当Linux文件系统
具体见图。
参考:https://www.jianshu.com/p/e872bc12f583

4.对象逻辑结构

Linux MySQL
目录 库
文件 表

库: 库名 、库属性
表: 表名、表属性、列(列名、列属性)、行 -----》 元数据(数据字典)+数据

mysql> show databases;
mysql> use mysql
mysql> show tables;

5.对象-物理存储结构-宏观

cd /data/3306/data

库: 对应着 OS 中的目录
表:
例如:
user 表 MyISAM
user.frm : 存储数据字典信息(列相关信息)
user.MYD : 存储数据行
user.MYI : 存储索引

servers 表 InnoDB
servers.frm : 存储数据字典信息(列相关信息)
servers.ibd : 存储数据行和索引

6.InnoDB存储引擎-物理存储结构引入-微观结构

存储引擎:MySQL 内部的“文件系统”,和磁盘交互的结构。

segment(数据段) : 表的数据存放的位置,包含1-N个extent(区、簇)
extent (区、簇) : 包含了连续的64个pages,默认1M。
page (数据页) : 最小IO单元,默认是16KB 。连续的4个OS block。

第五章 SQL 基础应用

1.什么是SQL?

关系型数据库当中通用的查询语言。全名:结构化查询语言。

2.SQL 标准 (ANSI/ISO)

SQL-89
SQL-92
SQL-99
SQL-03

3.SQL 常用分类

DDL : 数据定义语言
DCL : 数据控制语言
DML : 数据操作语言

4.SQL_MODE ?

5.7+ 之后采用的是严格模式。
作用:
为了让我们SQL在执行时更加严谨、有意义,符合常识、逻辑、符合科学等。。。
例子:

  1. 日期格式: 2020-07-01 0000-00-00
  2. 除法运算: 除数不能为0

查看SQL_MODE:
mysql> select @@sql_mode;
±------------------------------------------------------------------------------------------------------------------------------------------+
| @@sql_mode |
±------------------------------------------------------------------------------------------------------------------------------------------+
| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
±------------------------------------------------------------------------------------------------------------------------------------------+

设置SQL_MODE:
mysql> set sql_mode=’’;
Query OK, 0 rows affected, 1 warning (0.00 sec)

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

set sql_mode=‘ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION’;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> select @@sql_mode;
±------------------------------------------------------------------------------------------------------------------------------------------+
| @@sql_mode |
±------------------------------------------------------------------------------------------------------------------------------------------+
| ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
±------------------------------------------------------------------------------------------------------------------------------------------+

5.字符集和校对规则

5.1 字符集

mysql> show charset;
utf8
utf8mb4

mysql> show variables like ‘%char%’;
±-------------------------±--------------------------------------------------------------+
| Variable_name | Value |
±-------------------------±--------------------------------------------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /data/app/mysql-5.7.28-linux-glibc2.12-x86_64/share/charsets/ |
±-------------------------±--------------------------------------------------------------+

utf8 和 utf8mb4 区别?
例如:
utf8不完整,emoji表情字符是不支持,utf8mb4是支持的。
根本原因是,utf8 字符最大长度为3字节,utf8mb4是4字节。

5.2 校对规则(排序规则)

mysql> show collation;
作用: 影响到了字符串的排序。

6.数据类型

作用: 约束存储的数据更加有意义,符合对于这个列的定义。

6.1 数字类型

​ 字节量 范围
tinyint 1 0~255 -127~128
int 4 0~2^32-1 -2^31 ~2^31-1

6.2 字符串类型

char(10)
定长类型的字符串类型。最多存储10个字符。如果存了5个,剩余空间用空格填充。

varchar(10)
变长类型的字符串类型。最多存储10个字符。如果存了5个,按需分配存储空间,另外需要1-2字节,存储字符长度。

怎么选择:一般情况下 变长字符串就用varchar,固定长度一般采用char类型

enum() : 枚举类型
应用场景: 列中的数据,有限个数的值的时候,并且是有规律。
enum(‘bj’,‘sh’,‘tj’,…)
1 2

6.3 时间日期

DATETIME
范围为从 1000-01-01 00:00:00.000000 至 9999-12-31 23:59:59.999999。

TIMESTAMP
1970-01-01 00:00:00.000000 至 2038-01-19 03:14:07.999999。
timestamp会受到时区的影响

6.4 二进制

略。

6.5 json类型

略。

7.约束和其他表属性

Primary key : 主键约束 ,要求设置为主键的列,储值时,非空且唯一。每张表只有一个主键。
not null : 非空约束,必须录入值
unique key : 唯一约束,不能重复值
unsigned : 数字类型约束,无符号。

default : 设置默认值,一般配合not null 使用
auto_increment : 针对数字列,自动增长,一般配合主键
comment : 列或者表进行注释

8.DDL 应用

作用: 数据定义语言 。

8.1 库定义

创建库

CREATE DATABASE test CHARSET utf8mb4;
CREATE DATABASE wordpress;

查询库

SHOW DATABASES;
SHOW CREATE DATABASE test;
SHOW CREATE DATABASE wordpress;

修改库

ALTER DATABASE wordpress CHARSET utf8mb4;

删除库(生产禁用!!!!)

DROP DATABASE wordpress;

8.2 表定义

建表

USE test;
CREATE TABLE stu (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT ‘学号’,
sname VARCHAR(64) NOT NULL COMMENT ‘姓名’,
age TINYINT UNSIGNED NOT NULL DEFAULT 0 COMMENT ‘年龄’,
gender ENUM(‘m’,‘f’,‘n’) NOT NULL DEFAULT ‘n’ COMMENT ‘性别’,
intime DATETIME NOT NULL COMMENT ‘入学时间’
)ENGINE=INNODB CHARSET=utf8mb4 COMMENT ‘学生表’;

查表定义

SHOW TABLES;
SHOW CREATE TABLE stu;
DESC stu;

修改表定义

– 添加和删除字段
– 1. 在表中添加telnum char(11) not null unique key comment ‘手机号’
ALTER TABLE stu ADD COLUMN telnum CHAR(11) NOT NULL UNIQUE KEY COMMENT ‘手机号’;

– 2. 在sname后添加a列
ALTER TABLE stu ADD COLUMN a INT NOT NULL COMMENT ‘测试列’ AFTER sname;

– 3. 在第一列前添加b列
ALTER TABLE stu ADD COLUMN b INT NOT NULL COMMENT ‘测试列’ FIRST ;

– 4. 删除添加的a,b列
ALTER TABLE stu DROP COLUMN a;
ALTER TABLE stu DROP COLUMN b;

– 5. 修改数据类型
ALTER TABLE stu MODIFY telnum VARCHAR(20) NOT NULL UNIQUE KEY COMMENT ‘手机号’;
ALTER TABLE stu MODIFY telnum VARCHAR(30) NOT NULL UNIQUE KEY COMMENT ‘手机号’;

– 6. 修改列名及数据类型
ALTER TABLE stu CHANGE telnum tel VARCHAR(64) NOT NULL UNIQUE KEY COMMENT ‘手机号’;

删除表

drop table stu;

8.3 DDL语句开发规范

库:

CREATE DATABASE test CHARSET utf8mb4;

1. 库名要与业务有关
2. 库名不使用大写字母、数字开头。
3. 不要使用内置关键字
4. 建库要指定字符集。
5. 生产中禁止使用删库操作。

表:

CREATE TABLE stu (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT ‘学号’,
sname VARCHAR(64) NOT NULL COMMENT ‘姓名’,
age TINYINT UNSIGNED NOT NULL DEFAULT 0 COMMENT ‘年龄’,
gender ENUM(‘m’,‘f’,‘n’) NOT NULL DEFAULT ‘n’ COMMENT ‘性别’,
intime DATETIME NOT NULL COMMENT ‘入学时间’
)ENGINE=INNODB CHARSET=utf8mb4 COMMENT ‘学生表’;

  1. 表名:与业务有关,例如:wp_users,不使用大写字母、数字开头,不要太长(16以下)
  2. 设置存储引擎、字符集、表注释
  3. 表名、列名要使用内置关键字
  4. 列名要有意义,长度(16以下)
  5. 数据类型:合适的、足够的、简短
  6. 每个表要有主键,一般是自增长、无关列数字列。
  7. 每个列尽量是not null ,可以配合default
  8. 每个列要有注释
  9. 修改定义的操作,要在业务不繁忙期间去做。如果紧急可以使用pt-osc 。

9.DCL

grant
revoke

10.DML语句

10.1 作用:

针对表的数据行增删改查。

10.2 种类

insert
update
delete
select

10.3 insert 应用

USE test;
DESC student;

标准数据插入方式

INSERT student(id,NAME,age,gender,intime)
VALUES(1,‘zhangs’,18,‘M’,‘2020-07-02 08:30:00’);

SELECT * FROM student;

INSERT INTO
student(id,NAME,age,gender,intime)
VALUES
(2,‘zhang1’,18,‘M’,‘2020-07-01 08:30:00’),
(3,‘zhang2’,19,‘F’,‘2020-07-03 08:30:00’),
(4,‘zhang3’,17,‘M’,‘2020-07-05 08:30:00’),
(5,‘zhang4’,16,‘F’,‘2020-07-06 08:30:00’),
(6,‘zhang5’,15,‘M’,‘2020-07-07 08:30:00’);

省略写法

INSERT INTO
student
VALUES
(7,‘zhang6’,19,‘M’,‘2020-06-07 08:30:00’);

部分列录入

INSERT INTO
student(NAME,intime)
VALUES(‘ma6’,NOW());
SELECT * FROM student;

10.4 update 应用

UPDATE student SET NAME=‘马六’ WHERE id=8;

10.5 delete 应用

DELETE FROM student WHERE id=8 ;

– 彩蛋1: 伪删除的实现,使用update替代delete。

  1. 添加一个状态列 state

ALTER TABLE student ADD state TINYINT NOT NULL DEFAULT 1 ;

  1. update 替代 delete

UPDATE student SET state=0 WHERE id=9;

  1. 查询语句修改为

SELECT * FROM student WHERE state=1;

–彩蛋2: 以下三条语句的功能及区别?
drop table t1 ; —> 表定义+表数据(物理),全删除,磁盘空间立即删除
truncate table t1 ; —> 清空表数据(物理),立即释放磁盘空间。
delete from t1; —> 逐行删除表数据(逻辑,delete mark)。不会立即释放磁盘空间,会有碎片。

11.DQL 语句

11.1 select

11.1.1 作用:

获取用户表中的数据行。

11.1.2 select 独立使用

查询系统变量(参数)

SELECT @@port;
SELECT @@basedir;
SELECT @@datadir;
SELECT @@server_id;
SELECT @@innodb_flush_log_at_trx_commit;
#替代方案:
SHOW VARIABLES;
SHOW VARIABLES LIKE ‘%trx%’;

查询用户变量

SET @oldguo=100;
SELECT @oldguo;

查询函数

SELECT VERSION();
SELECT USER();
SELECT NOW();
SELECT CONCAT(“hello world”)
SELECT CONCAT(USER ,"@",HOST) FROM mysql.user;

11.1.3 select 通用使用方法

单表查询的语法结构

/*
select 列
from 表
where 条件
group by 条件
having 条件
order by 列
limit 条件;
*/

导入world练习库

– https://dev.mysql.com/doc/index-other.html
– [root@db01 ~]# mysql -uroot -p123 < world.sql

了解业务

1. 查看列的信息

USE world;
DESC city;
SHOW CREATE TABLE city;
/*
id : 主键列,自增长1-N。
name : 城市名字
countrycode: 城市所在国家编码(3字母,CHN、USA)
District :城市所在区域(省、州、县)
Population :城市人口
*/

2. 查询表中部分数据

SELECT * FROM city LIMIT 10;

3. 找开发沟通获取信息

select + from 应用

– 1. 查询全表数据(不代表生产操作) —> cat /etc/passwd
SELECT * FROM city;
– 2. 查询部分列数据 —> awk $2 $5
SELECT NAME,population FROM city;

select + from + where 应用

1. where 配合等值查询

– 例子: 查询中国(CHN)所有的城市信息
SELECT * FROM city
WHERE countrycode=‘CHN’;
– 例子: 查询美国(USA)所有的城市名和人口数
SELECT NAME,population FROM city
WHERE countrycode=‘USA’;

2. where 配合不等值查询 (> < >= <= !=)

– 例子: 查询世界上人口数据小于100人的城市信息
SELECT * FROM city
WHERE population<100;

3. where 配合 and or ,between and ,in 使用

– 例子:查询中国,并且人口大于500w的城市信息
SELECT * FROM city
WHERE countrycode=‘CHN’ AND population>5000000;

– 例子: 查询中国或美国的城市信息
SELECT * FROM city
WHERE countrycode=‘CHN’ OR countrycode=‘USA’;
— 等价写法
SELECT * FROM city
WHERE countrycode IN (‘CHN’,‘USA’);

– 例子: 查询人口数量在 100w-110w之间
SELECT * FROM city
WHERE population >=1000000 AND population<=1100000;
— 等价写法
SELECT * FROM city
WHERE population BETWEEN 1000000 AND 1100000;

4. where 配合 like应用

– 查询countrycode是 “CH” 开头的城市信息
SELECT * FROM city
WHERE countrycode LIKE ‘CH%’;

select + from + where + group by + 聚合函数 应用

– 1. 需求 :1000人在一个广场上,要求快速统计每个省的学生数量?
– 1. 站队。分组
– 2. 数数

– 2. group by + 聚合函数的执行逻辑?
– 1. 按照group by的列进行排序+去重复
– 2. 讲其他的查询列进行聚合操作
– 3. 1+2 显示给用户

– 聚合函数种类:
/*
count() : 统计个数
sum() : 求和
avg() :平均值
max() :最大值
min() :最小值
group_concat():列转行:

*/

– 例子1 : 统计city表,每个国家的城市个数

SELECT countrycode,COUNT(*)
FROM city
GROUP BY countrycode;

– 例子2 : 统计city表,中国 每个省的 城市个数
SELECT district,COUNT(*)
FROM city
WHERE countrycode=‘CHN’
GROUP BY district;

– 例子3 : 统计city表,每个国家的总人口数
SELECT countrycode,SUM(population)
FROM city
GROUP BY countrycode;

– 例子4 : 统计city表,中国 每个省的总人口数
SELECT district,SUM(population)
FROM city
WHERE countrycode=‘CHN’
GROUP BY district;

– 例子5 : 统计city表,中国 每个省的 城市个数 ,所有城市名
SELECT district,COUNT(*) ,GROUP_CONCAT(NAME)
FROM city
WHERE countrycode=‘CHN’
GROUP BY district;

5.select + from + where + group by + 聚合函数 + having 应用

– 例子: 统计city表,中国 每个省的总人口数,显示总人口数超过500w的信息
SELECT district,SUM(population)
FROM city
WHERE countrycode=‘CHN’
GROUP BY district
having SUM(population)>5000000;

select + from + where + group by + 聚合函数 + having +order by

– 例子: 统计city表,中国 每个省的总人口数,显示总人口数超过500w的信息,并按照总人口排序输出。

SELECT district,SUM(population)
FROM city
WHERE countrycode=‘CHN’
GROUP BY district
HAVING SUM(population)>5000000
order by SUM(population);

SELECT district,SUM(population)
FROM city
WHERE countrycode=‘CHN’
GROUP BY district
HAVING SUM(population)>5000000
ORDER BY SUM(population) desc ;

select + from + where + group by + 聚合函数 + having +order by + limit

– 例子: 统计city表,中国 每个省的总人口数,显示总人口数超过500w的信息,并按照总人口从大倒小排序输出
– 只显示前5名。

SELECT district,SUM(population)
FROM city
WHERE countrycode=‘CHN’
GROUP BY district
HAVING SUM(population)>5000000
ORDER BY SUM(population) desc
limit 5 offset 0 ;

– 只显示6-10名。
SELECT district,SUM(population)
FROM city
WHERE countrycode=‘CHN’
GROUP BY district
HAVING SUM(population)>5000000
ORDER BY SUM(population) DESC
LIMIT 5,5;

SELECT district,SUM(population)
FROM city
WHERE countrycode=‘CHN’
GROUP BY district
HAVING SUM(population)>5000000
ORDER BY SUM(population) DESC
LIMIT 5 offset 5;

多表连接查询

1. 预备工作

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

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

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

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

INSERT INTO student(sno,sname,sage,ssex)
VALUES
(1,‘zhang3’,18,‘m’),
(2,‘zhang4’,18,‘m’),
(3,‘li4’,18,‘m’),
(4,‘wang5’,19,‘f’),
(5,‘zh4’,18,‘m’),
(6,‘zhao4’,18,‘m’),
(7,‘ma6’,19,‘f’),
(8,‘oldboy’,20,‘m’),
(9,‘oldgirl’,20,‘f’),
(10,‘oldp’,25,‘m’);

INSERT INTO teacher(tno,tname) VALUES
(101,‘oldboy’),
(102,‘hesw’),
(103,‘oldguo’)
(104,‘alex’);

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

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

2.多表连接的类型
– 笛卡尔乘积

mysql> select * from teacher , course;

±----±-------±-----±-------±----+
| tno | tname | cno | cname | tno |
±----±-------±-----±-------±----+
| 101 | oldboy | 1001 | linux | 101 |
| 102 | hesw | 1001 | linux | 101 |
| 103 | oldguo | 1001 | linux | 101 |
| 104 | alex | 1001 | linux | 101 |
| 101 | oldboy | 1002 | python | 102 |
| 102 | hesw | 1002 | python | 102 |
| 103 | oldguo | 1002 | python | 102 |
| 104 | alex | 1002 | python | 102 |
| 101 | oldboy | 1003 | mysql | 103 |
| 102 | hesw | 1003 | mysql | 103 |
| 103 | oldguo | 1003 | mysql | 103 |
| 104 | alex | 1003 | mysql | 103 |
| 101 | oldboy | 1004 | go | 105 |
| 102 | hesw | 1004 | go | 105 |
| 103 | oldguo | 1004 | go | 105 |
| 104 | alex | 1004 | go | 105 |
±----±-------±-----±-------±----+

– 内连接 (取交集)

SQL92:
mysql> select *from teacher , course where teacher.tno=course.tno;
SQL99:
mysql> select *from teacher join course on teacher.tno=course.tno;
±----±-------±-----±-------±----+
| tno | tname | cno | cname | tno |
±----±-------±-----±-------±----+
| 101 | oldboy | 1001 | linux | 101 |
| 102 | hesw | 1002 | python | 102 |
| 103 | oldguo | 1003 | mysql | 103 |
±----±-------±-----±-------±----+

– 外连接 (左、右)

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

mysql> select * from teacher right join course on teacher.tno = course.tno;
±-----±-------±-----±-------±----+
| tno | tname | cno | cname | tno |
±-----±-------±-----±-------±----+
| 101 | oldboy | 1001 | linux | 101 |
| 102 | hesw | 1002 | python | 102 |
| 103 | oldguo | 1003 | mysql | 103 |
| NULL | NULL | 1004 | go | 105 |
±-----±-------±-----±-------±----+

3. 多表连接语法格式

select xxx
from a join b
on a.x=b.y
where
group by
having
order by
limit

select xxx
from a join b
on a.x=b.y
join c
on b.z=c.zz

核心思路:
1.找到所有相关表
2.找到所有表之间的关联关系
3.罗列其他的查询条件

4.多表连接例子:

— 统计学员zhang3,学习了几门课
SELECT student.sname,COUNT(*)
FROM student JOIN sc
ON student.sno =sc.sno
WHERE student.sname=‘zhang3’;

— 所有学员学习的课程门数
SELECT student.sname,COUNT(*)
FROM student JOIN sc
ON student.sno =sc.sno
GROUP BY student.sname;

— 查询zhang3,学习的课程名称有哪些?
SELECT student.sname,GROUP_CONCAT(course.cname)
FROM student
JOIN sc
ON student.sno=sc.sno
JOIN course
ON sc.cno=course.cno
WHERE student.sname = ‘zhang3’
GROUP BY student.sname;

– 课堂练习:
— 查询oldguo所教课程的平均分数
SELECT teacher.tname ,AVG(sc.score) FROM
teacher
JOIN course
ON teacher.tno=course.tno
JOIN sc
ON course.cno=sc.cno
WHERE teacher.tname=‘oldguo’
GROUP BY teacher.tname;

— 每位老师所教课程的平均分,并按平均分排序
SELECT teacher.tname ,AVG(sc.score) FROM
teacher
JOIN course
ON teacher.tno=course.tno
JOIN sc
ON course.cno=sc.cno
GROUP BY teacher.tname
ORDER BY AVG(sc.score);

— 查询oldguo所教的不及格的学生姓名

SELECT teacher.tname,GROUP_CONCAT(student.sname) FROM
teacher
JOIN course
ON teacher.tno=course.tno
JOIN sc
ON course.cno=sc.cno
JOIN student
ON sc.sno=student.sno
WHERE teacher.tname=‘oldguo’ AND sc.score<60
GROUP BY teacher.tname ;

— 查询所有老师所教学生不及格的信息
SELECT teacher.tname,GROUP_CONCAT(student.sname) FROM
teacher
JOIN course
ON teacher.tno=course.tno
JOIN sc
ON course.cno=sc.cno
JOIN student
ON sc.sno=student.sno
WHERE sc.score<60
GROUP BY teacher.tname ;

别名的使用

– 表别名
SELECT a.tname,GROUP_CONCAT(d.sname) FROM
teacher AS a
JOIN course AS b
ON a.tno=b.tno
JOIN sc AS c
ON b.cno=c.cno
JOIN student AS d
ON c.sno=d.sno
WHERE c.score<60
GROUP BY a.tname ;

– 列别名
SELECT a.tname AS aa ,GROUP_CONCAT(d.sname) AS bb FROM
teacher AS a
JOIN course AS b
ON a.tno=b.tno
JOIN sc AS c
ON b.cno=c.cno
JOIN student AS d
ON c.sno=d.sno
WHERE c.score<60
GROUP BY a.tname ;

SELECT teacher.tname AS ‘老师名’ ,AVG(sc.score) AS ‘平均分’ FROM
teacher
JOIN course
ON teacher.tno=course.tno
JOIN sc
ON course.cno=sc.cno
GROUP BY teacher.tname
ORDER BY 平均分;

课后作业:

  1. 查询平均成绩大于60分的同学的学号和平均成绩;
  2. 查询所有同学的学号、姓名、选课数、总成绩;
  3. 查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分
  4. 统计各位老师,所教课程的及格率
  5. 查询每门课程被选修的学生数
  6. 查询出只选修了一门课程的全部学生的学号和姓名
  7. 查询选修课程门数超过1门的学生信息
  8. 统计每门课程:优秀(85分以上),良好(70-85),一般(60-70),不及格(小于60)的学生列表
  9. 查询平均成绩大于85的所有学生的学号、姓名和平均成绩

=====

11.2 元数据的获取

11.2.1 元数据包含什么?

数据字典信息(表属性、列、列属性)、状态、系统参数、权限等。
ibdata1 、 frm 、 mysql库(权限表、状态表、统计信息) 、 P_S、SYS表

11.2.2 查询换数据方法

show 语句

help show
show databases;
show tables [from DB];
show create database world;
show craete table world.city;
show full processlist;
show engines;
show charset;
show collation;
show variables [like ‘%%’]
show status [like ‘%%’]
show grants for
SHOW OPEN TABLES
SHOW INDEX FROM tbl_name
SHOW MASTER STATUS
SHOW BINLOG EVENTS
SHOW RELAYLOG EVENTS
SHOW SLAVE STATUS
SHOW SLAVE HOSTS

information_schema 视图库

每次数据库启动,自动在内存中生成的“虚拟表”(视图)。
保存了各种常用元数据查询方法的视图,只能查询不能修改和删除。

TABLES 使用

1. 结构介绍

作用:存储了整个MySQL中所有表相关属性信息
desc tables;
TABLE_SCHEMA : 所在库
TABLE_NAME : 表名
ENGINE : 存储引擎
TABLE_ROWS : 数据行
AVG_ROW_LENGTH : 平均行长度
INDEX_LENGTH : 索引的长度
DATA_FREE : 碎片的情况

2. 应用案例

– 例子1: 统计MySQL所有业务库:库名、表个数、表名
select table_schema,count(*),group_concat(table_name)
from information_schema.tables
where table_schema not in (‘mysql’,‘sys’,‘information_schema’,‘performance_schema’)
group by table_schema ;

– 例子2: 统计MySQL所有业务库:库名、数据总量(单张表:TABLE_ROWS*AVG_ROW_LENGTH+INDEX_LENGTH)

select table_schema,sum(TABLE_ROWS*AVG_ROW_LENGTH+INDEX_LENGTH)/1024/1024 as sum_mb
from information_schema.tables
where table_schema not in (‘mysql’,‘sys’,‘information_schema’,‘performance_schema’)
group by table_schema ;

– 例子3:
生产案例:客户MySQL系统 经历的很多个版本 5.1 --》 5.5 —》 5.6。。。
系统中有2000-3000张表,其中有myisam、innodb两种存储引擎类型。
需求1: 查找业务库中,所有非InnoDB表

select table_schema,table_name,engine
from information_schema.tables
where table_schema not in (‘mysql’,‘sys’,‘information_schema’,‘performance_schema’) and engine !=‘innodb’;

需求2: 将所有这些表备份走
mysqldump -uroot -p123 test t1 >/data/test_t1.sql

select concat(“mysqldump -uroot -p123 “,table_schema,” “,table_name,” >/data/”,table_schema,"_",table_name,".sql")
from information_schema.tables
where table_schema not in (‘mysql’,‘sys’,‘information_schema’,‘performance_schema’) and engine !=‘innodb’
into outfile ‘/tmp/dump.sh’;

需求3: 将以上表替换为InnoDB引擎
alter table test.t1 engine=innodb;

select concat(“alter table “,table_schema,”.”,table_name," engine=innodb;")
from information_schema.tables
where table_schema not in (‘mysql’,‘sys’,‘information_schema’,‘performance_schema’) and engine !=‘innodb’
into outfile ‘/tmp/alter.sql’;

[root@db01 ~]# sh /tmp/dump.sh
[root@db01 ~]# cd /data/
[root@db01 data]# ll
-rw-r–r-- 1 root root 1741 Jul 2 18:30 test_t1.sql
-rw-r–r-- 1 root root 1741 Jul 2 18:30 world_t2.sql
[root@db01 data]# mysql -uroot -p123

mysql> select table_schema,table_name,engine from information_schema.tables where table_schema not in (‘mysql’,‘sys’,‘information_schema’,‘performance_schema’) and engine !=‘innodb’;
Empty set (0.00 sec)

你可能感兴趣的:(数据库学习)