文章目录
-----转自 【王者-YCZ】的笔记
知识体系介绍
数据库介绍
体系结构及管理
SQL开发规范和建议
索引及执行计划(查询优化)
存储引擎
日志和备份恢复
主从
架构
一、数据库介绍
1.数据库产品介绍
第一代: RDBMS , Oracle, DB2,MSSQL ,PG,MySQL
第二代: RDBMS+NoSQL+数据库中间件
NoSQL : redis ,MongoDB,Hadoop,Hbase,ES,CD
数据库中间件: 读写分离(proxySQL,maxscale,MyCAT),分布式(MyCAT,DBLE)
云数据库产品
第三代: NewSQL: PolarDB , TDB ,TiDB
RDBMS:关系数据库管理系统
查看数据库排名:http://www.db-engines.com/ranking
2.MySQL版本介绍与区别
1.推荐使用版本
5.6 : 5.6.33 5.6.34 5.6.36 5.6.38 5.6.40
5.7 : 5.7.18 5.7.19 5.7.20 5.7.22 5.7.24 5.7.26
8.0 : 8.0.11之后的版本均可
较为推荐使用:GA后6-12月之间的版本
较为推荐二进制的版本:二进制版的好处是所有的软件都装在一个目录下,都在/usr/local里面,不像yum,四零八散。
2.版本之间的区别(5.6与5.7与8.0)
a.初始化数据:
(5.7的命令)
/usr/local/mysql/bin/mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql/data
(5.6的命令)
/usr/local/mysql/scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql/data
b.安全方面:
5.7版本安全方面得到了加强,具体体现在(1)密码长度、(2)密码复杂度、(3)密码过期时间、
(4)两种初始化: --initialize-insecure 无安全模式, --initialize 安全模式
c.用户管理方面:
8.0版本以前可以直接使用grant创建用户并且授权;8.0版本以后必须先创建用户,再授权。
d.严格模式SQL_MODE:
5.7及其之后的版本拥有严格模式,在存储数据时,存储超出长度的数据不会存进去,会直接报错;
而5.6版本由于没有严格模式,在存储超出长度的数据时,会将数据截断为可以存储的最大长度存储。
二、体系结构和基础管理
1.基于C/S 模型
Linux下的mysql可以使用两种协议方式建立数据库连接:TCP/IP、Socket
Windows下的mysql可以使用两种方式建立数据库连接:TCP/IP、sharememory(共享内存)
示例(Linux):
TCP/IP(远程、本地):
mysql -uroot -p123 -h 10.0.0.51 -P 3306
Socket(仅本地):
mysql -uroot -p123 -S /tmp/mysql.sock
2.mysql实例
MySQL独占内存,是基于线程管理的
实例: mysqld + MasterThread + 干活Thread + 预分配内存
类比
公司: 老板+经理+员工+办公区
实例中的mysqld是守护进程,先启动它,再通过他再来启动其他干活的线程,并预分配内存。
3.mysqld的程序结构(一条SQL语句的执行过程) ---------重要
连接层
- 提供连接协议
TCP/IP
socket文件 - 用户验证
- 分配连接线程
接受用户SQL
返回用户结果
SQL层
- 语法语义检查
- 对象权限检查
- SQL_MODE检查
- 解析---->解析树
- 预处理
- 优化器(代价最低)
- 执行,得出结果
- 缓存到query_cache,生产中实际是用第三方,如Redis,memcached,Tair缓存产品替代。
- 日志记录(binlog):变更类语句日志记录,备份恢复和主从复制。
存储引擎层
通过执行的结果,从磁盘上拿数据,结构化成表,显示出来。
流程解析:
连接层部分:
1.数据库一启动,连接层就会提供两种连接协议(TCP/IP,Socket);
2.然后就验证用户的ip,端口,密码;
3.验证完成后,立马会给用户分配的一个专门的连接线程(每一个用户都会分配一个新的连接线程),
线程是用来接收用户请求的,也就是接收用户的SQL语句命令,然后提供返回结果;
4.连接层是不具体负责SQL语句处理的,要交给SQL层来处理;
SQL层部分:
1.SQL层拿到连接层传过来的SQL语句,先做语法分析,分析语法正确与否;
2.然后再做语义检查,检查是属于什么类型的语句,如DDL,DCL等等;
3.然后做用户对象的权限检查,查看该用户是否拥有权限;
4.接着是进行SQL_MODE的检查,严格、标准化数据的插入;
5.6及之前的版本没有严格模式,如时间字段依然可以录入毫无意义的时间;
5.7及之后的版本拥有严格模式,只要发现是违反数据类型的值,就会报SQL_MODE的错误;
总的来说,SQL_MODE检查就是检查插入数据有没有意义,合不合法,符不符合科学常识。
5.然后,是对SQL语句进行解析,解析时会生成解析树;
6.解析完后再进行预处理,也就是计算各个处理方式的代价模型,即消耗的资源;
7.然后交给优化器选出代价最低的处理方式,即开销最低的处理方式;
8.最后,通过优化器选择的处理方式执行该SQL语句,并且得出结果。
存储引擎层:
1.通过获取SQL层执行的结果,从磁盘上拿取数据(拿取后的数据是二进制的数据),再将二进制的数据结构化成表,显示出来。
最后,其实在SQL层部分还做了两件事情:
第一件事是查询缓存query_cache:
第一次执行SQL语句,会将它生成一个哈希值,带着哈希值和查询结果,缓存到query_cache中。
第二件事是日志记录(binlog):
Mysql日常工作中会对变更类语句进行日志记录。
关于缓存:
缓存功能是默认关闭,8.0版本以前可以手动开起来用,8.0版本以后取消了;
因此,生产环境中,一般通过Redis,memcached,Tair缓存产品来替代。
关于日志记录(binlog):
默认情况下,日志记录功能是关闭的;
binlog是备份恢复和主从复制所必须的一个日志。
4.MySQL的逻辑结构
库: 库名 + 库属性(字符集+校对规则)
表: 表名 + 表列(列名+数据类型+约束+其他属性) + 表行(记录) + 表属性(引擎+字符集+校对规则)
5.MySQL的物理结构
宏观物理结构
InnoDB :
xxx.ibd 数据行和索引
xxx.frm 表结构
MyISAM :
xxx.MYI 索引信息
xxx.MYD 数据行
xxx.FRM 表结构
5.5.6版本及之后的版本,默认的存储引擎是InnoDB
InnoDB微观物理结构
表空间数据文件:
段 : 一个表(非分区表)就是一个段。
页 : 一个page默认是16KB,是MySQL最小的IO单元
区 : 64个连续页,默认1M
系统磁盘扇区 512b
block 4kb
mysql_页 16kb
mysql_分区 1Mb,64个连续页
数据库优化:归根结底就是优化io,一方面是优化次数(IOPS),一方面是优化顺序。
常规优化: 人 ----> SQL语句 ----> IO(顺序,次数) ----> 底层
架构思维: 分布式架构
6.用户,权限,连接,初始化配置,启动
用户
1.定义:
名字@'白名单'
白名单:可以允许登录MySQL的IP
oldguo@'localhost' 本地socket登录的用户
oldguo@'%' 所有远程用户
oldguo@'192.168.195.%' 允许某个网段ip(255.255.255.0)的用户
oldguo@'192.168.195.0/255.255.254.0' 允许某个子网的IP的用户
oldguo@'192.168.195.5%' 允许192.168.195.50-59IP的用户
2.操作:
crete user 用户信息 identified by '密码'; 创建用户
drop user 用户信息; 删除用户
alter user 用户信息 identified by '新密码'; 更改用户密码
select user,host ,authentication_string from mysql.user; 查询用户信息
权限
1.用户授权命令:
grant 权限 on 范围 to 用户 identified by '密码'
2.用户收回权限命令:
revoke 权限 on 范围 from 用户;
3.权限种类(ALL):
SELECT,INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE
4.在授权命令加上with grant option,可以让授权的用户也可以进行授权的操作:
grant 权限 on 范围 to 用户 identified by '密码' with grant option;
5.范围:
*.* 所有库所有表
oldguo.* 某个库
oldguo.t1 某个库中的某个表
6.mysql中权限的授权是相加操作,因此才会有收回权限的操作;
mysql中权限是用户的属性,linux中权限是文件和目录的属性。
连接
1.mysql自带的工具:
mysql
mysqldump
2.第三方工具:
navicat
powerdesigner(建模工具)
3.mysql连接常用参数
-u 用户
-p 密码
-h IP
-P 端口
-S socket文件
-e 免交互执行命令
< 导入SQL脚本
初始化配置
1.初始化配置的方法:
a.配置文件 (常规)
b.命令行 (维护性操作)
c.源码编译时
2.配置文件的格式:
[标签]
配置=xxxx
3.标签:
a.服务器端标签
[server] [mysqld] [mysqld_safe]
b.客户端标签
[client] [mysql] [mysqldump]
c.常用
[mysqld] : 主要控制服务器启动,正常工作模式
[mysql] : 主要影响本地客户端
4.配置文件的示例:
vim /etc/my.cnf
[mysqld]
user=mysql
basedir=/usr/local/mysql
datadir=/data/mysql/data
server_id=10
port=3306
socket=/tmp/mysql.sock
[mysql]
socket=/tmp/mysql.sock
启动
1.脚本启动(自带)
cd /usr/local/mysql/support-files
./mysql.server stop 停止
./mysql.server start 开启
./mysql.server restart 重启
2.特殊启动方式(维护操作)
mysqld_safe
mysqld
示例:忘记本地管理员密码的处理方法
1.关闭MySQL
cd /usr/local/mysql/support-files
./mysql.server stop、
2.启动到安全模式
mysqld_safe --skip-grant-tables --skip-networking &
3.修改密码
flush privileges;
alter user root@"localhost" identified by "123";
4.重启数据库到正常模式
mysqld restart
解析:
--skin-grant-tables 跳过连接层密码验证;
--skip-networking 停掉连接层远程连接;
登陆后没加载授权表,改不了密码;
因此要flush privileges手动刷新授权表,才能修改密码。
3.多实例
1.准备目录
mkdir -p /data/3307/data
2.授权
chown -R mysql.mysql /data
3.配置文件
vim /data/3307/my.cnf
[mysqld]
user=mysql
basedir=/usr/local/mysql
datadir=/data/3307/data
server_id=20
port=3307
socket=/tmp/mysql3307.sock
4.初始化数据
mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql --datadir=/data/3307/data
5.启动3307端口的mysql
mysqld_safe --defaults-file=/data/3307/my.cnf &
6.本地连接
mysql -S /tmp/mysql3307.sock
some command
查看mysql当前会话信息
show processlist
查看非innodb引擎的数据表
select table_schema,table_name,engine from information_schema.tables
where engine != 'innodb';