数据库:
程序=指令 + 数据
数据结构:变量,数组
I/O :
提供数据,保存数据
文件,交互式输入
持久存储
文件:
数据冗余和不一致性
数据访问困难
数据孤立
原子性问题
并发访问异常
安全性问题
DBMS:
层次型:倒装型
网状型:不易于开发,管理,都在一块混着
关系型:二维数据表(字段,记录)
RDBMS:关系型管理工具
Sybase + Microsoft
SQL Server
Informix --> IBM
DB2
Oracle <--- SUN
MySQL
MySQL --- > MariaDB
percona公司:---> xtradb(增强版的innodb)-->用于MariaDB
webscaledb -——>为web产生的web数据库
PsotgreSQL ,pgsql(性能优秀,但是市场决定一切)
C/S架构:
mysql --> mysqld
(mysql协议)
sqlite:(工作有本地的,关系型数据库接口,引擎,把数据组织成表格形似
数据库使用:
1、直接使用交互式接口;
2、使用开发程序软件:
可调用的客户端:API
sqlite:客户端和服务器端在一块,不需要C/S通信了,数据保存在一个lib中,包括元数据等信息,同时又可以加载用以自己理解的形式查看
dbm:把数据保存成散列形式(哈希)
SQL:structure query language
DDL:定义
CREATE,DROP,ALTER
DML:操作语言
INSERT,UPDATE,DELETE
DCL:控制
GRANT,REVOKE
DQL:查询
SELECT
事务:
ACID
A:原子性 ---> 要不执行,要不都执行 ,整个事务中的所有操作要么全部成功执行,要么全部失败后回滚
C:一致性 ---> 数据库总是从一个一致性状态转换为另一个一致性状态
I:隔离性 ---> 一个事务的所有修改操作在提交之前对其它事务是不可见的
D:持久性 ---> 一旦事务得到提交,其所做的修改会永久有效
提交:持久
未提交:提交,回滚
隔离:隔离级别
read uncommitted 读未提交
read committed 读提交
repeatable read :可重读
serializable:串行化
MySQL:存储引擎:
MyISAM:无事务
分离索引:数据和索引分开
InnoDB:事务型
聚簇索引:数据和索引放一块
机械式硬盘:(对内存来讲,两种读写都是一样的)
随机读写:慢,磁盘指针转动需要时间
顺序读写:
SQL:支持xml,可以输出为xml文件
规范:ANSI定义
SQL-86,89,92,99,03
关系数据库的约束:
主键约束,外键,唯一键,条件约束,非空约束
约束:constraint,向数据表提供的数据要遵守的限制;
主键:一个或多个字段的组合,填入的数据必须能在本表中唯一标识本行;必须提供数据,即NOT NULL;
一个表只能存在一个
惟一键:一个或多个字段的组合,填入的数据必须能在本表中唯一标识本行;允许为NULL;
一个表可以存在多个
外键:一个表中的某字段可填入数据取决于另一个表的主键已有的数据;
检查性:字段值在一定范围内
索引:将表中的一个或多个字段中的数据复制一份另存,并且此些需要按特定次序排序存储;
关系运算:
选择:挑选出符合条件的行(部分);
投影:挑选出需要的字段;
连接:表间字段的关联
数据抽象:
物理层:决定数据的存储格式,即RDBMS在磁盘上如何组织文件;
逻辑层:描述DB存储什么数据,以及数据间存在什么样的关系;
视图层:描述DB中的部分数据;
关系模型的分类:
关系模型
实体-关系模型
基于对象的关系模型
半结构化的关系模型
DBA:
开发:
数据库设计
代码设计 :存储过程,存储函数,触发器
管理:
连接管理及优化
备份及还原
数据库设计
基本语句优化
用户即权限管理
安全管理
数据库软件安装和升级
配置优化
MySQL:
高性能,完全多线程,查询缓存(小规模)
支持复制(伸缩性)
Product Family:
MySQL server(mysqld,mysql)
MySQL Cluster
MySQL Proxy
MySQL Adminitrator
MySQL Query Browser
MySQL Workbench
MySQL Arch:
真正执行SQL的是优化器之后的存储引擎,所以一个库支持一个引擎
MySQL安装:
rpm
源码编译
通用二进制(已经编译好的)
版本:
GA:
RC: 即将变为GA
beta:共测
alpha:内侧
rpm安装:client , server, shared, shared-compat
二进制安装:
插件式引擎
三种默认服务,mysqld,mysqld-safe,mysql-mtuil
默认开始的是safe
约束:
主键约束:
不能重复,不能为NULL,有且只能有一个
外键约束
唯一键约束
可以有多个,唯一,可能为NULL
检查是约束
用户自定义有效取值范围
键:(字段)
主键:能够 唯一 标识表中每一个记录的字段或字段的组合(不能重复,不能为NULL)
候选键:可以挑来做主键的组合,但是没选
初始化:提供配置文件
配置文件 .cnf
集中式的配置,多个应用程序共用的配置文件
[mysqld]:
[mysql_safe]
[client]
# ./usr/local/mmysql/bin/mysqld --help -v | head -20
# 读取配置文件的顺序
Default options are read from the following files in the given order:
/etc/mysql/my.cnf /etc/my.cnf ~/.my.cnf
使用配置文件的方式:
1、它一次查找每个需要查找的文件,结果多有文件的并集
2、如果某参数出现多次,后去读取的生效
# ./usr/local/mmysql/bin/mysqld --help -v
1、显示 mysql程序启动时可用的选项,通常是长选项
2、显示mysql的配置文件中可用的服务变量
SHOW GLOBAL VARIABLES
SHOW SESSION VARIABLES
初始化的第二个操作:
1、删除所有的匿名用户
DROP USER ''@loaclhost
DROP USER ''@node2
用户账号有两部分组成: user@hostname
host可以使用通配符
%:任意长度的字符串
_:下划线匹配任意单个字符
2、给所有的root用户设定密码
第一种方式:
SET PASSEORD FOR usernam@host = PASSEWORD('1231')
第二种范式:比较妥当的方式
UPFATE user SET password = PASSWORD('12345') WHERE user='root';
FLUSH PRIVILEGES;
第三种方式:
mysqladmin -uUserName -hHost -p password 'new_password'
mysqladmin -uUserName -hHost -p flush-privileges;
接入mysql服务器:
mysql client <----> mysql protocol ---> mysqld
mysqld 接受连接请求L:
本地通信:客户端与服务器端在同一个主机,而且还要基于127.0.0.1(localhost)地址或lo接口进行通信
Linux和UNix:unix sock /var/lib/mysql/mysql.sock
windows:本地通信:共享内存,管道通信---memory,pipe
远程通信:客户端与服务器位与不同的主机,或在同一主机使用非 本地回环地址通信
tcp socket
客户端工具:
mysql,mysqladmin,mysqldump,mysqlcheck
有[client]段,其中的所有项,对以上工具都是生效的。
通行的选项:
-u
-h
-p, --password
--protocol = {tcp|scok|pipe|memory}
后三者都是本地,后两者是windows上
--port 端口
--socket :指定文件名(本地通信)
mysql监听端口:tcp/3306
非客户端类的管理工具:
myisamchk, myisampack
第一个是检查工具
第二个是打包工具
mysql:
交互式模式:
脚本模式:输入重定向
mysql < /path/mysql.mysql
交互式模式:
客户端命令:不要分号
help:查看命令
C:不执行命令(命令结束符之前使用)
G:Send command to mysql server, display result vertically.
g:Send command to mysql server.
q:Exit mysql. Same as quit.
! :Execute a system shell command
s: Get status information from the server.
. 导入mysql脚本
服务器端命令:需要命令结束符,默认分号
help 关键字:查看帮助
help contents:内容列表,获取整体,获取某个,跟上具体的名字
mysql命令行选项:
--compress:压缩传输
--default-character-set:默认字符集(mysql客户端),用的很少,避免与服务器端不同的编码方式
-v
-V:
--ssl-ca:ca证书文件
--ssl-capath:多个ca证书,自动寻找
--ssl-cipher:冒号分割是加密方式
--ssl-verify-server-cert:验证服务器端证书
-D /--database= :直接指定要使用的库
mysql命令提示符:
mysql> 等待输入命令
'>
">
`>
/*> 注释 */ 结束
-> :续航
支持光标移动:
crtrl + w:删除 光标之前的单词
ctrl + u: 删除光标之前至命令行之前的所有内容
ctrl + y:恢复之前删除的内容
ctrl + a:行首
ctrl + e:行尾
-A:禁用命令补全
/#: 启用
当前用户家目录下 ~/.mysql.history: 命令历史
mysql的输出格式:
-H:
mysql -H -uroot -p 进入之后,执行的命令结果都是html格式的
-X:输出格式为xml
--safe-updates:实现发送命令时拒绝 没有where 或update 命令,如果后弦限制了行数的话,也可以执行
mysqladmin工具:
mysqladmin [options] command
command:
create:创建库
mysqladmin -uroot -p create mydb :不需要登录创建库
mysql -uroot -p -e show databases;直接查看库
drop dbName:删除库
debug:打开调试日志,并记录与mysql的error log中
status:输出状态信息
mysqladmin -uroot -p status --sleep 1 --count 5:间隔时长,显示的批次
extended-status :相当于show global status 输出mysql的各状态变量及其值
variables:mysql的各服务器变量
flush-hosts:清空主机缓存
DNS解析缓存,此前因为连接错误次数过多而被拒绝访问mysql的主机
flush-logs:日志滚动(二进制日志,中继日志)
refresh:相当于同时使用 flush-hosts, flush-logs
flush-ptivileges:重载授权表
reload
flush-status:重置状态变量,不是清空,只把启动到现在的一些变量信息归0
flush-tables:关闭当前打开的表文件句柄(手动加锁的时候用)
flush-treads:清空线程缓存
kill :杀死指定的线程(线程ID),使用逗号分隔,不能有多余的空白字符
password:修改指定用户密码
ping:服务器是否在线
processlist:各线程信息
shutdown:关闭mysql进程
start-slave:启动从服务器线程
stop-slave:关闭
GUI客户端工具:
Navicat for mysql: 之前公司用的
SQLyog
phpMyAdmin
MySQL Front
开发DBA:
数据库设计(E-R关系图) sql开发,内置函数,存储例程(存储过程和存储函数)--尽量在服务器端执行,触发器(自动执行),事件调度器(event sechduler)
管理DBA:
安装, 升级,卸载,备份,恢复,用户管理,权限管理,监控,测试,分析,语句优化(sql语句),配置服务器(服务器变量,定制存储引擎参数,内置缓存,日志),数据字典,
SQL语言的组成部分:
DDL:数据定义语言
DML:数据操作语言
完整性定义语言:DDL的一部分功能
主键约束,外键约束(不是所有的引擎支持),条件约束,唯一键约束,非空约束,事物约束
视图定义:虚表,存储下来的的select语句
事务控制:
动态sql 和 嵌入sql
DCL:控制(授权)
数据类型的作用:
1、存储的值类型;数据类型
2、存储空间的大小
3、定长,变长
4、如何被索引及排序:binary 是区分大小写的
5、是否能够被索引
text(只能索引左侧固定长度的信息)
数据字典:系统编目(systm catalog),并不是目录
保存数据库服务器上的元数据
初始化数据表:mysql这个库
元数据:
关系的名字
每个关系的各字段的名字
各字段的数据类型和长度
约束
每个关系上的视图的名字及视图的定义
授权用户的名字
用户的授权和账号信息
统计类的数据:
每个关系字段的个数
每个关系中函数
每个关系的存储方法
保存元数据的数据库:
information_schema 元数据,统计类信息, 虚的,不存在,在内存中,类似于/dev/映射为的设备文件
performance_schema 性能信息
SQL语句:
数据类型:
字符型:
不区分大小写:
char
varchar
text:
区分大小写:
binary
varbinary
blob:二进制的大对象
数值型
精确数值型
整型
十进制数据:
近似数值型
单精度
双精度
日期型
时间型
日期型
日期时间型
时间戳
YEAR
布尔型:非真正的bool型
tinyint
内建型
ENUM, SET(枚举,集合)
数值型:
TINYINT:精确
SMALLINT
MEDIUMINT
INT
BIGINT
DECTML
FLOAT
DOUBAL
字符型:
CHAR
VARCHAR
TINYTEXT
MEDIUMTEXT
LONGTEXT
BINARY
VARINARY
BLOB
MEDIUMBOLB
变长 是需要结束符的
尽量不要使用text,索引空难,而且以对象索引,存在于数据库外的某个位置,数据库存指针
尽量别可变长度,影响索引
char --- 最多255个字符
varchar --- 最多65535个字符
tinytext --- 最多255个
CHAR , VARCHAR, TEXT字符型常用的属性修饰符:
NOT NULL:非空约束
NULL:运行为空
DEFAULT ‘string':不适用于text
CHARACTER SET ' 字符集':指定字符集 (从小到大范围继承)
查看字符集:
SHOW CHARACETER SET;
SHOW VARIABLES LIKE '%CHAR%'
支持的排序规则:
SHOW COLLATION;
BINARY,VARBINARY, BLOB:二进制存储,字节的大小排序
NOT NULL
NUL
DEFAULT : 不适用于BLOB
数值型:常用属性修饰符
TINYINT 0-255 1字节
SMALLINT 0-65535 2
MEDIUMINT 0-16777215 3
INT 0-4亿 4字节
AUTO_INCREMENT :自动增长
前提:非空,唯一,支持索引(用过之后,就不会再用,即便前面数删除了),非负值。
SELECT LAST_INSERT_ID():显示插入语句用了多少,但是准确,如果批量插入,只记录1次
使用 DROP FROM table;再插入数据,LAST_INSERT_ID() 从当前数据增长
最好使用 TRUNCATE table; 就1开始
UNSIGNED:无符号
NULL, NOT NULL , DEFAULT 不能加引号
浮点型:支持使用精度
NULL , NOT NULL , DEFAULT,UNSIGNED
日期:
DATE 3 字节
DATETIME 8字节
TIME 3字节
YEAR 1字节
NOT NULL
NULL
DEFAULT
ENUM:最大65535个字符,字符串,只能选一个
SET:单个字符, 或几个字符,用的时候,是挑几个的组合,而且使用的是索引
可以支持多个字节。
NOT NULL
NULL
DEFAULT ‘’
MySQL mysql_mode:sql 模型:
常用的模式:
TRADITIONAL:传统模式
STRICT_TRANS_TABLES:事务的表严格模式
STRICT_ALL_TABLES:所有的都 严格
SHOW GLOBAL VARIABLES LIKE '%mode%'
设定服务器变量的值:(仅用于支持动态的变量)
支持修改的服务器变量:
动态变量:mysql运行时修改
静态变量:于配置文件中修改,重启后才能生效
服务器变量从其生效范围:
全局变量:服务器级别的,修改之后,仅对新建立的会话有效
会话变量:仅对当前的会话有效
会话建立时 ,从全局继承各变量
查看服务器变量:
SHOW GLOBAL[SESSION] VARIABLES [LIKE ' '] :默认session
SELECT @@{GLOABL|SESSION}.sql_mode
或者在 information_schema 库中,表中查看
修改变量:
前提:默认只有root才有权限修改全局
SET global | session variable_name='';
例如: SET SESSION SQL_MODE=‘’
修改了去全局,对当前会话无效,对新建会话有效。
注:无论是全局还是会话级别的动态变量的修改,在重启mysql后,都会失效,想永久有效,一般放下配置文件的[mysqld]
mysql --help -v : 带-- 命令行参数, 不加的是配合文件参数,有重叠,但不一定相同
MySQL的大小写问题:
sql的关键字和函数名,是不区分大小写的。
数据库,表,视图的名字,取决于 文件系统,linux区分,windows不区分(移植库 可能会出现问题)
存储过程和存储函数,事件调度器不区分大小写
触发器区分大小写
表别名 区分大小写
主键,唯一键是否区分大小写:字段类型,binary区分大小写,char 不区分
SQL表,库管理语句:
数据库:
创建数据库:
CREATE DATABASE | SCHEMA [IF NOT EXISTS] [CHARACTER SET = ''] [COLLATE = ''] db_name;
默认字符集:等号可有可无
CHARACTER SET =
排序:等号可有可无
COLLATE =
默认值:
DEFAULT
删除库:
DROP DATABASE | SCHEMA [IF EXISTS] db_name
修改数据库: [CHARACTER SET = ''] [COLLATE = ''],也可以升级数据字典
ALTER DATABASE | SCHEMA db_name [CHARACTER SET = ''] [COLLATE = '']
表创建方式一:
数据表:键是索引,索引不一定是键,键有约束 HELP CREATE TABLES; -------
CREATE [TEMPORARY] TABLE [IN NOT EXISTS] tb_name
(create_definition ,...)
[table_options]
[partition_options]
(create_definition ,...):
字段定义:字段名,类型,类型修饰符
键,约束或索引:
PRIMARY KEY, UNIQUE KEY, FOREIGN KEY, CHECK
{INDEX | KEY}
create table t1 (Name varchar(30) not null , age tinyint unsigned not null,primary key(Name,age)); 多字段组成的主键
[table_options]:
ENGINE= engine_name;
AUTO_INCREMENT [=] value 从几开始
CHARACTER SET [=] characte—name
COLLATE [=] collation_name
COMMATION [=] 'STRING' 注释
DELAY_KEY_WRITE [=] {0|1}:索引降低写,提高查,每次修改都要重新构建,过一会再写入
ROW_FORMAT [=] {DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT} 表格式
TABLESPACE tablespace_name [STORAGE {DISK|MEMORY|DEFAULT}] 表空间
create table t1 (Name varchar(30) not null , age tinyint unsigned not null,primary key(Name,age)) engine='MyISAM'; 添加引擎
SHOW ENGINES; 存储引擎
SHOW TABLE STATUS LIKE 't1'G
mysql> SHOW TABLE STATUS LIKE 't1'G
*************************** 1. row ***************************
Name: t1
Engine: InnoDB
Version: 10
Row_format: Compact
Rows: 0
Avg_row_length: 0
Data_length: 16384
Max_data_length: 0
Index_length: 0
Data_free: 10485760
Auto_increment: NULL
Create_time: 2018-10-26 09:41:59
Update_time: NULL
Check_time: NULL
Collation: utf8_general_ci
Checksum: NULL
Create_options:
Comment:
MyISAM表每个表都有是哪个文件,都位于数据库目录中:
tb_name.frm: 表结构定义
tb_naem.MYD:数据文件
tb_name.MYI:索引文件
InnoDB 有两种存储方式:
1、默认:每个表有一个独立文件和一个多表共享的文件
tb_name.frm:表结构的定义,位于数据库目录(与数据库同名的目录)
ibdata#:共享的表空间文件(所有的表),默认位于数目录(datadir指向的目录)中
2、独立的表空间文件,每表有一个表结构文件一个独有的表空间文件,包括索引。
修改配置文件:[mysqld]
show global variables like '%innodb%';
| innodb_file_per_table | OFF |
tb_name.frm:每表一个表结构文件
tb_name.ibd:一个独有的表空间文件
表创建方式二:(复制表数据
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
[(create_definition,...)]
[table_options]
[partition_options]
select_statement
表创建方式三:基于某张表,创建空表(复制表结构)
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
{ LIKE old_tbl_name | (LIKE old_tbl_name) }
表删除:
DROP [IF EXISTS] tb_name [CASCADE -- 级联,关联的也会删除]
修改:
ALTER TABLE tb_name
修改字段定义:
插入新字段:
ALTER TABLE t1 ADD IID INT NOT NULL;
删除字段:
ALTER TABLE t1 DROP IID;
修改字段:
修改字段名称;
| CHANGE [COLUMN] old_col_name new_col_name column_definition [FIRST|AFTER col_name]
ALTER TABLE t1 CHANGE Name Sname char(10) NOT NULL;
修改字段类型及属性等:
| MODIFY [COLUMN] col_name column_definition [FIRST | AFTER col_name]
ALTER TABLE t1 MODIFY Name varchar(30) AFTER age;
添加索引:
ALTER TABLE t1 ADD INDEX (Sname);把某个字段作为索引
给某个字段添加索引:
CREATE INDEX idx_name ON tb_name(字段(指定长度)):指定长度:如果该字段的索引到了一定值后不会再改变,可以节省空间
查看索引:
show indexes from t1;
删除一个索引;
ALTER TABLE t1 DROP INDEX Sname;
DROP INDEX idx_name ON tb_name
SHOW INDEX_STAISTICS;查看索引利用情况
修改约束,键,索引
表改名:
RENAME [TO|AS] db_name
也可以直接使用:
mysql> RENAME TABLE old_name TO new_name;
不建议修改引擎:(它会新建一个表,把数据复制过去)
要是修改,直接指定
指定排序标准的字段:
ORDER BY col_name
转换字符集及排序规则:
CONVERT TO CHARACTER SET charset_name [COLATE collation_name]
SQL查询语句:
单表查询:简单查询
多表查询:连续查询
联合查询:
单表查询:简单查询
选择和投影:
选择:挑选要显示的行:
投影:挑选要显示的字段
投影:SELECT 字段1,字段2,... FROM 表名;
SELECT * FROM tb_name;
选择:SELECT 字段 FROM tb—name WHERE 子句;
布尔条件表达式
比较操作符:
=:等值比较
<=> : 跟NULL 比较不会出现错误的 等值比较
<> != :不等比较
<
>
<=
>=
IS NULL:不能用=
IS NOT NULL:
LIKE:模糊匹配 % _
RLIKE:支持使用正则表达式的
REGEXP:
IN:某一字段的值是否在指定的列表中
BETWEEN ,,, AND,,, : 在,,,之间 WHERE Age NETWEEN 10 AND 30;
CREATE TABLE students (SID INT UNSIGNED AUTO_INCREMENT NOT NULL unique key,Name CHAR(10) NOT NULL, AGE INT UNSIGNED NOT NULL ,Gender ENUM('M','F') NOT NULL, Tutor CHAR(20));
INSERT INTO students VALUES ( , , ,)
INSERT INTO tb_name (co1,co2) VALUES(VA1,VA2)
组合条件测试:
NOT !
AND &&
OR ||
XOR:异或
排序:
ORDER BY ' ' ASC 默认升序
ORDER BY ' ' DESC 降序
select * from students order by -classid desc;将NULL 放到最后
mysql内置的聚合函数:
SUM(), AVG(), MAX() , MIN(),COUNT()
SELECT SUM(Age) FROM students;
分组:以什么为条件,分组
GROUP BY
SELECT gender,sum(age) fromstudents GROUP BY gender;
对GROUP BY的结果做过滤,使用having,
注:where用在group by之前
SELECT gender,sum(age) fromstudents GROUP BY gender having gender='M'
返回有限 的行 limit
select* from, students limit 2
select* from, students limit 2,3 # 偏移两行,显示三行
SELECT语句的执行流程:
FROM --> WHERE --->GROUP BY ---> HAVING ---> ORDER BY --SELECT ---> LIMIT
SELECT语句后:
DISTINCT:重复的值 只显示一次
SQL_CACHE:缓存与查询缓存中,
SQL_NO_CACHE:不缓存
多表操作:
内连接:交集,缺点是,如果有的 NULL 不显示
老方法:where 判断
select * from students as s, teachers as t where s.teacherid=t.tid;
如果有相同的字段,可以加上表名.字段
select stuid,s.name,tid, s.name from students as s, teachers as t where s.teacherid=t.tid;
新方法:inner join ... on.....
select s.name, s.age,t.name from students s inner join teachers t on s.age=t.age;
左外连接:
左边表的全部内容,右边的处理交集,都为NULL, left outer join
select * from students s left outer join teachers t on s.teacherid=t.tid;
右外连接:right outer join ... on ...
注意表的先后顺序;
对结果再次过滤:
select * from students s left outer join teachers t on s.teacherid=t.tid where t.age>50;
左外连接去掉交集:
select * from students s left outer join teachers t on s.teacherid=t.tid where t.tid is null;
右外连接去掉交集:
完全外链接:并集
select* from students s full outer join teachers t on s.teacherid=t.tid -----mysql 不支持
左外连接+ 右外连接+ union
select * from students s left outer join teacher t on s.teacherid=t.tid
-> union
-> select * from stundents s right outer join teachers t on s.teacherid=t.tid
完全外连接去除交集:
上米昂的完全外链接,去掉公共部分
自连接:SELEsCT t.name,s.name FROM students s , students t where s.TID=t.tezcherID
+-------+---------------+-----+--------+---------+-----------+
| TID | Name | Age | Gender | ClassID | TeacherID |
+-------+---------------+-----+--------+---------+-----------+
| 1 | Shi Zhongyu | 22 | M | 2 | 3 |
| 2 | Shi Potian | 22 | M | 1 | 7 |
| 3 | Xie Yanke | 53 | M | 2 | 16 |
| 4 | Ding Dian | 32 | M | 4 | 4 |
| 5 | Yu Yutong | 26 | M | 3 | 1 |
子查询:
在查询中嵌套的查询
用于WHERE中的子查询:
1、用于比较表达式中的子查询
子查询的返回值只能有一个
2、用于EXISTS中的子查询
判断存在与否
3、用于IN 中的子查询
判断存在于指定的列表中
SELECT name,classid from students
用于From的子查询:
SELECT alias.co1,... FROM (select clause) as alias where condition
SELECT S.Name,s.Age, s.gender FROm (SELECT * FROM students WHERE gender='M') as s WHERE Age > 25
MySQL不擅长子查询,应该避免使用,尽量使用联合查询
MySQL的联合查询:
表结构的合并:
纵向合并:字段数一直,数据类型一致。
union:
select stuid,name,age,gender from students union select * from teachers;
有一模一样的数,是可以去重的。 但是谁union谁是有区别的,还有字段名字
select * from teachers union select stuid,name,age,gender from students ;
自己union 自己,就会去重,但是一般都是有主键的;
横向合并:
cross join:交叉乘积
select * from students cross join teachers;
+-------+---------------+-----+--------+---------+-----------+-----+---------------+-----+--------+
| StuID | Name | Age | Gender | ClassID | TeacherID | TID | Name | Age | Gender |
+-------+---------------+-----+--------+---------+-----------+-----+---------------+-----+--------+
| 1 | Shi Zhongyu | 22 | M | 2 | 3 | 1 | Song Jiang | 45 | M |
| 1 | Shi Zhongyu | 22 | M | 2 | 3 | 2 | Zhang Sanfeng | 94 | M |
| 1 | Shi Zhongyu | 22 | M | 2 | 3 | 3 | Miejue Shitai | 77 | F |
| 1 | Shi Zhongyu | 22 | M | 2 | 3 | 4 | Lin Chaoying | 93 | F |
| 1 | Shi Zhongyu | 22 | M | 2 | 3 | 5 | Yu Yutong | 26 | M |
EXPLAIN select 语句:
显示查询详细细节,可以看用到索引没 等信息
mysql> EXPLAIN select * from students s, teachers t where s.teacherid = t.tidG
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: s
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 25
Extra:
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: t
type: ALL
possible_keys: PRIMARY
key: NULL
key_len: NULL
ref: NULL
rows: 4
Extra: Using where; Using join buffer
视图:
虚表
存储下来的 select 语句:执行结果返回
create view stu AS SELECT Name,Age FROM students;
show tables;
show create view stu;查看创建过程
可以设置用户 访问view,就只能访问某些字段
插入数据:
可以插入数据,同时插入到原表中,但是如果视图设置了过滤条件,比如age>30 插入的20 ,是插不到视图,但是还是能插到原表中
删除:
DROP VIEW stu;
查看waring:只能在刚出现warings后查看,在期间执行其他语句后,就查不到了
show warings;
插入:INSERT
第一种:
INSERT INTO tb_name [(col1,col2...)]{VALUES|VALUE} (val11,val12...) (val21,val22...)
第二种:
INSERT INTO tb_nam SET col=val1 ,col2=val2
第三种:
INSERT INTO tb_name SELECT clause
RAPLACE:
如果定义了主键的,唯一键的,只能替换,重复的不能插入
使用方式同INSERT
更新:可以多表,一般少用
UPDATE
UPDATE [LOW_PRIORITY] [IGNORE] table_reference
SET col_name1=val1 [, col_name2=val2] ...
[WHERE where_condition]
[ORDER BY ...]
[LIMIT row_count]
UPDATE 通常必须使用WHERE 子句或者 LIMIT 限制要修改的行数
UPDATE student_count SET student_count=student_count+1;
--safe-update:避免因为没有where 全改了
DELETE:
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM tbl_name
[WHERE where_condition]
[ORDER BY ...]
[LIMIT row_count]
DELETE FROM students WHERE stuid = uid;
函数:不怎么使用
函数是有作用域的,某个库的,不能被其他库调用,(通过其他方式可以实现)
show function status; 查看所有的函数
存储于mysql库中的proc表中
DELIMITER ; 设置语句结束符
函数:系统函数和自定义函数
系统函数:https://dev.mysql.com/doc/refman/5.7/en/func-op-summary-
ref.html
自定义函数 (user-defined function UDF)
保存在mysql.proc表中
创建UDF
CREATE [AGGREGATE] FUNCTION function_name(parameter_nametype,[parameter_name type,...])RETURNS {STRING|INTEGER|REAL}
runtime_body
说明:
参数可以有多个,也可以没有参数
必须有且只有一个返回值
自定义函数
创建函数
示例:无参UDF
CREATE FUNCTION simpleFun() RETURNS VARCHAR(20) RETURN "Hello
World!”;
查看函数列表:
SHOW FUNCTION STATUS;
查看函数定义
SHOW CREATE FUNCTION function_name
删除UDF:
DROP FUNCTION function_name
调用自定义函数语法:
SELECT function_name(parameter_value,...)
示例:有参数UDF
DELIMITER //
CREATE FUNCTION deleteById(uid SMALLINT UNSIGNED) RETURNS
VARCHAR(20)
BEGIN
DELETE FROM students WHERE stuid = uid;
RETURN (SELECT COUNT(stuid) FROM students);
END//
DELIMITER ;
自定义函数中定义局部变量语法
DECLARE 变量1[,变量2,... ]变量类型 [DEFAULT 默认值]
说明:局部变量的作用范围是在BEGIN...END程序中,而且定义局部变量语句必须在
BEGIN...END的第一行定义
示例:
DELIMITER //
CREATE FUNCTION addTwoNumber(x SMALLINT UNSIGNED, Y SMALLINT
UNSIGNED)
RETURNS SMALLINT
BEGIN
DECLARE a, b SMALLINT UNSIGNED;
SET a = x, b = y;
RETURN a+b;
END//
DELIMITER ;
为变量赋值语法
SET parameter_name = value[,parameter_name = value...]
SELECT INTO parameter_name
示例:
...
DECLARE x int; ----只能在函数中调用
SELECT COUNT(id) FROM tdb_name INTO x;
RETURN x;
END//
MySQL管理:
第一层:面向连接,用户请求的连接,管理释放。
Mysql是明文的,支持文本和二进制两种格式的传输。
加密:基于SSL
第二层:MySQL核心服务层,BIF(内置函数),视图等。。。
分析器:语法分析,语句切片等完成优化(yacc,lex分析器,开源的)
优化器:语句重构,多表查询,调整顺序,选择开销最小的索引
EXPLAIN:
第三层:存储引擎,负责数据的存储和提取。
MySQL锁:
执行操作时,施加的锁模式:
读锁:共享锁,A读,不会影响B的读
写锁:独占锁,排他锁,不能查,写,
其他可能查到,因为缓存,要不这样,关闭query_cache_wlock....
锁粒度:
表锁:table lock
锁定了整张表
行锁:row lock
锁定了需要的行
粒度越小,开销越大,但并发性越好
锁的实现位置:
MySQL锁(第二层):显示锁,可以手动施加
存储引擎锁(第三层):隐式锁,自动的
显示锁:
LOCK TABLES;
UNLOCK TABLES;
LOCK TABLES tbl_name lock_type [, tbl_name lock_type] ...
UNLOCK TABLES;
施加读锁,不影响别人读,但是别人不能锁,只有释放,别人才能写,自己也不能写
施加写锁, 别人不能读,也不能写
InnoDB存储引擎 也支持另外一种显示锁(锁定挑选出的部分行,行级锁)
SELECT .... LOCK IN SHARE MODE;
SELECT .... FOR UPDATE;
先 show tables classes status; 查看引擎类型
注意:锁是在执行语句的过程中加入的,语句执行完,就失效了
SELECT * FROM classes WHERE ClassID <= 3 LOCK IN SHARE MODE;
SELECT * FROM classes WHERE ClassID <= 3 FOR UPDATE;
事务:Transaction
事务就是一组原子性的查询语句(查询—*****),也即将多个查询当作一个独立的工作单元。
ACID测试:能满足ACID 的测试,就表示能支持事务,兼容事务
A:atomictiy原子性,一个事务被视为一个不可分割的单元,要不执行,要不都不执行
C:Consistency ,一致性, A 转账B 总金额是不变的,从一个一致性状态,到另一个一致性状态
I:isolation,隔离性,事务所做的操作,在提交之前,别人是看不到的
A -300的过程,别人看不到A 减少了300 (在没提交之前)
D:durability,持久性,一旦事务提交了,其所作的修改就会永久有效
隔离级别:
READ - UNCOMMITED :读尚未提交,安全性差,并发好点(别人也能看到你没有提交的数据),会出现脏读,出现不可重复读(两次结果不一致,一个是未提交,一个是提交之后)
READ - COMMITTED (读提交,未提交的看不到,不可重读)
REPEATABLE READ(可重读,解决脏读),出现幻读 ---mysql,两个人同时是操作数据库,未提交,看到两种不同结果
A 删除了一条,也提交了
B 还是没有看到删除的,只有自己提交,在开启,才能看到删除的
便于数据备份,备份过程中数据不变
SERIALIZABLE 可串行化,隔离级别最高,但是性能太低(事务串行执行)
事务的未提交读 组织别人的写
A 为提交
B 阻塞
> start transaction
> commit
> rollback 全部回滚
> savepoint point_name
> rollabck to point_name
提交事务后,不能回滚的(显示开启,显示提交)
innodb支持自动提交事务(非显示开启),每一条语句都是一个事务,行级锁
SHOW GLOBAL VARIABLES LIKE '%commit%'
SET GLOBAL autocommit = 0(记得手动开启,手动提交)
查看隔离级别:
SHOW GLOBAL VARIABLES LIKE '%iso%'
或
SELECT @@global.tx_isolation
注意:服务器端修改 transaction-tx_isolation
建议:对事务要求不特别的严格,可以使用读题交
MySQL如何实现:
MVCC:多版本并发控制的内在机制实现的
每个事务启动时,InnoDB为每个启动的事务提供一个当下的快照,后续的操作,都在快照上操作
为了实现此功能,InnoDB 会为每个表提供两隐藏的字段:
一个用于保存行的创建时间,一个用于保存行的失效时间
里面存储的是系统版本号:
只在两个隔离级别下有效:读提交,可重读(默认)
MySQL存储引擎:
SHOW ENGINES;
SHOW TABLES STATUS [LIKE ''] [WHERE 语句]
SHOW TABLES STATUS IN hellodb;
SHOW TABLE STATUS IN hellodb WHERE name='classes'G :查看库中某个表的引擎
*************************** 1. row ***************************
Name: classes 表名
Engine: InnoDB 存储引擎
Version: 10 版本
Row_format: Compact 行格式(创建表的时候有)ROW_FORMAT [=] {DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT} 表格式
Rows: 9 表中的行数,innodb未必精确,mvcc机制导致可能存在镜像
Avg_row_length: 1820 行的平均长度(字节)
Data_length: 16384 表的数据总体大小
Max_data_length: 0 表的最大空间
Index_length: 0 索引的最大长度
Data_free: 9437184 可以用来存储的空间,但是未用的空间,也包括删除行释放的空间
Auto_increment: 10 自动增长(下一ge的值)
Create_time: 2018-10-26 11:52:27 表创建时间
Update_time: null 表数据的最近一次的修改时间
Check_time: NULL 使用CHECK TABLE 或myisamchk最近一次检测标的时间
Collation: utf8_general_ci 排序规则
Checksum: NULL 如果启用,则为表的checksum
Create_options: 创建表时指定的其他选项
Comment: 表的注释、如果是视图,显示VIEW,其他的为NILL
存储引擎也通常称为’表类型‘
MyISAM:
db_name.frm
db_name.MYD
db_name.MYI
InnoDB:
第一种格式:innodb_file_per_table=off 共享表空间
ibdata # 达到一定大小,启动新的(数据目录下)
tb_name.frm
第二种;innodb_file_per_table=on 独立表空间
每个表在数据库目录下存储两个文件
tb_name.frm
tb_name.idb
表空间:table space 由InnoDB管理的特有格式数据文件,Innodb使用聚簇索引
show engines;
SHOW VARIABLES LIKE '%ENGINE%';
default_storage_engine 服务变量实现
各存储引擎的特性:存储引擎比较:https://docs.oracle.com/cd/E17952_01/mysql-5.5-en/storage-engines.html
事务日志:随机IO 改为顺序IO(是一段连续的空间)
数据目录下 ib_logfile{1,0},一般是两个
InnoDB:
事务:事务日志
外键:
MVCC:
聚簇索引:
聚簇索引之外的索引,通常称为 辅助索引,不是指向数据,而是指向聚餐索引的
聚簇索引和数据是存放在一块的。一张表,聚簇索引只能有一个。否则就会乱套
辅助索引可以多个。
辅助索指针指向的是聚簇索引(InnoDB)
辅助索引 ---> 聚簇索引 ---> 数据本身
主键 作为聚簇索引。
辅助索引、聚簇索引 是基于位置的。
辅助索引、聚簇索引都是 B+tree 索引(也就是说内部结构)
行级锁:间隙锁
支持辅助索引
支持自适应的hash索引
支持热备份
MyISAM:
全文索引 (Mroonga引擎)
压缩(做数据仓库,节约空间,IO次数减少)
空间索引(通过空间函数)
表级锁
延迟更新索引
不支持事务
不支持外键
不支持MVCC
不支持行级锁
奔溃后,无法安全恢复
使用场景:只读数据(数据仓库),较小的表,能忍受数据丢失(崩溃后,数据恢复能力差,非事务)
ARCHIVE:
仅支持INSERT 和 SELECT 支持很好的压缩
适用于存储日志信息,或其他按时间序列实现的数据采集类的应用。
支持行级锁和专用缓存区
CSV:
CSV存储引擎使用逗号分隔值格式将数据存储在文本文件中。可以使用
CSV引擎以CSV格式导入和导出其他软件和应用程序之间的数据交换
不支持数据索引
仅适用于数据交换场景
BLACKHOLE :
黑洞存储引擎接受但不存储数据,检索总是返回一个空集。该功
能可用于分布式数据库设计,数据自动复制,但不是本地存储
没有存储机制,常用于多级复制架构中做中转服务区
MEMORY:
保存数据在内存中,内存表,实现临时表,保存中间数据,周期性的聚合数据等。
仅支持hash索引,适用表级锁,不支持BLOB 和text数据类型
MRG_MYISAM:
把两个MyISAM连到一起,能够将多个MyISAAM合并成一个虚表
NDB:
MySQL CLUSTER 中专用的存储引擎
第三方存储引擎:
OLTP:在线事务处理:
XtraDB:增强版的InnoDB, 由Percona提供
编译安装时,下载xtradb 的原码 替换mysql存储引擎中的InnoDB的原码
PBXT:MariaDB自带
支持引擎级别的复制操作
支持引擎级别的外加约束,
对SSD磁盘提供适当支持
支持MVCC
TokuDB:
使用Fractal Trees索引,没有锁片问题,适合在大数据领域,有和好的压缩比
被引入 MariaDB
列式存储引擎:
Infobright:目前较有名的劣势引擎,适用于海量数据存储场景,PB级别的,专为数据分析和数据仓库设计
InfiniDB
MonetDB
LucidDB
开源社区存储引擎:
Aria:前身Maria, 可理解为增强版的MyIS AM ,支持奔溃后恢复,支持数据缓存
Groona:全文索引引擎,用在搜索引擎上。Mroonga是改进版
QQGraph:Open Query开发,支持图结的存储引擎
SphinxSE:整合到MariaDB 中,全文搜索服务器提供了sql接口
Spider:将数据切片,能将数据分成不同的切片,比较透明的实现了分片,并支持在分片上支持并行查询
如何选择:
是否需要事务
是否需要备份,以及备份类型
崩溃后的恢复 ;
特有的特性(如,利用特有特性)
如果多个要求一致,做性能测试,再做出选择
索引类型:
聚簇索引
辅助索引
B树索引
R树索引
hash索引
全文索引
Mysql用户管理:
用户账号: username@hostname, password
用户账号管理:
CREATE USER
DROP USER
RENAME USER
SET PASSWORD
权限管理:
GRANT:同时还可以创建用户
REVOKE:
CREATE TEMPORARY TABLES:创建临时表,内存中
SHOW PROCESSLIST:显示当前运行的所有线程(跟用户相关的)mysqladmin那块有提到
MySQL权限级别:
库级别:
表级别:
字段级别:
管理类:
CREATE USER
CREATE USER username@hostname
[
IDENTIFIED BY [PASSWORD] 'password'
]
CREATE USER test@'192.168.%.%' IDENTIFIED BY '123456'
主机可以使用通配符:
testuser@'192.168.100.1__' ----> 100-199
查看用户能都使用的权限: SHOW GRANTS FOR 'test'@192.168.%.%';
RENAME USER .... TO ...:
RENAME USER 'test1'@'192.168.%.%' TO 'jack'@'192.168.%.%'
SET:
SET PASSWORD [FOR user] =
{
PASSWORD('cleartext password')
| OLD_PASSWORD('cleartext password')
| 'encrypted password'
}
SET PASSWORD FOR 'bob'@'%.example.org' = PASSWORD('cleartext password');
GRANT:
管理类权限:
CREATE TEMPORARY TABLES
CREATE USER
FILE
SHOW DATABASES
SHUTDOWN
SUPER
REPLICATION SLAVE 复制
REPLICATION CLIENT
LOCK TABLES
PROCESS
数据库级别,表级别 的权限:
ALTER:修改表
ALTER ROUTINE:修改存储函数,存储过程
CREATE :创建表,库
CREATE ROUTEINE
CREATE VIEW 视图
DROP:删除表,库
EXECUTE:执行函数或存储过程
GRANT OPTION:转增权限
INDEX:
SHOW VIEW:是否有权限查看view
数据操作(表级别:
SELECT
INSERT
UPDATE
DELETE
字段相关的:
SELECT (col,...)
UPDATE(COl ,....)
INSERT(col, ....)
命令:
GRANT
priv_type [(column_list)]
[, priv_type [(column_list)]] ...
ON [object_type] priv_level
TO user_specification [, user_specification] ...
[REQUIRE {NONE | ssl_option [[AND] ssl_option] ...}]
[WITH with_option ...]
GRANT PROXY ON user_specification
TO user_specification [, user_specification] ...
[WITH GRANT OPTION]
object_type:
TABLE
| FUNCTION
| PROCEDURE
priv_level:
*
| *.*
| db_name.*
| db_name.tbl_name
| tbl_name
| db_name.routine_name
user_specification:
user
[
IDENTIFIED BY [PASSWORD] 'password'
| IDENTIFIED WITH auth_plugin [AS 'auth_string']
]
ssl_option:
SSL
with_option:
GRANT OPTION
| MAX_QUERIES_PER_HOUR count 多少次查询
| MAX_UPDATES_PER_HOUR count 更新次数
| MAX_CONNECTIONS_PER_HOUR count 最大建立个数
| MAX_USER_CONNECTIONS count 使用同一个账户,同时连接几次
GRANT CREATEE ON hellodb.* TO 'test'@'%' IDENTIFIED BY '123456'
获得创建库的权限,必须对库的所有表有权限,才能创建库
REVOKE:收回授权:
REVOKE
priv_type [(column_list)]
[, priv_type [(column_list)]] ...
ON [object_type] priv_level
FROM user [, user] ...
REVOKE ALL PRIVILEGES, GRANT OPTION
FROM user [, user] ...
REVOKE CREATE ON test.t FROM test@'%'
授权信息表:
mysql库下的
db:库级别的权限
host:主机级别,废弃
tables_priv:表级别
colomns_priv:列级别的
procs_priv:存储过程和存储函数相关的授权
proxies_priv:代理用户的权限
FLUSH!!!!!!!!!!!!!
如果连接多次被拒绝了,需要清理一下host文件
如果root用户密码忘了?
配置mysqld中添加:skip-grant-tables
如何从mysql 升级到 mariadb
MySQL查询缓存:
用于保存Mysql 查询语句返回的完整结果,被命中时,Msyql 会立即返回,省去解析,优化,执行等过程。
如何检查缓存:
Mysql保存数据于缓存中:
把select语句本身做hash计算,计算的结果作为key,查询的结果作为value
次数命中率,字节命中率
什么样的语句不能被缓存:
查询语句中有一些不确定数据,用户自定义函数,存储函数,用户定义变量,临时表,系统表,或权限表
缓存带来的额外开销:
1、每个查询都得先查询是否命中
2、查询结果先缓存
3、内存有限,而且还要分配内存大小,lru删除,还可能产生内存碎片等等
mysql> show global variables like 'query_cache%';
+------------------------------+----------+
| Variable_name | Value |
+------------------------------+----------+
| query_cache_limit | 1048576 |
| query_cache_min_res_unit | 4096 |
| query_cache_size | 16777216 |
| query_cache_type | ON |
| query_cache_wlock_invalidate | OFF |
+------------------------------+----------+
query_cache_type:查询缓存类型,是否开启缓存功能,开启方式有三种,ON, OFF ,EDMAND
DEMAND
SELECT SQL_CACHE .... select语句只有加SQL_CACHE这句,才缓存
query_cache_size:缓存使用的总空间,单位字节,大小是1024的整数倍
mysql启动时,一次性分配,并立即初始化这里的指定大小空间
如果修改此大小,会清空全部缓存,并重新初始化
query_cache_min_res_unit:存储缓存的最小内存块
(query_cache_size - Qcache_free_memory)/Qcache_queries_in_cache 获取一个理想值
query_cache_limit:一个查询语句缓存的最大值(先缓存,如果超过了,再删除 ,又降低性能)
手动使用SQL_NO_CACHE 可以人为的避免尝试缓存返回结果超出此参数限定值的语句
query_cache_wlock_invalidate:
如果某个表被其他的用户锁住,是否从缓存中返回结果,OFF 表示返回。
如何判断命中率:
次数命中率:
状态变量是统计值,服务器变量是设定值********
SHOW GLOBAL STATUS LIKE 'Qcache%'
mysql> SHOW GLOBAL STATUS LIKE 'Qcache%';
+-------------------------+----------+
| Variable_name | Value |
+-------------------------+----------+
| Qcache_free_blocks | 1 |
| Qcache_free_memory | 16759696 |
| Qcache_hits | 0 |
| Qcache_inserts | 0 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 3 |
| Qcache_queries_in_cache | 0 |
| Qcache_total_blocks | 1 |
+-------------------------+----------+
Qcache_hits:命中次数
Qcache_free_memory:尚且空闲的空间,尚未分配
事先申请好的内存空间:
Qcache_free_blocks:空闲块数
Qcache_total_blocks:总块数
Qcache_queries_in_cache:缓存中缓存的查询个数
Qcache_inserts :缓存插入次数
Qcache_not_cached :没有缓存的
Qcache_lowmem_prunes:内存太少,修剪(腾出)内存的次数
碎片整理:
FLUSH QUERY_CACHE: 把小的集合起来
清空缓存:
RESET:
命中率的估算方式:
mysql> SHOW GLOBAL STATUS WHERE variable_name='Qcache_hits' OR variable_name='com_select';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Com_select | 3 |
| Qcache_hits | 0 |
+---------------+-------+
缓冲命中,Com_select是不会增加
所以命中率 Qcache_hits / (Qcache_hits + Com_select)
也参考另外一个指标:命中和写入的比率
Qcache_hits / Qcache)inserts 的值,大于3 表示缓存是有效的。
缓存优化使用的思路:
1、批量写入,而非多次单个写入
2、缓存空间不宜过大,因为大量缓存失效,会导致服务器假死
3、必要时,使用SQL_CACHE 和SQL_NO_CACHE 手动控制缓存
4、对写密集型的应用场景来说,警用缓存反而能提高性能
M有SQL日志:
查询日志:查询相关的信息
慢查询日志:查询执行时长超过指定时长的查询,未必是语句查询慢,可能被其他线程阻塞
错误日志:启动,关闭,复制线程(从服务器)
二进制日志:mysql中引起数据变化,mysql服务器改变的信息(修改的信息)MySQL复制的基本凭据
中继日志:保存在从服务器上的日志,跟主服务器上的二进制日志相同,用完可以删除。
事务日志:已提交数据,保存,未提交数据,回滚。
随机IO 转换为 顺序IO
日志文件组:至少有两个日志文件
注意:尽可能使用小事务
因为,如果事务大,事务日志中放不下,就会存到磁盘中,但是如果回滚,磁盘中的也得删除,这样,开销就会增大
ib_logfile{1|0} 两个
InnoDB_buffer支持read操作
如何尽量保证事务日志和数据的安全:
1、磁盘,事务日志,分别放在raid上(raid 10, 或raid 1)
2、做镜像
mysql> show global variables like 'innodb%';
+---------------------------------+------------------------+
| Variable_name | Value |
+---------------------------------+------------------------+
| innodb_log_buffer_size | 8388608 |
| innodb_log_file_size | 5242880 |
| innodb_log_files_in_group | 2 |
| innodb_log_group_home_dir | ./ |
| innodb_max_dirty_pages_pct | 75 |
| innodb_max_purge_lag | 0 |
| innodb_mirrored_log_groups | 1 |
| innodb_old_blocks_pct | 37 |
| innodb_old_blocks_time | 0 |
查询日志;默认关闭 ---- 一般不要开启
(动态变量)
log = ON|OFF 是否记录所有的语句的日志信息与一般产需日志文件(general_log)
log_output = TABLE| FILE | NONE :TABLE 和FILE 可以同时出现,用逗号分隔
general_log:是否启用查询日志
general_log_file:定义了一般查询日志保存文件 ---一般是 主机名。log
此选项 ,取决 log_output 是什么类型,只有FILE 的时候,次选项才能生效
开启:(两个都得打开)
SET GLOBAL log='ON'
SET GLOBAL general_log='ON'
记录到数据库:
SET GLOBAL log_output=’table';
mysql.general_log 表中
慢查询日志:
mysql> show global variables like 'long%'; 指定时间,多长时间才算慢
+-----------------+-----------+
| Variable_name | Value |
+-----------------+-----------+
| long_query_time | 10.000000 |
+-----------------+-----------+
slow_query_log OFF|ON 是启用慢查询 ,输出位置取决于log_ouput=FILE| TABLE| NONE
log_slow_queries ON|OFF
slow_query_log_file /mydata/data/node1-slow.log
如果log_ouput = FILE保存位置
记录到:
mysql.low_log查看
错误日志:
服务器启动和关闭信息:
服务器运行中的错误信息
事件调度器运行一个事件产生的信息;
在复制架构中从服务器上启动从服务器线程时产生的信息;
log_error /mydata/data/node1.err
log_warnings 1 :是否记录警告信息
二进制日志:记录的是,可能修改数据,或修改数据的信息
一般在数据目录下
使用 mysqlbinlog 查看
position:位置
time:时间
滚动:每一个日志文件不能过大
1、按照大小
2、按照时间
3、按照服务器启动
SHOW BINARY LOGS; 从开始到当前mysql服务器使用了的二进制文件
记录在 x.index文件中
功能:
时间点恢复:
复制:
PURGE:删除日志
PURGE { BINARY | MASTER } LOGS
{ TO 'log_name' | BEFORE datetime_expr }
示例:
PURGE BINARY LOGS TO ‘mariadb-bin.000003’;删除3之前的日志
PURGE BINARY LOGS BEFORE '2017-01-23';
PURGE BINARY LOGS BEFORE '2017-03-22 09:25:30';
删除所有二进制日志,index文件重新记数 RESET MASTER [TO #]; 删除所有二进制日志文件,并重新生成日志文
件,文件名从#开始记数,默认从1开始,一般是master主机第一次启动时执行,MariaDB10.1.6开始支持TO #
SHOW MASTER STATUS;查看日志信息
FLUSH LOGS;重启一个新的日志文件,滚动日志
SHOW BINARY LOGS;
mysql> SHOW BINARY LOGS;
+---------------+-----------+
| Log_name | File_size |
+---------------+-----------+
| binlog.000015 | 724935 |
| binlog.000016 | 733481 |
+---------------+-----------+
SHOW BINLOG EVENTS 查看二进制文件
SHOW BINLOG EVENTS
[IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count]
eg: SHOW BINLOG EVENTS IN 'aria_log.00000001'
SHOW BINLOG EVENTS IN 'aria_log.00000001' FROM 66761:
从指定的位置查看
mysqlbinlog:
--start-time
--stop-time
--start-poditon
--stop-positon
mysqlbinlog --start-positon= mysql-bin.log000001 > /a.sql
server-id: 服务器身份标识
Mysql记录二进制日志格式有两种:
1、基于语句:statment,
2、基于行:row:更精确
CURRENT_DATE():这种,只能基于行,基于语句,时间就不对了
3、混合模式:mixed
二进制日志文件的内容格式:
时间发生的时间和日期
服务器的ID
事件的结束位置
事件的类型
原服务器生成此事件的线程ID
语句的时间戳和写入二进制日志文件的时间差
错误代码
事件内容
事件位置,也就是下一个事件的开始位置
服务器参数:
log-bin
log-bin-trust-function-creators
sql_log_bin
sync_binlog:记录缓冲的 多久同步到磁盘中,0 不同步
log-bin = {ON|OFF|path} 文件路径,哪个路径下的文件中
ON 默认 mysql...00001
sql_log_bin = {ON|off} 会话级别参数,是否记录到二进制文件中,只有SUPER权限才可以修改
binlog_format = {statement | row|mixed}
max_binlog_cache_size =
二进制日志缓冲空间大小,仅用于缓冲实物类的语句
max_binlog_stmt_cache_size =
非事务类和事务类 共用的空间大小
max_binlog_size
二进制日志文件的大小
建议:二进制日志 与 数据文件 不要放在同一设备上
中继日志:
relay-log
| relay_log
| relay_log_index
| relay_log_info_file relay-log.info
| relay_log_purge ON 是否清理不用的中继日志
| relay_log_recovery OFF
| relay_log_space_limit 0 空间大小是否有限定
备份 和 恢复:
1、灾难恢复
2、审计 (某一数据在某一时刻是什么样的)
3、测试
备份:目的用于恢复,对备份数据做定期的恢复测试
备份类型:
根据备份时,服务器是否在线:
冷备:离线状态
热备:基于事务的
温备:全局施加共享锁,阻止写
根据备份的数据集:
完全备份:
部分备份:
根据备份时的接口(直接备份数据文件还是通过mysql服务器导出数据)
物理备份:直接复制数据文件的备份方式,存储引擎必须一致
逻辑备份:把数据从库中提取出来保存为文本文件,可以基于网络恢复,与存储引擎无关,避免数据恢复
缺点:速度慢,占据空间大。无法保证浮点数的精度,还原回来的数据需要 重建索引。(不适合数据量大的,慢)
工具:mysqldump
根据备份时是备份变化数据,还是整个数据:
完全备份;
增量备份:
|
|_________1________2________3
|--------->
------->
-------->
完全备份 + 增量备份 + 二进制即使点恢复 + 回滚
差异备份:(容易备份)
|
|_________1________2________3
|--------->
|------------------>
|---------------------------->
备份策略:
选择备份时间,备份方式,备份成本(锁时间,备份时长,备份负载),恢复成本
备份对象:
数据;
配置文件
代码:存储过程,存储函数,触发器
OS相关的配置文件:crontabl配置计划及相关脚本
跟复制先关的配置信息
二进制日志文件。
常用的工具:
mysqldump:逻辑备份工具
InnoDB 热备,MyISAM温备,Aria温备
备份和恢复时间较慢
mysqldumper:多线程MySQLdump
很难实现差异或增量备份;
lvm-snapshot:
接近于热备的工具:因为要先请求全局所,而后创建快照,并在创建快照完成后释放全局锁
cp,tar等工具物理备份,
备份和恢复速度快
无法做增量备份,请求全局锁需要等待一段时间
SELECT:部分备份工具:
SELECT 语句 INTO OUTEFILE '/path/to/somefile'
恢复:LOAD DATA INFILE '/path/to/somefile'
仅备份数据,不会备份关系
Innobase:商业备份,innobackup
Xtrabackup:由percona提供的开源备份工具。
InnoDB热备,增量备份
MyISAM温备,完全备份,不支持增量
物理备份,速度快
mysqlhotcopy:几乎冷备
具体使用
mysqldump:逻辑备份时文本信息,可以二次编辑
还原的时候如果库不在,需要手动闯将
步骤:备份单个库(备份的文件里没有创建库的语句,所以建议使用--databases
1、mydqldump -uroot -hlocalhost -p hellodb > /tmp/bdb.sql
/tmp/bdb.sql 是可以vim打开,二次编辑
2、恢复的时候,先创建库, CREATE DATABSE hellodb
3、导入:mysql-uroot -hlocalhost -p hellodb < /tmp/bdb.sql
步骤:备份所有库
msyqldump --all-databases > /tmp/all.sql
步骤:部分指定的多个库,不需要手动创建库
mysqldump --databases db1 db2 > /tmp/m.sql
注意:备份前要加锁
--lock-all-tabes:请求锁定所有表之后备份(读锁),对MyISAM,InnoDB,Aria 做温备
--single-transaction:能够对InnoDB引擎 实现热备(就不用--lock-all-tabes)
备份代码:
--events:备份事件调度器代码
--routines:备份存储过程和存储函数
--triggers:备份触发器
备份时 滚动日志:
--flush-logs:备份前,请求到锁之后滚动日志
复制时的同步标记:
--master-data = 0,1,2
0:不记录
1:记录为CHANGE MASTER 语句
2:记录为是注释的CHANGE MASTER 的语句
使用mysqldump备份:
请求锁:--lock-all-tables或--singe-transaction 进行INNODB热备
滚动日志: --flush-logs
选定要被扥的库: --databases
指定二进制日志文件及位置 --master-data
实例:
手动施加全局锁:
1、FLUSH TABLES WITH READ LOCK:缓存中的同步到磁盘,同时施加全局读锁
2、FLUSH LOGS
3、SHOW MASTER STATUS
4、mysqldump --databases hdb > /tmp/hdb.sql
5、UNLOCK TABLES;
mysqldump --databases hdb --lock-all-tables --flush-logs > /tmp/hdb2.sql (温备)
热备:(全是innodb引擎)
mysqldump --databases hdb --single-transaction --flush-logs > /tmp/hdb2.sql
恢复:
即使点恢复
一次完成过程:
备份:
1、先查看 存储引擎:
2、 mysqldump --databases hdb --lock-all-tables --flush-logs --master-data=2 > /tmp/hdb2.sql (温备)
查看hdb2.sql 有一句:注释掉的语句:
-- CHANGE MASTER TO MASTER_LOG_FILE='master-bin.00005',MASTER_LOG_POS=367
也就是说,下次即使点恢复,从此二进制文件的367位置开始往后
3、备份之后,又在表中插入数据等操作,而后,不小心把表删了
4、恢复到表删除之前:
4.1、先找到二进制文件,并备份保存
4.2、mysqlbinlog --start-positions=367 master-bin.00005 在里边找,不小心删除的语句之前的一个位置
4.3、保存二进制文件
mysqlbinlog --start-positions=367 --stop-positons=669 master-bin.00005 > /tmp/hdb2.inc.sql
4.4、因为不需要恢复的日志,不需要记录,所以先关掉,
SET SESSION sql_log_bin=0
5、导入完全备份:
SHOW MASTERS STATUS;查看位置对不
mysql> source /tmp/hdb2.sql
6、增量 恢复:
mysql> source /tmp/hdb2.inc.sql
7、SET SESSION sql_log_bin=1
注:恢复,关闭二进制文件,关闭其他用户连接(关闭全局二进制日志)
备份策略:基于mysqldump
备份:mysqdump +二进制日志文件
周日做一次完全备份:备份的同时滚动日志(下次二进制就从新的文件开始)
周一-周六:备份二进制日志
恢复:
完全备份 +各二进制文件至此刻事件
lvm-snapshot:
快照卷,获得文件的一致性通路
作为原卷的访问路径,
刚创建是没有内容,指向原卷,
修改的数据,文件先复制到快照卷,未修改的来自原卷,修改的来自快照卷
1、事务日志 跟 数据文件 必须在同一个卷上,两个卷不能保证时间一致
2、创建快照卷之前,要请求全局锁; 快照创建完之后,释放锁
3、请求全局锁完成之后,做一次日志滚动。做二进制日志文件及位置标记
实例:/mydata/data
1、lvs 看下逻辑卷
LV VG
mydata myvg
2、FLUSH LOGS WITH LOCK READ; 刷新日志,并施加锁
3、mysql -e 'show master status' > /binlog.pos 记录位置
4、lvcreat -L 100M -s -n mydata-snap -p -r /dev/myvg/mydata
lvs :查看
5、unlock tables;
6、挂载 快照卷
mount /dev/myvg/mydata /mnt -o ro
7、之后又进行了操作,如插图数据
8、开始备份
cd /mnt/data/
cp data/ /backup/data-2018-10-25 -a (归档模式,保证原权限)
9、卸载快照卷
10、一不小心删了/mydata/data/
11、二进制文件在 /mydata/binlog/
12、到新电脑上,安装mysql
13、cp /backup/data-2018-10-25/* /mydata/data/ 确保权限mysql.mysql
14、启动mysqld
15、基于二进制还原 原电脑上
根据刚才记住的位置,和文件
导出二进制文件内容
mysqlbinlog --start-positions=367 /mydata/binlog/master-bin.000009 | mysql
Xtrabackup(percona):实现增量备份
innobackupex:需要服务器处于运行状态
注意:
1、要将数据和备份放在不同的磁盘设备上,异机 或异地设备存储最为理想
2、备份的数据,应该周期性的进行还原测试
3、每一次灾难恢复后,都应该做一次完全备份
4、针对不同规模或级别的数量,要定制好备份策略
5、做好二进制日志备份,并跟数据 放在不同磁盘上,
从备份中恢复应该遵循步骤:
1、停止MySQL服务器(mysqldump不能)
2、记录服务器的配置和文件权限
3、将数据从备份移到MySQL数据目录中,执行方式,依赖于工具
4、改变配置和文件权限
5、以限制访问模块重启服务器,mysql的--skip-networking选项跳过网络功能
方法:编辑my.cnf
skip-networking
soket=/tmp/mysql-recorvery.socket
6、载入逻辑备份(如果有) ,而后检查和重放二进制日志
7、检查已经还原的数据
8、重新以完全访问模式重启服务器。
注释前面在my.cnf中添加的选项,并重启
SELECT .... INTO OUTEFILE '/tmp/stu.sql.txt'
这种方式需要手动创建表格式 testtb
LOAD DATA INFILE '...' INTO TABLE testtb