linux之mysql基础

一,数据库基础

安装部署
备份恢复

主备复制

读写分离

HA架构

分布式数据库
压力测试
性能优化
自动化运维

==数据的存储方式
1. 人工管理阶段
2. 文件系统阶段

3. 数据库系统管理阶段

4. 大数据 BIGDATA
==数据库技术构成
1. 数据库系统 DBS
A.数据库管理系统(DataBase Management System, DBMS):
SQL(RDS): ORACLE、Oracle MySQL、MariaDB、Percona server、DB2
NoSQL: Redis、MongoDB、Memcache
B. DBA

2. SQL语言(结构化查询语言)
A. DDL语句 数据库定义语言: 数据库、表、视图、索引、存储过程、函数, CREATE DROP ALTER //开发人员
B. DML语句 数据库操纵语言: 插入数据 INSERT、删除数据DELETE、更新数据UPDATE //开发人员
C. DQL语句 数据库查询语言: 查询数据 SELECT
D. DCL语句 数据库控制语言: 例如控制用户的访问权限GRANT、REVOKE

3. 数据访问技术
A. ODBC PHP <.php>
B. JDBC JAVA <.jsp>

二,mysql(5.1/5.5)安装

rpm安装方式

方式
清理环境:等同于源码安装的清理环境步骤

下载yum源安装包:
http://dev.mysql.com/doc/refman/5.7/en/linux-installation-yum-repo.html
# md5sum mysql57-community-release-el7-9.noarch.rpm

安装yum源安装包:
# yum -y install mysql57-community-release-el7-9.noarch.rpm
linux之mysql基础_第1张图片
linux之mysql基础_第2张图片
linux之mysql基础_第3张图片

# yum repolist enabled | grep mysql
# yum -y install mysql-community-server
# systemctl start mysqld //第一次启动先初始数据库
# systemctl enable mysqld
#grep password /var/log/mysqld.log
#mysql -uroot -p'uopCBgXBu8,k'

修改密码:密码太简单不行
两种方式:
第一种:
mysql> alter user 'root'@'localhost' identified by '123';
第二种:
# mysqladmin -u root -p'uopCBgXBu8,k' password 'Qianfeng123!@'

源码编译安装

linux之mysql基础_第4张图片

1. 编译安装

准备系统:centos7u4 硬盘剩余空间至少8G,内存剩余至少2G
准备安装环境:依赖包
# yum -y install ncurses ncurses-devel openssl-devel bison gcc gcc-c++ make

cmake:
# yum -y install cmake

boost:
# wget http://sourceforge.net/projects/boost/files/boost/1.59.0/boost_1_59_0.tar.gz

mysql:
# groupadd mysql
# useradd -r -g mysql -s /bin/false mysql -r//创建一个系统用户 -s//指定登陆的shell
# tar xvf mysql-5.7.19.tar.gz
# cd mysql-5.7.19
[root@mysql3 mysql-5.7.19]# pwd
/root/mysql-5.7.19
[root@mysql3 mysql-5.7.19]# tar xf /root/boost_1_59_0.tar.gz -C /root/mysql-5.7.19
[root@mysql3 mysql-5.7.19]# cmake . \
-DWITH_BOOST=boost_1_59_0/ \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \ //安装的目录
-DSYSCONFDIR=/etc \
-DMYSQL_DATADIR=/usr/local/mysql/data \ //数据库存放的位置
-DINSTALL_MANDIR=/usr/share/man \
-DMYSQL_TCP_PORT=3306 \ //Mysql的端口号
-DMYSQL_UNIX_ADDR=/tmp/mysql.sock \ //sock 进程间的通信方式
-DDEFAULT_CHARSET=utf8 \
-DEXTRA_CHARSETS=all \
-DDEFAULT_COLLATION=utf8_general_ci \
-DWITH_READLINE=1 \
-DWITH_SSL=system \
-DWITH_EMBEDDED_SERVER=1 \
-DENABLED_LOCAL_INFILE=1 \
-DWITH_INNOBASE_STORAGE_ENGINE=1

提示:boost也可以使用如下指令自动下载,把下面参数添加到上面的命令里面
-DDOWNLOAD_BOOST=1

注:
-DWITH_EMBEDDED_SERVER=1 #支持嵌入式mysql服务器
-DWITH_SSL=system #使mysql支持证书登陆

# make
# make install

2. 初始化

[root@mysql1 local]# cd mysql
[root@mysql1 mysql]# mkdir mysql-files
[root@mysql1 mysql]# chown -R mysql.mysql .
[root@mysql1 mysql]# bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
[root@mysql1 mysql]# bin/mysql_ssl_rsa_setup --datadir=/usr/local/mysql/data

建立MySQL配置文件my.cnf
[root@mysql1 mysql]# vim /etc/my.cnf
[mysqld]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data

启动MySQL
方法一:使用mysqld_safe
[root@mysql1 mysql]# bin/mysqld_safe --user=mysql &

方法二:使用centos6 mysql.server脚本(system V)
[root@mysql1 mysql]# cp support-files/mysql.server /etc/init.d/mysqld
[root@mysql1 mysql]# chkconfig --add mysqld
[root@mysql1 mysql]# chkconfig mysqld on
[root@mysql1 mysql]# service mysqld start

[root@mysql2 mysql]# service mysqld start
Starting MySQL.Logging to '/usr/local/mysql/data/mysql2.err'.
SUCCESS!
[root@mysql2 mysql]# ps aux |grep mysqld
mysql 76 pts/0 Sl 14:38 0:00 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=mysql2.err --pid-file=/usr/local/mysql/data/mysql2.pid

PATH[可选]
[root@mysql2 mysql]# mysql
-bash: mysql: command not found
[root@mysql2 mysql]# /usr/local/mysql/bin/mysql
[root@mysql1 mysql]# echo "export PATH=$PATH:/usr/local/mysql/bin" >> /etc/profile
[root@mysql1 mysql]# source /etc/profile
[root@mysql1 mysql]# mysqladmin -uroot -p'>>e4KKcol6i1' password '(TianYunYang123)'

如果需要重新初始化...
# killall mysqld
# rm -rf /usr/local/mysql/data
[root@mysql1 mysql]# bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
[root@mysql1 mysql]# bin/mysql_ssl_rsa_setup --datadir=/usr/local/mysql/data


RPM or Yum:
datadir: /var/lib/mysql

源码包 和 预编译:
basedir: datadir:
/usr/local/mysql /usr/local/mysql/data

忘记MySQL密码

MySQL 5.7.5 and earlier:
# vim /etc/my.cnf
[mysqld]
skip-grant-tables

# service mysqld restart
# mysql
mysql> update mysql.user set password=password("456") where user="root" and host="localhost";
mysql> flush privileges;
mysql> \q

# vim /etc/my.cnf
[mysqld]
#skip-grant-table                                //把这一行删除就行
# service mysqld restart

MySQL 5.7.6 and later:
[root@slave1 ~]# vim /etc/my.cnf
[mysqld]
skip-grant-tables

[root@slave1 ~]# systemctl restart mysqld

linux之mysql基础_第5张图片

[root@slave1 ~]# vim /etc/my.cnf

[root@slave1 ~]# systemctl restart mysqld

二进制安装方式

二进制 预编译 mysql-5.7.19-linux-glibc2.12-x86_64.tar.gz
http://dev.mysql.com/doc/refman/5.7/en/binary-installation.htmllinux之mysql基础_第6张图片

# groupadd mysql
# useradd -r -g mysql -s /bin/false mysql
# cd /usr/local
[root@mysql1 local]# tar xf /root/mysql-5.7.16-linux-glibc2.5-x86_64.tar.gz
[root@mysql1 local]# ln -s mysql-5.7.19-linux-glibc2.12-x86_64 mysql

mysql 初始化
没有编译安装的过程
[root@mysql1 local]# cd mysql
[root@mysql1 mysql]# mkdir mysql-files
[root@mysql1 mysql]# chmod 750 mysql-files
[root@mysql1 mysql]# chown -R mysql .
[root@mysql1 mysql]# chgrp -R mysql .
[root@mysql1 mysql]# bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
[root@mysql1 mysql]# bin/mysql_ssl_rsa_setup --datadir=/usr/local/mysql/data
[root@mysql1 mysql]# chown -R root .
[root@mysql1 mysql]# chown -R mysql data mysql-files


建立MySQL配置文件my.cnf
[root@mysql1 mysql]# vim /etc/my.cnf
[mysqld]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data

启动MySQL
方法一:使用mysqld_safe
[root@mysql1 mysql]# bin/mysqld_safe --user=mysql &

方法二:使用centos6 mysql.server脚本(system V)
[root@mysql1 mysql]# cp support-files/mysql.server /etc/init.d/mysqld
[root@mysql1 mysql]# chkconfig --add mysqld
[root@mysql1 mysql]# chkconfig mysqld on
[root@mysql1 mysql]# service mysqld start

[root@mysql2 mysql]# service mysqld start
Starting MySQL.Logging to '/usr/local/mysql/data/mysql2.err'.
SUCCESS!
[root@mysql2 mysql]# ps aux |grep mysqld
mysql 76 pts/0 Sl 14:38 0:00 /usr/local/mysql/bin/mysqld --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=mysql2.err --pid-file=/usr/local/mysql/data/mysql2.pid

PATH[可选]
[root@mysql2 mysql]# mysql
-bash: mysql: command not found
[root@mysql2 mysql]# /usr/local/mysql/bin/mysql
[root@mysql1 mysql]# echo "export PATH=$PATH:/usr/local/mysql/bin" >> /etc/profile
[root@mysql1 mysql]# source /etc/profile
[root@mysql1 mysql]# mysql -uroot -p'xxxx'
mysql> alter user root@'localhost' identified by 'tianyun';

如果需要重新初始化...[可选]
# killall mysqld
# rm -rf /usr/local/mysql/data
[root@mysql1 mysql]# chown -R mysql .
[root@mysql1 mysql]# chgrp -R mysql .
[root@mysql1 mysql]# bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
[root@mysql1 mysql]# bin/mysql_ssl_rsa_setup
[root@mysql1 mysql]# chown -R root .
[root@mysql1 mysql]# chown -R mysql data mysql-files

三,sql介绍

SQL语言

SQL(Structured Query Language 即结构化查询语言)
SQL语言主要用于存取数据、查询数据、更新数据和管理关系数据库系统,SQL语言由IBM开发。
DDL语句 数据库定义语言: 数据库、表、视图、索引、存储过程,例如CREATE DROP ALTER
DML语句 数据库操纵语言: 插入数据INSERT、删除数据DELETE、更新数据UPDATE
DCL语句 数据库控制语言: 例如控制用户的访问权限GRANT、REVOKE
DQL语句 数据库查询语言: 查询数据SELECT

增删改查

库 存放数据的目录
表 文件

id name 性别
1 lilei
     
     
行:记录
列:字段 字段名称

创建一个库 create database "库名";
查看库 show databases;
进入库 use "库名";
创建表 create table "表名"(字段属性);
查看表
查看表状态 show table status like "表名" \G
查看表名称 show tables;
查看表结构 desc "表名";
查看表内容 select * from "表名";
修改表
修改表名 rename table "表名1" to "表名2"
添加字段 alter table "表名" add "字段";
删除字段 alter table "表名" drop "字段";
修改字段 alter table "表名" change "字段1" "字段2" "字段属性";//change把字段1改成字段2并指定字段属性
alter table "表名" modify "字段" "字段属性" // modify只能修改字段的属性
修改记录
添加记录 insert into "表名(字段...)" value(字段对应的值); insert into "表名" set 字段1=?,字段2=?...;
更新记录 update table "表名" set 字段=? where 字段=ID;
删除记录 delete from "表名" where "条件"; 如果id=NULL 可以delete from "表名" where id is NULL;
查询
删除表 drop table "表名";
删除库 drop database "库名";

四,库操作

系统数据库

information_schema: 虚拟库,主要存储了系统中的一些数据库对象的信息,例如用户表信息、列信息、权限信息、字符信息等
performance_schema: 主要存储数据库服务器的性能参数
mysql: 授权库,主要存储系统用户的权限信息
sys: 主要存储数据库服务器的性能参数

创建数据库:DDL

1. #mysqladmin -u root -p1 create db1
2. 直接去创建数据库目录并且修改权限
3. mysql> create database wing;

数据库命名规则:
区分大小写
唯一性
不能使用关键字如 create select
不能单独使用数字
每条sql语句都要以;结尾,但是如果列比较多,想看的清楚一点,可以以\G结尾

查看数据库

mysql> show databases;
mysql> show create database wing;

查看当前所在库:
mysql> select database();

切换数据库
mysql> use wing;
mysql> show tables;

删除数据库
DROP DATABASE 数据库名;

五,表操作

表操作概念

MySQL表操作
是数据库存储数据的基本单位,由若干个字段组成,主要用来存储数据记录。

使用编辑器编辑指令
mysql> edit
mysql> \e

命令行操作数据库脚本
# mysql -u root -p1 -e "use db2;create table t3(name char(20),pass char(100));insert into t3 set name='wing',pass=password('123')"

在mysql客户端内执行系统命令
mysql> system ls
mysql> \! ls

创建表
表:school.student1
字段 字段 字段
id name sex age
1 tom male 23 记录
2 jack male 21 记录
3 alice female 19 记录

语法:
create table 表名(
字段名1 类型[(宽度) 约束条件],
字段名2 类型[(宽度) 约束条件],
字段名3 类型[(宽度) 约束条件]
)[存储引擎 字符集];
==在同一张表中,字段名是不能相同
==宽度和约束条件可选
==字段名和类型是必须的

mysql> CREATE DATABASE school
mysql> use school;
mysql> create table student1(
-> id int,
-> name varchar(50),
-> sex enum('m','f'),
-> age int
-> );
Query OK, 0 rows affected (0.03 sec)

查看表(当前所在库)
mysql> show tables;
mysql> desc emp;
mysql> show create table emp;
mysql> show table status like 'emp' \G

查看表内容(后面单独讲表查询操作)
mysql> select id,name,sex,age from student1; //查询表中所有字段的值
Empty set (0.00 sec)

mysql> select * from student1; //查询表中所有字段的值
Empty set (0.00 sec)

mysql> select name,age from student1; //查询表中指定字段的值
Empty set (0.00 sec)

修改表:
alter 修改表名称 修改字段名称 修改字段数据类型 修改字段的修饰符
insert 插入数据
delete 删除数据
update 更新数据

修改表名称
mysql> rename table emp to abc;
mysql> alter table abc rename emp;

添加新字段
mysql> alter table t1 add math int(10);
mysql> alter table t1 add (chinese int(10),english int(10));

修改字段数据类型修饰符
mysql> alter table t1 modify chinese int(5) not null;
修改名称、数据类型、修饰符
mysql> alter table t1 change chinese china int(6);

first after
mysql> alter table t1 change english en int(6) after id;
mysql> alter table t1 modify en int(6) first;

删除字段
mysql> alter table t1 drop en;

插入数据(添加记录)
字符串必须引号引起来
mysql> insert into t1(id,name,math,china) values(1,"wing",80,90);
mysql> insert into t1(id,name,math,china) values(2,"king",70,100),(3,"tom",50,70);
mysql> insert into t1 values(4,"xiaosan",50,100);
mysql> insert into t1(id,math) values(5,70);
mysql> insert into t1 set id=6,math=65;

更新记录
mysql> update t1 set name="lili" where id=5;

删除记录
mysql> delete from t1 where id=6;
mysql> delete from t1; //删除所有记录

表复制:key不会被复制: 主键、外键和索引
复制一张表
mysql> create table t10(select * from t3);
mysql> create table t10(select id,name from t3);

复制表结构
mysql> create table t4(select * from t3 where 5=4);
mysql> create table t4(select id,name from t3 where 5=4);

复制记录
mysql> insert into t3 select * from t10 where id=9;

删除表
mysql> drop table t1;

删除库
mysql> drop database gnu;

表操作示例

MySQL表操作 DDL
是数据库存储数据的基本单位,由若干个字段组成,主要用来存储数据记录。
表的操作包括:
创建表、查看表、修改表和删除表。

这些操作都是数据库管理中最基本,也是最重要的操作。
本节内容包括:
创建表 create table
查看表结构 desc table, show create table
表完整性约束
修改表 alter table
复制表 create table ...
删除表
drop table

一、创建表(表的基本操作)
表:school.student1
字段 字段 字段
id name sex age
1 tom male 23 记录
2 jack male 21 记录
3 alice female 19 记录

语法:
create table 表名(
字段名1 类型[(宽度) 约束条件],
字段名2 类型[(宽度) 约束条件],
字段名3 类型[(宽度) 约束条件]
)[存储引擎 字符集];
==在同一张表中,字段名是不能相同
==宽度和约束条件可选
==字段名和类型是必须的

mysql> CREATE DATABASE school; //创建数据库school
mysql> use school;
mysql> create table student1(
-> id int,
-> name varchar(50),
-> sex enum('m','f'),
-> age int
-> );
Query OK, 0 rows affected (0.03 sec)

查看表(当前所在库)
mysql> show tables;
+------------------+
| Tables_in_school |
+------------------+
| student1 |
+------------------+
1 row in set (0.00 sec)

向表中插入内容
语法:
insert into 表名(字段1,字段2...) values(字段值列表...);

查看表结构


mysql> select id,name,sex,age from student1; //查询表中所有字段的值
Empty set (0.00 sec)

mysql> select * from student1; //查询表中所有字段的值
Empty set (0.00 sec)

mysql> select name,age from student1; //查询表中指定字段的值
Empty set (0.00 sec)

顺序插入
linux之mysql基础_第7张图片


只向指定的字段插入值
linux之mysql基础_第8张图片

表school.student2

                       字段名     数据类型
编号                id                    int
姓名                name              varchar(50)
出生年份        born_year      year
生日                birthday          date
上课时间        class_time      time
注册时间         reg_time         datetime

mysql> create table student2(
id int,
name varchar(50),
born_year year,
birthday date,
class_time time,
reg_time datetime
);
mysql> desc student2;
mysql> insert into student2 values(1,'tom', now(), now(), now(), now());
mysql> insert into student2 values(2,'jack',1982,19821120,123000,20140415162545);

表school.student3

id        id            int
姓名    name     varchar(50)
性别    sex         enum('male','female')
爱好    hobby     set('music','book','game','disc')

mysql> create table student3(
id int,
name varchar(50),
sex enum('male','female'),
hobby set('music','book','game','disc')
);

mysql> desc student3;
mysql> show create table student3\G
mysql> insert into student3 values (1,'tom','male','book,game');
mysql> insert into student3 values (2,'jack','male','film');

mysql> select * from student3;

二、查看表结构
DESCRIBE查看表结构
DESCRIBE 表名;
DESC 表名;

SHOW CREATE TABLE查看表详细结构

SHOW CREATE TABLE 表名;

三、表完整性约束

作用:用于保证数据的完整性和一致性

==============================================================
约束条件                         说明
PRIMARY KEY (PK)      标识该字段为该表的主键,可以唯一的标识记录, 不可以为空 UNIQUE + NOT NULL
FOREIGN KEY (FK)      标识该字段为该表的外键,实现表与表(父表主键/子表1外键/子表2外键)之间的关联
NOT NULL                      标识该字段不能为空
UNIQUE KEY (UK)         标识该字段的值是唯一的, 可以为空,一个表中可以有多个UNIQUE KEY
AUTO_INCREMENT      标识该字段的值自动增长( 整数类型,而且为主键
DEFAULT                        为该字段设置默认值
UNSIGNED                      无符号,正数
ZEROFILL                        使用0填充,例如0000001

说明:
1. 是否允许为空,默认NULL,可设置NOT NULL,字段不允许为空,必须赋值
2. 字段是否有默认值,缺省的默认值是NULL,如果插入记录时不给字段赋值,此字段使用默认值
sex enum('male','female') not null default 'male'
age int unsigned NOT NULL default 20 必须为正值(无符号) 不允许为空 默认是20
3. 是否是key
主键 primary key
外键 forengn key
索引 (index,unique...)
==============================================================

===DEFAULT、NOT NULL

表school.student4

linux之mysql基础_第9张图片

linux之mysql基础_第10张图片

mysql> insert into student4 values(1,'jack','m',20,'book');
Query OK, 1 row affected (0.00 sec)

mysql> select * from student4;

mysql> insert into student4(id,name) values(2,'robin');
Query OK, 1 row affected (0.00 sec)

mysql> insert into student4 values(3, NULL,'m',40,'book');
ERROR 1048 (23000): Column 'name' cannot be null

===设置唯一约束 UNIQUE

表company.department1

CREATE TABLE company.department1 (
dept_id INT,
dept_name VARCHAR(30) UNIQUE,
comment VARCHAR(50)
);
linux之mysql基础_第11张图片

表company.department2

CREATE TABLE company.department2 (
dept_id INT,
dept_name VARCHAR(30),
comment VARCHAR(50),
CONSTRAINT uk_name UNIQUE(dept_name)
);
linux之mysql基础_第12张图片

===设置主键约束 PRIMARY KEY
primary key 字段的值是不允许重复,且不允许不NULL( UNIQUE + NOT NULL
单列做主键
多列做主键(复合主键)


单列做主键

表school.student6 方法一

mysql> create table student6(
-> id int primary key not null auto_increment,
-> name varchar(50) not null,
-> sex enum('male','female') not null default 'male',
-> age int not null default 18
-> );
Query OK, 0 rows affected (0.00 sec)

表school.student7 方法二

mysql> create table student7(
-> id int auto_increment not null,
-> name varchar(50) not null,
-> sex enum('male','female') not null default 'male',
-> age int not null default 18,
-> CONSTRAINT pk_id primary key(id)
-> );
Query OK, 0 rows affected (0.00 sec)

linux之mysql基础_第13张图片

mysql> insert into student6 values (1,'alice','female',22);
mysql> insert into student6(name,sex,age) values
-> ('jack','male',19),
-> ('tom','male',23);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0

mysql> select * from student6;
+----+-------+------+-----+
| id | name | sex | age |
+----+-------+------+-----+
| 1 | alice | female | 22 |
| 2 | jack | male | 19 |
| 3 | tom | male | 23 |
+----+-------+------+-----+
3 rows in set (0.00 sec)

linux之mysql基础_第14张图片

复合主键

表school.service

host_ip 主机IP
service_name 服务名
port 服务对应的端口
allow(Y,N) 服务是否允许访问
主键: host_ip + port = primary key

PRI PRI
192.168.122.223 http 80 Y
192.168.122.223 ftp 21 Y
192.168.122.220 http 80 Y

mysql> create table service(
-> host_ip varchar(15) not null,
-> service_name varchar(10) not null,
-> port varchar(5) not null,
-> allow enum('Y','N') default 'N',
-> primary key(host_ip,port)
-> );
Query OK, 0 rows affected (0.00 sec)

linux之mysql基础_第15张图片

mysql> insert into service values ('192.168.2.168','ftp','21','Y');

mysql> insert into service values ('192.168.2.168','httpd','80','Y');

linux之mysql基础_第16张图片
linux之mysql基础_第17张图片

mysql> desc mysql.user;
+------------------------+-----------------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------------+-----------------------------------+------+-----+---------+-------+
| Host | char(60) | NO | PRI | | |
| User | char(16) | NO | PRI | | |
| Password | char(41) | NO | | | |
| Select_priv | enum('N','Y') | NO | | N | |
| Insert_priv | enum('N','Y') | NO | | N | |

===设置字段值增 AUTO_INCREMENT

表company.department3


CREATE TABLE department3 (
dept_id INT PRIMARY KEY AUTO_INCREMENT,
dept_name VARCHAR(30),
comment VARCHAR(50)
);

===设置外键约束 FOREIGN KEY

父表company.employees

mysql> create table employees(
-> name varchar(50) not null, 主键
-> mail varchar(20),
-> primary key(name)
-> ) engine=innodb;

子表company.payroll

mysql> create table payroll(
-> id int not null auto_increment,
-> name varchar(50) not null, 外键
-> payroll float(10,2) not null,
-> primary key(id),
-> foreign key(name) references employees(name) on update cascade on delete cascade
-> ) engine=innodb;
子表name外键,关联父表(employees 主键name),同步更新,同步删除
linux之mysql基础_第18张图片

mysql> update employees set name='tomaaa' where name='tom';
mysql> delete from employees where name='alice';
结论:
当父表中某个员工的记录修改时,子表也会同步修改
当父表中删除某个员工的记录,子表也会同步删除
四、修改表ALTER TABLE
语法:
1. 修改表名
ALTER TABLE 表名
RENAME 新表名;

2. 增加字段
ALTER TABLE 表名
ADD 字段名 数据类型 [完整性约束条件…],
ADD 字段名 数据类型 [完整性约束条件…];
ALTER TABLE 表名
ADD 字段名 数据类型 [完整性约束条件…] FIRST;
  ALTER TABLE 表名
ADD 字段名 数据类型 [完整性约束条件…] AFTER 字段名;

3. 删除字段
ALTER TABLE 表名
DROP 字段名;

4. 修改字段
ALTER TABLE 表名
MODIFY 字段名 数据类型 [完整性约束条件…];
ALTER TABLE 表名
CHANGE 旧字段名 新字段名 旧数据类型 [完整性约束条件…];
ALTER TABLE 表名
CHANGE 旧字段名 新字段名 新数据类型 [完整性约束条件…];

示例:
1. 修改存储引擎
mysql> alter table service
-> engine=innodb; //engine=myisam|memory|....

2. 添加字段
mysql> create table student10 (id int);
mysql> alter table student10
-> add name varchar(20) not null,
-> add age int not null default 22;

mysql> alter table student10
-> add stu_num int not null after name; //添加name字段之后

mysql> alter table student10
-> add sex enum('male','female') default 'male' first; //添加到最前面

3. 删除字段
mysql> alter table student10
-> drop sex;

mysql> alter table service
-> drop mac;

4. 修改字段类型modify
mysql> alter table student10
-> modify age tinyint not null default 22; //注意保留原有的约束条件

mysql> alter table student10
-> modify id int not null primary key ; //修改字段类型、约束、主键

5. 增加约束(针对已有的主键增加auto_increment)
mysql> alter table student10 modify id int not null primary key auto_increment; //错误,该字段已经是primary key
ERROR 1068 (42000): Multiple primary key defined

mysql> alter table student10 modify id int not null auto_increment;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0

6. 增加复合主键
mysql> alter table service2
-> add primary key(host_ip,port);

7. 增加主键
mysql> alter table student1
-> add primary key(id);

8. 增加主键和自动增长
mysql> alter table student1
-> modify id int not null primary key auto_increment;

9. 删除主键[primary key auto_increment]
a. 删除自增约束
mysql> alter table student10 modify id int not null;

b. 删除主键
mysql> alter table student10
-> drop primary key;

五、复制表
复制表结构+记录 (key不会复制: 主键、外键和索引)
mysql> create table new_service select * from service;

只复制表结构

mysql> create table new1_service select * from service where 1=2; //条件为假,查不到任何记录

复制表结构,包括Key
mysql> create table t4 like employees;

六、删除表
DROP TABLE 表名;
========================================================

六,数据操作(开发)

MySQL数据操作:DML

========================================================
在MySQL管理软件中,可以通过SQL语句中的DML语言来实现数据的操作,包括使用INSERT实现数据
的插入、DELETE实现数据的删除以及UPDATE实现数据的更新。
更新数据 insert
更新数据 update
删除数据 delete


一、插入数据INSERT
1. 插入完整数据(顺序插入)
语法一:
INSERT INTO 表名(字段1,字段2,字段3…字段n) VALUES (值1,值2,值3…值n);

语法二:
INSERT INTO 表名 VALUES (值1,值2,值3…值n);

2. 指定字段插入数据
语法:
INSERT INTO 表名(字段2,字段3…) VALUES (值2,值3…);

3. 插入多条记录
语法:
INSERT INTO 表名 VALUES
(值1,值2,值3…值n),
(值1,值2,值3…值n),
(值1,值2,值3…值n);

4. 插入查询结果
语法:
INSERT INTO 表1(字段1,字段2,字段3…字段n)
SELECT (字段1,字段2,字段3…字段n) FROM 表2
WHERE …;
linux之mysql基础_第19张图片

二、更新数据UPDATE
语法:
UPDATE 表名 SET
字段1=值1,
字段2=值2,
WHERE CONDITION;
示例:
linux之mysql基础_第20张图片

三、删除数据DELETE
语法:
DELETE FROM 表名
WHERE CONITION;
示例:
DELETE FROM mysql.user
WHERE authentication_string=’’;

七,单表查询

MySQL单表查询SELECT

: DQL

========================================================
简单查询
通过条件查询
查询排序
限制查询记录数
使用集合函数查询
分组查询
使用正则表达式查询

表company.employee5

雇员编号             id                              int
雇员姓名             name                       varchar(30)
雇员性别             sex                           enum
雇用时期             hire_date                date
职位                      post                         varchar(50)
职位描述             job_description       varchar(100)
薪水                     salary                        double(15,2)
办公室                 office                         int
部门编号             dep_id                       int

mysql> CREATE TABLE company.employee5(
id int primary key AUTO_INCREMENT not null,
name varchar(30) not null,
sex enum('male','female') default 'male' not null,
hire_date date not null,
post varchar(50) not null,
job_description varchar(100),
salary double(15,2) not null,
office int,
dep_id int
);
linux之mysql基础_第21张图片

mysql> insert into company.employee5(name,sex,hire_date,post,job_description,salary,office,dep_id) values
('jack','male','20180202','instructor','teach',5000,501,100),
('tom','male','20180203','instructor','teach',5500,501,100),
('robin','male','20180202','instructor','teach',8000,501,100),
('alice','female','20180202','instructor','teach',7200,501,100),
('tianyun','male','20180202','hr','hrcc',600,502,101),
('harry','male','20180202','hr', NULL,6000,502,101),
('emma','female','20180206','sale','salecc',20000,503,102),
('christine','female','20180205','sale','salecc',2200,503,102),
('zhuzhu','male','20180205','sale', NULL,2200,503,102),
('gougou','male','20180205','sale','',2200,503,102);

[root@ slave2 ~]# mysqldump -p"(tianyunTIANYUN123)" -B company --single-transaction > company.sql

[root@ slave1 ~]# wget ftp://10.18.40.100/tianyun/company.sql
[root@ slave1 ~]# mysql -p'TianYun520^&*' < company.sql

一、简单查询
简单查询
SELECT * FROM employee5;
SELECT name, salary, dep_id FROM employee5;

避免重复DISTINCT
SELECT post FROM employee5;
SELECT DISTINCT post FROM employee5;
注:不能部分使用DISTINCT,通常仅用于某一字段。

通过四则运算查询
SELECT name, salary, salary*14 FROM employee5;
SELECT name, salary, salary*14 AS Annual_salary FROM employee5;
SELECT name, salary, salary*14 Annual_salary FROM employee5;

定义显示格式
CONCAT() 函数用于连接字符串
SELECT CONCAT(name, ' annual salary: ', salary*14 ) AS Annual_salary FROM employee5;

二、单条件查询
单条件查询
SELECT name,post
FROM employee5
WHERE post='hr';

多条件查询
SELECT name,salary
FROM employee5
WHERE post='hr' AND salary>10000;

关键字BETWEEN AND
SELECT name,salary FROM employee5
WHERE salary BETWEEN 5000 AND 15000;

SELECT name,salary FROM employee5
WHERE salary NOT BETWEEN 5000 AND 15000;

关键字IS NULL
SELECT name,job_description FROM employee5
WHERE job_description IS NULL;

SELECT name,job_description FROM employee5
WHERE job_description IS NOT NULL;

SELECT name,job_description FROM employee5
WHERE job_description='';

关键字IN集合查询
SELECT name, salary FROM employee5
WHERE salary=4000 OR salary=5000 OR salary=6000 OR salary=9000 ;

SELECT name, salary FROM employee5
WHERE salary IN (4000,5000,6000,9000) ;

SELECT name, salary FROM employee
WHERE salary NOT IN (4000,5000,6000,9000) ;

关键字LIKE模糊查询
通配符’%’
SELECT * FROM employee5
WHERE name LIKE 'al%';

通配符’_’
SELECT * FROM employee5
WHERE name LIKE 'al _ _ _';

三、查询排序
按单列排序
SELECT * FROM employee5 ORDER BY salary;
SELECT name, salary FROM employee5 ORDER BY salary ASC;
SELECT name, salary FROM employee5 ORDER BY salary DESC;

按多列排序
SELECT * FROM employee5
ORDER BY hire_date DESC,
salary ASC;
linux之mysql基础_第22张图片

先按入职时间,再按薪水排序

linux之mysql基础_第23张图片

先按职位,再按薪水排序

linux之mysql基础_第24张图片

四、限制查询的记录数
示例:
SELECT * FROM employee5 ORDER BY salary DESC
LIMIT 5; //默认初始位置为0

SELECT * FROM employee5 ORDER BY salary DESC
LIMIT 0,5;

SELECT * FROM employee5 ORDER BY salary DESC
LIMIT 3,5; //从第4条开始,共显示5条

五、使用集合函数查询
示例:
SELECT COUNT(*) FROM employee5;
SELECT COUNT(*) FROM employee5 WHERE dep_id=101;
SELECT MAX(salary) FROM employee5;
SELECT MIN(salary) FROM employee5;
SELECT AVG(salary) FROM employee5;
SELECT SUM(salary) FROM employee5;
SELECT SUM(salary) FROM employee5 WHERE dep_id=101;
linux之mysql基础_第25张图片

六、分组查询
GROUP BY和GROUP_CONCAT()函数一起使用
SELECT dep_id, GROUP_CONCAT(name ) FROM employee5 GROUP BY dep_id;
SELECT dep_id, GROUP_CONCAT(name ) as emp_members FROM employee5 GROUP BY dep_id;
linux之mysql基础_第26张图片

linux之mysql基础_第27张图片

GROUP BY和集合函数一起使用
linux之mysql基础_第28张图片

七、使用正则表达式查询
SELECT * FROM employee5 WHERE name REGEXP '^ali';

SELECT * FROM employee5 WHERE name REGEXP 'yun$';

SELECT * FROM employee5 WHERE name REGEXP 'm{2}';

小结:对字符串匹配的方式

WHERE name = 'tom';
WHERE name LIKE 'to%';
WHERE name REGEXP 'yun$';

八,多表查询

MySQL多表查询 DQL

========================================================
多表连接查询
复合条件连接查询
子查询


一、准备两张表

表company.employee6

linux之mysql基础_第29张图片
linux之mysql基础_第30张图片

表company.department6

linux之mysql基础_第31张图片
linux之mysql基础_第32张图片


二、多表的连接查询
交叉连接: 生成笛卡尔积,它不使用任何匹配条件

内连接: 只连接匹配的行


外连接之左连接: 会显示左边表内所有的值,不论在右边表内匹不匹配
外连接之右连接: 会显示右边表内所有的值,不论在左边表内匹不匹配
全外连接: 包含左、右两个表的全部行

=================交叉连接=======================
linux之mysql基础_第33张图片

=================内连接=======================

只找出有部门的员工 (部门表中没有natasha所在的部门)

linux之mysql基础_第34张图片 linux之mysql基础_第35张图片

外连接语法:
SELECT 字段列表
    FROM 表1 LEFT|RIGHT JOIN 表2
    ON 表1.字段 = 表2.字段;

=================外连接(左连接 left join)=======================
mysql> select emp_id,emp_name,dept_name from employee6 left join department6 on employee6.dept_id = department6.dept_id;

找出所有员工及所属的部门,包括没有部门的员工

linux之mysql基础_第36张图片



=================外连接(右连接right join)=======================
mysql> select emp_id,emp_name,dept_name from employee6 right join department6 on employee6.dept_id = department6.dept_id;

找出所有部门包含的员工,包括空部门

linux之mysql基础_第37张图片

=================全外连接=======================
mysql> select * from employee6 full join department6;
+--------+----------+---------+---------+-----------+
| emp_id | emp_name | dept_id | dept_id | dept_name |
+--------+----------+---------+---------+-----------+
| 1 | tianyun | 200 | 200 | hr |
| 1 | tianyun | 200 | 201 | it |
| 1 | tianyun | 200 | 202 | sale |
| 1 | tianyun | 200 | 203 | fd |
| 2 | tom | 201 | 200 | hr |
| 2 | tom | 201 | 201 | it |
| 2 | tom | 201 | 202 | sale |
| 2 | tom | 201 | 203 | fd |
| 3 | jack | 201 | 200 | hr |
| 3 | jack | 201 | 201 | it |
| 3 | jack | 201 | 202 | sale |
| 3 | jack | 201 | 203 | fd |
| 4 | alice | 202 | 200 | hr |
| 4 | alice | 202 | 201 | it |
| 4 | alice | 202 | 202 | sale |
| 4 | alice | 202 | 203 | fd |
| 5 | robin | 200 | 200 | hr |
| 5 | robin | 200 | 201 | it |
| 5 | robin | 200 | 202 | sale |
| 5 | robin | 200 | 203 | fd |
| 6 | natasha | 204 | 200 | hr |
| 6 | natasha | 204 | 201 | it |
| 6 | natasha | 204 | 202 | sale |
| 6 | natasha | 204 | 203 | fd |
+--------+----------+---------+---------+-----------+
24 rows in set (0.00 sec)

三、复合条件连接查询
示例1:以 内连接的方式查询employee6和department6表,并且employee6表中的age字段值必须大于25
找出公司所有部门中年龄大于25岁的员工
linux之mysql基础_第38张图片

示例2:以 内连接的方式查询employee6和department6表,并且以age字段的升序方式显示
linux之mysql基础_第39张图片

四、子查询
子查询是将一个查询语句嵌套在另一个查询语句中。
内层查询语句的查询结果,可以为外层查询语句提供查询条件。
子查询中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等关键字
还可以包含比较运算符:= 、 !=、> 、<等

1. 带IN关键字的子查询
查询employee表,但dept_id必须在department表中出现过
linux之mysql基础_第40张图片

2. 带比较运算符的子查询
=、!=、>、>=、<、<=、<>
查询年龄大于等于25岁员工所在部门(查询老龄化的部门)
linux之mysql基础_第41张图片

3. 带EXISTS关键字的子查询
EXISTS关字键字表示存在。在使用EXISTS关键字时,内层查询语句不返回查询的记录,而是返回一个真假值。
Ture或False,当返回Ture时,外层查询语句将进行查询;当返回值为False时,外层查询语句不进行查询

department表中存在dept_id=203,Ture
linux之mysql基础_第42张图片
department表中存在dept_id=300,False
linux之mysql基础_第43张图片

九,数据类型

1,数值类型

整型

作用:用于存储用户的年龄、游戏的Level、经验值等。
分类:tinyint smallint mediumint int bigint
有符号 :
有正负数
无符号 :

没有负数 类型后面使用unsigned和zerofill修饰符

存储数据大小范围:
1个字节 2个字节 3个字节 4个字节 8个字节
8bit 16 24 32 64
11111111

无符号:范围运算公式 0到2^n-1
比如:
tinyint:0到255
bigint: 0到2^64-1

有符号:范围运算公式 -2^(n-1)到2^(n-1)-1
比如:
tinyint:-128到127

显示宽度:
类型后面小括号内的数字是显示宽度,不能限制插入数值的大小
比如:bigint(2) 2是显示宽度

定义无符号整型:
unsigned:
mysql> create table t6(id bigint(2) unsigned);

zerofill:
mysql> create table t2 (
-> id1 int zerofill,
-> id2 int(6) zerofill
-> );
Query OK, 0 rows affected (0.05 sec)

mysql> desc t2;
+-------+---------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------------------------+------+-----+---------+-------+
| id1 | int(10) unsigned zerofill | YES | | NULL | |
| id2 | int(6) unsigned zerofill | YES | | NULL | |
+-------+---------------------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> insert into t2 values(2,2);
Query OK, 1 row affected (0.01 sec)

mysql> select * from t2;
+------------+--------+
| id1 | id2 |
+------------+--------+
| 0000000002 | 000002 |
+------------+--------+
1 row in set (0.00 sec)

浮点型
作用:用于存储用户的身高、体重、薪水等
float(5,3) 5宽度 3精度

mysql> create table t12(id float(6,2));

double(5,3)

定点型
定点数在MySQL内部以字符串形式存储,比浮点数更精确,适合用来表示货币等精度高的数据。
decimal(5,3)

位类型(了解)
BIT(M)可以用来存放多位二进制数,M范围从1~64,如果不写默认为1位
对于位字段可以使用函数读取:
bin()显示为二进制
hex()显示为十六进制
mysql> create table test_bit (id bit(4)); //4bit能存储的最大值为15
mysql> desc test_bit;
+-------+--------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------+------+-----+---------+-------+
| id | bit(4) | YES | | NULL | |
+-------+--------+------+-----+---------+-------+

mysql> insert into test_bit values(4);

mysql> select * from test_bit;
+------+
| id |
+------+
| |
+------+

mysql> select bin(id),hex(id) from test_bit;
+---------+---------+
| bin(id) | hex(id) |
+---------+---------+
| 100 | 4 |
+---------+---------+

1 row in set (0.00 sec)

2,字符串类型

字符串类型
作用:用于存储用户的姓名、爱好、发布的文章等
======================================
字符类型 char varchar
char(10) 根据10,占10个.
列的长度固定为创建表时声明的长度: 0 ~ 255
varchar(10) 根据实际字符串长度占空间,最多10个
列中的值为可变长字符串,长度: 0 ~ 65535

在检索的时候,CHAR列删除了尾部的空格,而VARCHAR则保留这些空格
mysql> create table vc (
-> v varchar(4),
-> c char(4)
-> );

mysql> desc vc;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| v | varchar(4) | YES | | NULL | |
| c | char(4) | YES | | NULL | |
+-------+------------+------+-----+---------+-------+

mysql> insert into vc values('ab ','ab ');

mysql> select * from vc;
+------+------+
| v | c |
+------+------+
| ab | ab |
+------+------+

mysql> select length(v),length(c) from vc;
+-----------+-----------+
| length(v) | length(c) |
+-----------+-----------+
| 4 | 2 |
+-----------+-----------+

mysql> select concat(v,'='), concat(c,'=') from vc; //在后面加字符'=',看的更清楚
+---------------+---------------+
| concat(v,'=') | concat(c,'=') |
+---------------+---------------+
| ab = | ab= |
+---------------+---------------+

二进制类型 BINARY和VARBINARY
与 CHAR和VARCHAR类型有点类似,不同的是BINARY和VARBINARY存储的是二进制的字符串,而非字符型字符串。也就是说,BINARY和VARBINARY没有字符集的概念,对其排序和比较都是按照二进制值进行对比。
BINARY(N)和VARBINARY(N)中的N指的是字节长度,而CHAR(N)和VARCHAR(N)中N指的是的字符长度。对于BINARY(10) ,其可存储的字节固定为10,而对于CHAR(10) ,其可存储的字节视字符集的情况而定。

文本类型 BLOB和TEXT
能用varchar就不用text,长度不够的时候再使用text
blob与text的区别和binary与char的区别一样,blob以字节形式存储,text以字符形式存储

TINYBLOB
TINYTEXT
一个BLOB或TEXT列,最大长度为255(2^8-1)个字节或字符。

BLOB
TEXT
一个BLOB或TEXT列,最大长度为65535(2^16-1)个字节或字符。

MEDIUMBLOB
MEDIUMTEXT
一个BLOB或TEXT列,最大长度为16777215(2^24-1)个字节或字符。

LONGBLOB
LONGTEXT
一个BLOB或TEXT列,最大长度为4294967295(2^32-1)个字节或字符。

1.经常变化的字段用varchar
2.知道固定长度的用char
3.尽量用varchar
4.超过255字符的只能用varchar或者text
5.能用varchar的地方不用text

枚举类型 enum
mysql> create table t101(name enum('wing','jim'));
只能从wing,jim两个里面2选其1

注:
enumerate 英[ɪˈnju:məreɪt] 美[ɪˈnu:məreɪt]

集合类型 set
mysql> create table t204(name set('wing','jim'));
mysql> insert into t204 set name="jim,wing";
跟enum一样被限定范围,但是可以同插入多个数据

3,时间类型

日期类型
===时间和日期类型测试:year、date、time、datetime、timestamp
作用:用于存储用户的注册时间,文章的发布时间,文章的更新时间,员工的入职时间等

date
09-09 09/09

2018

00-69 21世纪
70-99 20世纪

time
050510 05:05:10

datetime
141125050510

timestamp
141125050510

a b
1 null

和datetime不同的是:当插入值为null的时候,显示值也会是当前的时间
mysql> insert into t values(null);

mysql> create table test_time( d date, t time, dt datetime );

mysql> insert into test_time values(now(),now(),now());
Query OK, 1 row affected, 2 warnings (0.00 sec)

mysql> select * from test_time;
+------------+----------+---------------------+
| d | t | dt |
+------------+----------+---------------------+
| 2018-01-11 | 10:59:57 | 2018-01-11 10:59:57 |
+------------+----------+---------------------+

now() year() month() day() minute() hour() second()

4,数据类型

MySQL数据类型

一、MySQL常见的数据类型
在MySQL数据库管理系统中,可以通过存储引擎来决定表的类型。同时,MySQL数据库管理系统也
提供了数据类型决定表存储数据的类型。MySQL数据库管理系统提供的数据类型:

数值类型:
整数类型 TINYINT SMALLINT MEDIUMINT INT BIGINT
浮点数类型 FLOAT DOUBLE
定点数类型 DEC
位类型 BIT

字符串类型:
CHAR系列 CHAR VARCHAR
TEXT系列 TINYTEXT TEXT MEDIUMTEXT LONGTEXT
BLOB 系列 TINYBLOB BLOB MEDIUMBLOB LONGBLOB
BINARY系列 BINARY VARBINARY
枚举类型: ENUM
集合类型: SET

时间和日期类型: DATE TIME DATETIME TIMESTAMP YEAR

二、数据类型测试
===整数类型测试:tinyint,int
作用:用于存储用户的年龄、游戏的Level、经验值等。


LAB1:
mysql> create table test1(
-> tinyint_test tinyint,
-> int_test int
-> );

mysql> desc test1;
+--------------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+------------+------+-----+---------+-------+
| tinyint_test | tinyint(4) | YES | | NULL | |
| int_test | int(11) | YES | | NULL | |
+--------------+------------+------+-----+---------+-------+
2 rows in set (0.01 sec)

mysql> insert into test1 values (111,111);
Query OK, 1 row affected (0.09 sec)

mysql> insert into test1(tinyint_test) values(128);
ERROR 1264 (22003): Out of range value for column 'tinyint_test' at row 1

mysql> insert into test1(int_test) values(2147483647);
Query OK, 1 row affected (0.05 sec)

mysql> insert into test1(int_test) values(2147483648);
ERROR 1264 (22003): Out of range value for column 'int_test' at row 1

//测试结果,默认有符号,超过存储范围出错。

LAB2: 无符号整形测试
mysql> create table test2(
-> tinyint_test tinyint unsigned, //约束条件unsigned限定只能存正值(无符号)
-> int_test int unsigned
-> );
Query OK, 0 rows affected (0.00 sec)

mysql> desc test2;
+--------------+---------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------+---------------------+------+-----+---------+-------+
| tinyint_test | tinyint(3) unsigned | YES | | NULL | |
| int_test | int(10) unsigned | YES | | NULL | |
+--------------+---------------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> insert into test2(tinyint_test) values(255);
Query OK, 1 row affected (0.06 sec)

mysql> insert into test2(int_test) values(2147483648);
Query OK, 1 row affected (1.87 sec)

mysql> insert into test2 values(-20,-20);
ERROR 1264 (22003): Out of range value for column 'tinyint_test' at row 1


测试整数类型的显示宽度
mysql> create table t1 (
-> id1 int,
-> id2 int(6)
-> );

mysql> desc t1;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id1 | int(11) | YES | | NULL | |
| id2 | int(6) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+

mysql> insert into t1 values(1,1);
Query OK, 1 row affected (0.00 sec)

mysql> select * from t1;
+------+------+
| id1 | id2 |
+------+------+
| 1 | 1 |
+------+------+
1 row in set (0.00 sec)


mysql> create table t2 (
-> id1 int zerofill,
-> id2 int(6) zerofill
-> );
Query OK, 0 rows affected (0.05 sec)

mysql> desc t2;
+-------+---------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------------------------+------+-----+---------+-------+
| id1 | int(10) unsigned zerofill | YES | | NULL | |
| id2 | int(6) unsigned zerofill | YES | | NULL | |
+-------+---------------------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> insert into t2 values(2,2);
Query OK, 1 row affected (0.01 sec)

mysql> select * from t2;
+------------+--------+
| id1 | id2 |
+------------+--------+
| 0000000002 | 000002 |
+------------+--------+
1 row in set (0.00 sec)


mysql> insert into t2 values(3,2222222); //插入大于宽度限制的值,仍然可以存储
Query OK, 1 row affected (0.03 sec)

mysql> select * from t2;
+------------+---------+
| id1 | id2 |
+------------+---------+
| 0000000002 | 000002 |
| 0000000003 | 2222222 |
+------------+---------+
2 rows in set (0.00 sec)

结论:整形的宽度仅为显示宽度,不是限制。因此建议整形无须指定宽度。

===浮点数类型测试:
作用:用于存储用户的身高、体重、薪水等

浮点数和定点数都可以用类型名称后加(M,D)的方式来表示,(M,D)表示一共显示M位数字(整数位
+小数位),其中D位于小数点后面,M和D又称为精度和标度。

float和double在不指定精度时,默认会按照实际的精度(由实际的硬件和操作系统决定)来显示,
而decimal在不指定精度时,默认的整数位为10,默认的小数位为0

定点数在MySQL内部以字符串形式存储,比浮点数更精确,适合用来表示货币等精度高的数据。

mysql> create table test4(float_test float(5,2)); //一共5位,小数占2位
Query OK, 0 rows affected (0.00 sec)

mysql> desc test4;
+------------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+------------+------+-----+---------+-------+
| float_test | float(5,2) | YES | | NULL | |
+------------+------------+------+-----+---------+-------+
1 row in set (0.00 sec)

mysql> insert into test4 values (10.2), (70.243), (70.246);
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0

mysql> select * from test4;
+------------+
| float_test |
+------------+
| 10.20 |
| 70.24 |
| 70.25 |
+------------+
3 rows in set (0.00 sec)

mysql> insert into test4 values (1111.2);
ERROR 1264 (22003): Out of range value for column 'float_test' at row 1


定点数decimal测试:
mysql> create table test5(decimal_test decimal(5,2));

mysql> insert into test5 values (70.245);
Query OK, 1 row affected, 1 warning (0.05 sec)

mysql> show warnings;
+-------+------+---------------------------------------------------+
| Level | Code | Message |
+-------+------+---------------------------------------------------+
| Note | 1265 | Data truncated for column 'decimal_test' at row 1 |
+-------+------+---------------------------------------------------+
1 row in set (0.00 sec)



===位类型测试:BIT
BIT(M)可以用来存放多位二进制数,M范围从1~64,如果不写默认为1位
对于位字段可以使用函数读取:
bin()显示为二进制
hex()显示为十六进制
mysql> create table test_bit (id bit( 4));
Query OK, 0 rows affected (0.35 sec)

mysql> desc test_bit;
+-------+--------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------+------+-----+---------+-------+
| id | bit( 4) | YES | | NULL | |
+-------+--------+------+-----+---------+-------+
1 row in set (0.01 sec)

mysql> insert into test_bit values(4);

mysql> select * from test_bit;
+------+
| id |
+------+
| |
+------+
1 row in set (0.00 sec)


mysql> select bin(id ), hex(id ) from test_bit;
+---------+---------+
| bin(id) | hex(id) |
+---------+---------+
| 100 | 4 |
+---------+---------+
1 row in set (0.00 sec)

插入超过指定宽度的值:
mysql> insert into test_bit values(8);
Query OK, 1 row affected (0.05 sec)

mysql> insert into test_bit values(9);
Query OK, 1 row affected (0.06 sec)

mysql> insert into test_bit values(16);
ERROR 1406 (22001): Data too long for column 'id' at row 1



===时间和日期类型测试:year、date、time、datetime、timestamp
作用:用于存储用户的注册时间,文章的发布时间,文章的更新时间,员工的入职时间等

mysql> create table test_time(
-> d date,
-> t time,
-> dt datetime
-> );
Query OK, 0 rows affected (0.03 sec)

mysql> desc test_time;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| d | date | YES | | NULL | |
| t | time | YES | | NULL | |
| dt | datetime | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
3 rows in set (0.01 sec)

mysql> insert into test_time values( now(), now(), now());
Query OK, 1 row affected, 1 warning (0.02 sec)

mysql> select * from test_time;
+------------+----------+---------------------+
| d | t | dt |
+------------+----------+---------------------+
| 2013-12-18 | 00:06:10 | 2013-12-18 00:06:10 |
+------------+----------+---------------------+
1 row in set (0.00 sec)


mysql> create table t(id timestamp);
Query OK, 0 rows affected (0.01 sec)

mysql> desc t;
+-------+-----------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------+------+-----+-------------------+-----------------------------+
| id | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------+-----------+------+-----+-------------------+-----------------------------+
1 row in set (0.00 sec)


mysql> insert into t values( null);
Query OK, 1 row affected (0.00 sec)

mysql> select * from t;
+---------------------+
| id |
+---------------------+
| 2013-12-18 00:08:41 |
+---------------------+
1 row in set (0.00 sec)


注意事项:
其它的时间,按要求插入
==插入年份时,尽量使用4位值
==插入两位年份时,<=69,以20开头,比如65, 结果2065
>=70,以19开头,比如82,结果1982

mysql> create table t3(born_year year);
Query OK, 0 rows affected (0.40 sec)

mysql> desc t3;
+-----------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------+------+-----+---------+-------+
| born_year | year(4) | YES | | NULL | |
+-----------+---------+------+-----+---------+-------+
1 row in set (0.00 sec)


mysql> insert into t3 values
-> (12),(80);
Query OK, 2 rows affected (0.06 sec)
Records: 2 Duplicates: 0 Warnings: 0

mysql> select * from t3;
+-----------+
| born_year |
+-----------+
| 2012 |
| 1980 |
+-----------+
2 rows in set (0.00 sec)


===字符串类型测试:CHAR、VARCHAR
作用:用于存储用户的姓名、爱好、发布的文章等

CHAR 列的长度固定为创建表时声明的长度: 0 ~ 255
VARCHAR 列中的值为可变长字符串,长度: 0 ~ 65535

注:在检索的时候,CHAR列删除了尾部的空格,而VARCHAR则保留这些空格

mysql> create table vc (
-> v varchar(4),
-> c char(4)
-> );
Query OK, 0 rows affected (0.03 sec)

mysql> desc vc;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| v | varchar(4) | YES | | NULL | |
| c | char(4) | YES | | NULL | |
+-------+------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> insert into vc values('ab ','ab ');
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> select * from vc;
+------+------+
| v | c |
+------+------+
| ab | ab |
+------+------+
1 row in set (0.00 sec)

mysql> select length(v),length(c) from vc;
+-----------+-----------+
| length(v) | length(c) |
+-----------+-----------+
| 4 | 2 |
+-----------+-----------+
1 row in set (0.00 sec)

mysql> select concat(v,'='), concat(c,'=') from vc; //在后面加字符'=',看的更清楚
+---------------+---------------+
| concat(v,'=') | concat(c,'=') |
+---------------+---------------+
| ab = | ab= |
+---------------+---------------+
1 row in set (0.00 sec)


字符串类型测试:BINARY、VARBINARY
BINARY 和 VARBINARY类似于CHAR 和 VARCHAR,不同的是它们包含二进制字符而不包含
非二进制字符串

mysql> create table binary_t (c binary(3));
Query OK, 0 rows affected (0.03 sec)

mysql> desc binary_t;
+-------+-----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------+------+-----+---------+-------+
| c | binary(3) | YES | | NULL | |
+-------+-----------+------+-----+---------+-------+
1 row in set (0.00 sec)

mysql> insert into binary_t set c='aaa';
Query OK, 1 row affected (0.00 sec)

mysql> select *,hex(c) from binary_t;
+------+--------+
| c | hex(c) |
+------+--------+
| aaa | 616161 |
+------+--------+
1 row in set (0.00 sec)


===字符串类型
===ENUM类型即枚举类型、集合类型SET测试
字段的值只能在给定范围中选择
常见的是单选按钮和复选框
enum 单选 只能在给定的范围内选一个值,如性别 sex 男male/女female
set 多选 在给定的范围内可以选择一个或一个以上的值(爱好1,爱好2,爱好3...)
表school.student3
姓名 name varchar(50)
性别 sex enum('m','f')
爱好 hobby set('music','book','game','disc')


mysql> use school
mysql> create table student3(
-> name varchar(50),
-> sex enum('m','f'),
-> hobby set('music','book','game','disc')
-> );
Query OK, 0 rows affected (0.31 sec)

mysql> desc student3;
+-------+-----------------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------------------------------+------+-----+---------+-------+
| name | varchar(50) | YES | | NULL | |
| sex | enum('m','f') | YES | | NULL | |
| hobby | set('music','book','game','disc') | YES | | NULL | |
+-------+-----------------------------------+------+-----+---------+-------+
3 rows in set (0.00 sec)

mysql> insert into student3 values
-> ('tom','m','book,game');
Query OK, 1 row affected (0.00 sec)

mysql> select * from student3;
+------+------+-----------+
| name | sex | hobby |
+------+------+-----------+
| tom | boy | book,game |
+------+------+-----------+
1 row in set (0.00 sec)

mysql> insert into student3 values ('jack','m','film');
ERROR 1265 (01000): Data truncated for column 'hobby' at row 1


mysql> show create table student3\G
*************************** 1. row ***************************
Table: student3
Create Table: CREATE TABLE `student3` (
`name` varchar(50) default NULL,
`sex` enum('m','f') default NULL,
`hobby` set('music','book','game','disc') default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.00 sec)
========================================================

十,约束

约束(修饰符)
null
not null

当一个字段被设置不能为空(not null)但是又没有给设置值的时候会按不同类型给与默认值
数值 0
字符串 空
enum 第一个预定义值
timestamp 当前时间

default
mysql> alter table t2 modify id int not null default 8;

unique(key)
mysql> alter table t2 modify id int unique;
mysql> alter table t200 drop index id; //删除

auto_increment 自增
mysql> create table t4(id int unique auto_increment,name char(10));

primary key(key)
每张表里只能有一个主键
不能为空,而且唯一

mysql> create table t7(hostname char(20) primary key,ip char(150));
mysql> create table t9(hostname char(20),ip char(150),primary key(hostname));

联合主键
mysql> create table t9(hostname char(20),ip char(150),primary key(hostname,ip));

mysql> alter table t101 drop primary key; //删除主键

hostname ip
www 192.168.1.8
www 192.168.1.9

index(key)
索引 优化查询速度
创建索引:三种
mysql> create table t100(hostname char(20) primary key,ip char(150),index (ip));

mysql> create table t101(hostname char(20) primary key,ip char(150),index dizhi(ip));

mysql> create index dizhi on t105(ip);

删除索引:
mysql> alter table t101 drop index dizhi; //删除index索引

外键foreign key (key)(了解)
mysql> create table t1(id int,manager char(10) primary key) engine = innodb;
mysql> create table t2(id int,admin char(10),foreign key (admin) references t1 (manager)) engine = innodb ;

带关联删除的外键:
mysql> create table xingzheng(id int,admin char(10),foreign key (admin) references guanli(manager) on delete cascade) engine = innodb;

管理部 销售部 财务部
tom tom

十一,权限机构

1,用户管理

MySQL用户管理
1. 登录和退出MySQL
#mysql -h 192.168.5.240 -P 3306 -u root -p123 mysql -e "select user,host from user"
-h 指定主机名 【默认为localhost】
-P MySQL服务器端口 【默认3306】
-u 指定用户名 【默认root】
-p 指定登录密码 【默认为空密码】
此处mysql为指定登录的数据库
-e 接SQL语句

2. 创建用户
方法一:CREATE USER语句创建
mysql> create user wing;
mysql> create user wing@'localhost' identified by '123456';

方法二: GRANT语句创建
mysql> GRANT ALL ON *.* TO 'user3'@’localhost’ IDENTIFIED BY ‘123456’;

当手动更新权限表的时候需要刷新权限,使用如下命令:
mysql> FLUSH PRIVILEGES;

Example 1: Create an account that uses the default authentication
plugin and the given password. Mark the password expired so that the
user must choose a new one at the first connection to the server:


mysql> CREATE USER 'jeffrey'@'localhost'
IDENTIFIED BY 'new_password' PASSWORD EXPIRE;

Example 2: Create an account that uses the sha256_password
authentication plugin and the given password. Require that a new
password be chosen every 180 days:

mysql> CREATE USER 'jeffrey'@'localhost'
IDENTIFIED WITH sha256_password BY 'new_password'
PASSWORD EXPIRE INTERVAL 180 DAY;

CREATE USER 'jeffrey'@'localhost' IDENTIFIED BY 'mypass';
GRANT ALL ON db1.* TO 'jeffrey'@'localhost';
GRANT SELECT ON db2.invoice TO 'jeffrey'@'localhost';
ALTER USER 'jeffrey'@'localhost' WITH MAX_QUERIES_PER_HOUR 90;

3. 删除用户
方法一:DROP USER语句删除
DROP USER 'user1'@’localhost’;


方法二:DELETE语句删除
mysql> DELETE FROM mysql.user
WHERE user=’user2’ AND host=’localhost’;
mysql> FLUSH PRIVILEGES;


4. 修改用户密码
===root修改自己密码
方法一:
# mysqladmin -uroot -p'123' password 'new_password' //123为旧密码


方法二:
mysql> update mysql.user set authentication_string=password('Qianfeng123!') where user='root' and host='localhost';

方法三:
SET PASSWORD=password(‘new_password’);
上面方法将会在后面的版本remove,使用下面方法
SET PASSWORD='new_password';

==root修改其他用户密码
方法一:
mysql> SET PASSWORD
FOR user3@’localhost’=password(‘new_password’);
上面的方法会在将来remove,使用下面的方法:
mysql> SET PASSWORD FOR user3@’localhost’='new_password';

方法二:
UPDATE mysql.user SET authentication_string=password(‘new_password’)
WHERE user=’user3’ AND host=’localhost’;

===普通用户修改自己密码
mysql> SET password=password('new_password');
mysql> alter user 'wing'@'localhost' identified by 'Qianfeng123!@';


root账户没了或者root密码丢失:
关闭Mysql使用下面方式进入Mysql直接修改表权限

5.1/5.5版本 :
# mysqld_safe --skip-grant-tables --user=mysql &

5.6/5.7版本:
# mysqld --skip-grant-tables --user=mysql &

# mysql -uroot
mysql> UPDATE mysql.user SET authentication_string=password(‘new_password’)
WHERE user=’root’ AND host=’localhost’;
mysql> FLUSH PRIVILEGES;
======================================
密码复杂度限制策略
MySQL5.7默认安装了validate_password插件,若没有安装,则SHOW VARIABLES LIKE 'vali%'则会返回空。

1、查看现有的密码策略
mysql> SHOW VARIABLES LIKE 'validate_password%';
参数解释:
1).validate_password_dictionary_file 指定密码验证的文件路径;
2).validate_password_length 密码最小长度
3).validate_password_mixed_case_count 密码至少要包含的小写字母个数和大写字母个数;
4).validate_password_number_count 密码至少要包含的数字个数
5).validate_password_policy 密码强度检查等级,对应等级为:0/LOW、1/MEDIUM、2/STRONG,默认为1
0/LOW:只检查长度;
1/MEDIUM:检查长度、数字、大小写、特殊字符;
2/STRONG:检查长度、数字、大小写、特殊字符字典文件。
6).validate_password_special_char_count密码至少要包含的特殊字符数

2、创建用户时报错:
mysql> create user 'miner'@'192.168.%' IDENTIFIED BY 'miner123';
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
报错原因:密码强度不够。
解决方法:(该账号为测试账号,所以采用降低密码策略强度)
mysql> set global validate_password_policy=0;
Query OK, 0 rows affected (0.00 sec)
mysql> set global validate_password_length=4;
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW VARIABLES LIKE 'validate_password%';
+--------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------+-------+
| validate_password_dictionary_file | |
| validate_password_length | 4 |
| validate_password_mixed_case_count | 1 |
| validate_password_number_count | 1 |
| validate_password_policy | LOW |
| validate_password_special_char_count | 1 |
+--------------------------------------+-------+
6 rows in set (0.00 sec)
再次创建用户,成功

3.关闭validate_password插件:
在配置文件中加入以下并重启mysqld即可:
[mysqld]
validate_password=off

重启mysqld后通过SHOW PLUGINS可以查到:
+-------------------+----------+-------------------+----------------------+-----+
| validate_password | DISABLED | VALIDATE PASSWORD | validate_password.so | GPL |
+-------------------+----------+-------------------+----------------------+-----+

======================================
用户重命名:
RENAME USER old_name TO new_name;

2,远程登陆

创建账户:
mysql> create user tom@'%' identified by '123';

%不包括127.0.0.1和localhost (-h的时候适用)

远程登陆:
#mysql -u tom -p123 -h 10.18.44.196 -P 3307

3,端口

端口号修改
#vim /etc/my.cnf
[mysqld]
port=3307

注意本地登陆:不需要添加端口号

问题:使用任何一个其他端口都可以登陆!
# mysql -u root -p123 --port=3000
解决:
本地登陆,端口不生效,任何端口都可以,远程登陆必须使用改过的端口

怀疑是mariadb和mysql这里有区别

4,权限管理

权限控制机制
四张表:user db (5.1/5.5版本有host表) tables_priv columns_priv

人 中国人

皇帝 封疆大吏 巡抚 县官

user db tables_priv columns_priv

用户
1.用户认证 是否能登陆数据库 只看user表
2.权限认证 判断这个账户有什么权限

1.用户认证
查看mysql.user表
2.权限认证
以select权限为例:
先看 user表里的select_priv权限
Y 不会接着查看其他的表 拥有查看所有库所有表的权限
N 接着看db表
db
Y 不会接着查看其他的表 拥有查看所有库所有表的权限
N 接着看tables_priv表
tables_priv
table_priv: 如果这个字段的值里包括select 拥有查看这张表所有
字段的权限,不会再接着往下看了
table_priv:如果这个字段的值里不包括select,接着查看下张表
还需要有column_priv字段权限

columns_priv
column_priv: 有select,则只对某一列有select权限
没有则对所有库所有表没有任何权限

db:
mysql> insert into db(host,db,user,Select_priv) values("10.18.44.%",'data','ying','Y');

tables_priv:
mysql> insert into tables_priv(host,db,user,table_name,table_priv) values('10.18.44.%','data','ying','t1','Select,insert');

columns_priv:
mysql> insert into columns_priv(host,db,user,table_name,column_name,column_priv) values('10.18.44.%','data','ying','t1','id','select');

host,db,user,Select_priv
host,db,user,table_name,table_priv
host,db,user,table_name,column_name,column_priv


刷新权限:两种方式
修改表之后需要刷新权限
方式1:
mysql > flush privileges;
方式2:
# mysqladmin flush-privileges -u root -p1

五表联动(5.7取消了host表)
user表
登录认证:用户能否进mysql查看user
权限认证:如果能进,看user表的权限有没有,没有就看下一个db表,db表没有看tables_priv,tables_priv没有就去看columns_priv

当db表的host字段为空的时候才会用到host表
db或者host 任何一个select是N,都是没权限

使用命令授权:grant
也可创建新账户(不过后面的版本会移除这个功能,建议使用create user)
语法格式:
grant 权限列表 on 库名.表名 to '用户名'@'客户端主机' [identified by '密码' with option参数];
==权限列表 all 所有权限(不包括授权权限)
select,update
select(col1), insert(col1,col2) Column level

==数据库.表名 *.* 所有库下的所有表 Global level
web.* web库下的所有表 Database level
web.stu_info web库下的stu_info表 Table level


==客户端主机 % 所有主机
192.168.2.% 192.168.2.0网段的所有主机
192.168.2.168 指定主机
localhost 指定主机

with_option参数(了解)
GRANT OPTION: 授权选项
MAX_QUERIES_PER_HOUR: 定义每小时允许执行的查询数
MAX_UPDATES_PER_HOUR: 定义每小时允许执行的更新数
MAX_CONNECTIONS_PER_HOUR: 定义每小时可以建立的连接数
MAX_USER_CONNECTIONS: 定义单个用户同时可以建立的连接数

mysql> grant select(id),insert(id) on wing.t1 to 'xiaowu'@'172.16.70.%' identified by '123';
mysql> grant select,insert on wing.t1 to 'xiaowu'@'172.16.70.%' identified by '123';
mysql> grant all on wing.t1 to 'xiaowu'@'172.16.70.%' identified by '123';
mysql> grant all on *.* to 'xiaowu'@'172.16.70.%' identified by '123';
mysql> grant all on *.* to 'xiaowu'@'172.16.70.%' ;
mysql> grant all on *.* to 'xiaowu'@'%';

查看权限
看自己的权限:
SHOW GRANTS\G

看别人的权限:
SHOW GRANTS FOR admin1@'%'\G

撤销权限:revoke
语法:
REVOKE 权限列表 ON 数据库名 FROM 用户名@‘客户端主机’

mysql> revoke all on *.* from 'xiaowu'@'%';
mysql> revoke delete on *.* from admin1@’%’; //回收部分权限
REVOKE ALL PRIVILEGES ON *.* FROM admin2@’%’; //回收所有权限
REVOKE ALL PRIVILEGES,GRANT OPTION ON *.* FROM 'admin2'@'%';

5,权限机制


MySQL安全机制 DDL DCL


========================================================
MySQL权限表
MySQL用户管理
MySQL权限管理
SSL加密连接

linux之mysql基础_第44张图片


一、MySQL权限表
mysql.user Global level
用户字段
权限字段
安全字段
资源控制字段
mysql.db Database level
用户字段
权限字段
mysql.tables_priv Table level
mysql.columns_priv Column level


二、MySQL用户管理
1. 登录和退出MySQL
示例:
mysql -h192.168.5.240 -P 3306 -u root -p123 mysql -e ‘select user,host from user’
-h 指定主机名 【默认为localhost】
-P MySQL服务器端口 【默认3306】
-u 指定用户名 【默认root】
-p 指定登录密码 【默认为空密码】
此处mysql为指定登录的数据库
-e 接SQL语句

2. 创建用户
方法一:CREATE USER语句创建
CREATE USER user1@’localhost’ IDENTIFIED BY ‘123456’;

方法二: GRANT语句创建
GRANT ALL ON *.* TO 'user3'@’localhost’ IDENTIFIED BY ‘123456’;
FLUSH PRIVILEGES;


Example 1: Create an account that uses the default authentication
plugin and the given password. Mark the password expired so that the
user must choose a new one at the first connection to the server:

CREATE USER 'jeffrey'@'localhost'
IDENTIFIED BY 'new_password' PASSWORD EXPIRE;

Example 2: Create an account that uses the sha256_password
authentication plugin and the given password. Require that a new
password be chosen every 180 days:

CREATE USER 'jeffrey'@'localhost'
IDENTIFIED WITH sha256_password BY 'new_password'
PASSWORD EXPIRE INTERVAL 180 DAY;

CREATE USER 'jeffrey'@'localhost' IDENTIFIED BY 'mypass';
GRANT ALL ON db1.* TO 'jeffrey'@'localhost';
GRANT SELECT ON db2.invoice TO 'jeffrey'@'localhost';
ALTER USER 'jeffrey'@'localhost' WITH MAX_QUERIES_PER_HOUR 90;

3. 删除用户
方法一:DROP USER语句删除
DROP USER 'user1'@’localhost’;


方法二:DELETE语句删除
DELETE FROM mysql.user
WHERE user=’user2’ AND host=’localhost’;
FLUSH PRIVILEGES;


4. 修改用户密码
===root修改自己密码
方法一:
# mysqladmin -uroot -p'123' password 'new_password' //123为旧密码


方法二:
UPDATE mysql.user SET authentication_string= password(‘new_password’ )
WHERE user=’root’ AND host=’localhost’;
FLUSH PRIVILEGES;

方法三:
SET PASSWORD=password(‘new_password’);


==root修改其他用户密码
方法一:
SET PASSWORD
FOR user3@’localhost’ =password(‘new_password’);

方法二:
UPDATE mysql.user SET authentication_string=password(‘new_password’)
WHERE user=’user3’ AND host=’localhost’;
FLUSH PRIVILEGES;

===普通用户修改自己密码
SET password= password(‘new_password’ );

===丢失root用户密码
# vim /etc/my.cnf
[mysqld]
skip-grant-tables
# service mysqld restart
# mysql -uroot
mysql> UPDATE mysql.user SET authentication_string=password(‘new_password’)
WHERE user=’root’ AND host=’localhost’;
mysql> FLUSH PRIVILEGES;

三、MySQL权限管理
权限应用的顺序:
user (Y|N) ==> db ==> tables_priv ==> columns_priv

语法格式:
grant 权限列表 on 库名.表名 to '用户名'@' 客户端主机' [identified by '密码' with option参数];
==权限列表 all 所有权限(不包括授权权限)
select,update

==数据库.表名 *.* 所有库下的所有表 Global level
web.* web库下的所有表 Database level
web.stu_info web库下的stu_info表 Table level
SELECT (col1), INSERT (col1,col2) ON mydb.mytbl Column level

==客户端主机 % 所有主机
192.168.2.% 192.168.2.0网段的所有主机
192.168.2.168 指定主机
localhost 指定主机

with_option参数
GRANT OPTION: 授权选项
MAX_QUERIES_PER_HOUR: 定义每小时允许执行的查询数
MAX_UPDATES_PER_HOUR: 定义每小时允许执行的更新数
MAX_CONNECTIONS_PER_HOUR: 定义每小时可以建立的连接数
MAX_USER_CONNECTIONS: 定义单个用户同时可以建立的连接数

Grant示例:
GRANT ALL ON *.* TO admin1@'%' IDENTIFIED BY '(TianYunYang584131420)';

GRANT ALL ON *.* TO admin2@'%' IDENTIFIED BY '(TianYunYang584131420)' WITH GRANT OPTION;

GRANT ALL ON bbs.* TO admin3@'%' IDENTIFIED BY '(TianYunYang584131420)';
GRANT ALL ON bbs.* TO admin3@'192.168.122.220' IDENTIFIED BY '(TianYunYang584131420)';

GRANT ALL ON bbs.user TO admin4@'%' IDENTIFIED BY '(TianYunYang584131420)';

GRANT SELECT(col1),INSERT(col2,col3) ON bbs.user TO admin5@'%' IDENTIFIED BY '(TianYunYang584131420)';

回收权限REVOKE
查看权限
SHOW GRANTS\G
SHOW GRANTS FOR admin1@'%'\G

回收权限REVOKE
语法:
REVOKE 权限列表 ON 数据库名 FROM 用户名@‘客户端主机’

示例:
REVOKE DELETE ON *.* FROM admin1@’%’; //回收部分权限
REVOKE ALL PRIVILEGES ON *.* FROM admin2@’%’; //回收所有权限
REVOKE ALL PRIVILEGES, GRANT OPTION ON *.* FROM 'admin2'@'%';

删除用户:
5.6 revoke all privilege drop user
5.7 drop user

十二,日志管理

1,日志的概述

MySQL日志管理
1.开启binlog日志
2.读取binlog日志
3.利用binlog日志恢复数据
linux之mysql基础_第45张图片

作用
配置文件
日志文件
启动
测试

error log 错误日志 排错 /var/log/mysqld.log【默认开启】
bin log 二进制日志 备份 增量备份 DDL DML DCL
Relay log 中继日志 复制 接收 replication master
slow log 慢查询日志 调优 查询时间超过指定值

Error Log
log-error=/var/log/mysqld.log

Binary Log(用于备份恢复数据)
产生binlog日志:
log-bin=/var/log/mysql-bin/slave2
server-id=2 //mysql5.7要写

# mkdir /var/lib/mysql-bin
# chown mysql.mysql /var/lib/mysql-bin/
# systemctl restart mysqld

注:
1. 重启mysqld 会截断旧日志产生新的日志
2. 刷新日志会截断旧日志产生新的日志
mysql> flush logs
3. 删除所有binlog(禁用)
mysql> reset master
4. 删除部分日志
mysql> PURGE BINARY LOGS TO 'mysql-bin.010';
mysql> PURGE BINARY LOGS BEFORE '2016-04-02 22:46:26';
5. 暂停binlog日志功能(仅对当前会话生效)
mysql> SET SQL_LOG_BIN=0;
mysql> SET SQL_LOG_BIN=1;

读取binlog日志
# mysqlbinlog mysql.000002

按datetime读取:
# mysqlbinlog mysql.000002 --start-datetime="2018-12-05 10:02:56"
# mysqlbinlog mysql.000002 --stop-datetime="2018-12-05 11:02:54"
# mysqlbinlog mysql.000002 --start-datetime="2018-12-05 10:02:56" --stop-datetime="2018-12-05 11:02:54"

按position读取:
# mysqlbinlog mysql.000002 --start-position=260
# mysqlbinlog mysql.000002 --stop-position=260
# mysqlbinlog mysql.000002 --start-position=260 --stop-position=930

Slow Query Log(优化)

2,日志管理

MySQL日志管理

/etc/my.cnf
=====================================
linux之mysql基础_第46张图片

error log 错误日志 排错 /var/log/mysqld.log【默认开启】
bin log 二进制日志 备份 增量备份 DDL DML DCL
Relay log 中继日志 复制 接收 replication master
slow log 慢查询日志 调优 查询时间超过指定值

Error Log
log-error=/var/log/mysqld.log

Binary Log
log-bin=/var/log/mysql-bin/slave2
server-id=2

# mkdir /var/lib/mysql-bin
# chown mysql.mysql /var/lib/mysql-bin/
# systemctl restart mysqld

注:
1. 重启mysqld 会截断
2. flush logs 会截断
3. reset master 删除所有binlog rm -rf /
4. 删除部分
PURGE BINARY LOGS TO 'mysql-bin.010';
PURGE BINARY LOGS BEFORE '2016-04-02 22:46:26';

5. 暂停 仅当前会话
SET SQL_LOG_BIN=0;
SET SQL_LOG_BIN=1;

6. 截取binlog
all:
# mysqlbinlog mysql.000002

datetime:
# mysqlbinlog mysql.000002 --start-datetime="2018-12-05 10:02:56"
# mysqlbinlog mysql.000002 --stop-datetime="2018-12-05 11:02:54"
# mysqlbinlog mysql.000002 --start-datetime="2018-12-05 10:02:56" --stop-datetime="2018-12-05 11:02:54"

position:
# mysqlbinlog mysql.000002 --start-position=260
# mysqlbinlog mysql.000002 --stop-position=260
# mysqlbinlog mysql.000002 --start-position=260 --stop-position=930

Slow Query Log
slow_query_log=1
slow_query_log_file=/var/log/mysql-slow/slow.log
long_query_time=3

# mkdir /var/log/mysql-slow/
# chown mysql.mysql /var/log/mysql-slow/
# systemctl restart mysqld

查看慢查询日志
测试:BENCHMARK(count,expr)
SELECT BENCHMARK(50000000,2*3);

十三,备份恢复

1,概述

MySQL数据备份

所有备份数据都应放在非数据库本地,而且建议有多份副本。
测试环境中做日常恢复演练,恢复较备份更为重要。
============================================
备份: 能够防止由于机械故障以及人为误操作带来的数据丢失,例如将数据库文件保存在了其它地方。
冗余: 数据有多份冗余,但不等备份,只能防止机械故障还来的数据丢失,例如主备模式、数据库集群。

备份过程中必须考虑因素:
1. 数据的一致性
2. 服务的可用性

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

逻辑备份: 备份的是建表、建库、插入等操作所执行SQL语句(DDL DML DCL),适用于中小型数据库,效率相对较低。
mysqldump
binlog

mydumper
phpmyadmin(自己部署试一试)

物理备份: 直接复制数据库文件,适用于大型数据库环境,不受存储引擎的限制,但不能恢复到不同的MySQL版本。
tar,cp

mysqlhotcopy 只能用于备份MyISAM。
xtrabackup
inbackup
lvm snapshot

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

ku 10
1个月 作一次完整备份 fullback

binlog10 xinlog11 xinlog12

完全备份
增量备份
差异备份


23号24点 完整备份
24号24点 做24号这一天的备份
25号24点 做25号这一天的备份

inode
linux之mysql基础_第47张图片
完整备份:
每次都将所有数据(不管自第一次备份以来有没有修改过),进行一次完整的复制,备份后会清除文件的存档属性,方便日后增量备份或者差异备份进行版本比较。
  
特点:占用空间大,备份速度慢,但恢复时一次恢复到位,相对恢复速度快。
  
增量备份:
在第一次完整备份之后,第二次开始每次都将添加了存档属性的文件进行备份,并且在备份之后再把这些存档属性清除。为什么要清除存档属性呢?这就是为了下一次备份的时候判断是否有文件变化,因为用户在每次备份以后修改这些被清除存档属性的文件,存档属性就会自动加上,相当于用户告诉系统,这些文件有变化,你下一次就备份这些文件,其他没有存档属性的就不需要备份,这就是增量备份的工作机制。
(相当于机器人把地板打扫干净了,你踩过,就会有脚印(增加标记),下次机器人就把脚
印记录下来,并且把脚印打扫干净(清除标记),始终保持地板干净。机器人每次记录并打
扫的脚印就相当于每次增量备份的内容)
  特点:因每次仅备份自上一次备份(注意是上一次,不是第一次)以来有变化的文件,所
以备份体积小,备份速度快,但是恢复的时候,需要按备份时间顺序,逐个备份版本进行恢
复,恢复时间长。
  
差异备份:
在第一次完整备份之后,第二次开始每次都将所有文件与第一次完整备份的文件做比较,把自第一次完整备份以来所有修改过的文件进行备份,且以后每次备份都是和第一次完整备份进行比较(注意是第一次,不是上一次),备份自第一次完整备份以来所有的修改过的文件。因此,差异备份在备份完毕之后不需要清除文件的存档属性,因为这些文件和下一次备份没有什么关系,它仅仅和第一次完整备份的数据进行比较(第一次完整备份之后是清除存档属性的)。
(相当于第一次机器人把地板打扫干净了,你踩过,就会有脚印,机器人就把脚印记录下
来,但不打扫,下次你又有踩脏的,机器人就把你这几次所有踩脏的地方都记录下来,始终
不打扫,每次都这样。机器人每次记录的内容就相当于差异备份的内容)
  
特点:占用空间比增量备份大,比完整备份小,恢复时仅需要恢复第一个完整版本和最后
一次的差异版本,恢复速度介于完整备份和增量备份之间。
  
简单的讲,完整备份就是不管三七二十一,每次都把指定的备份目录完整的复制一遍,不管目录下的文件有没有变化;增量备份就是每次将之前(第一次、第二次、直到前一次)做过备份之后有变化的文件进行备份;差异备份就是每次都将第一次完整备份以来有变化的文件进行备份。
 
• 举例:

  假设指定备份目录周一包含A、B、C三个文件。周一的时候,做了完整备份。周二新增了D文件,同时A文件发生变化,变成A1文件;周三新增了E文件,同时A文件变成了A2,B文件变成B1;周四新增了F文件,A2变成了A3,D变成了D1,同时删掉了C文件。
  
  不同备份方式下的备份情况(假设每天做一次备份):
  
完整备份:周一,备份ABC三个文件;周二,备份A1、B、C、D四个文件;周三,备份A2、B1、C、D、E五个文件;
  周四,备份A3、B1、D1、E、F五个文件。
  
  增量备份:周一,备份ABC三个文件,完整备份;周二,备份与周一相比有变化的文件,即备份A1和D两个文件;周三,备份与之前所有版本相比有变化的文件,即备份A2,B1,E三个文件;周四,备份与之前所有版本相比有变化的文件,即备份A3,D1,F三个文件并删除C。
  
  差异备份:周一,备份ABC三个文件,完整备份;周二,备份与周一相比有变化的文件,即备份A1和D两个文件;周三,备份与周一相比有变化的文件,即备份A2、B1、D、E四个文件;周四,备份与周一相比有变化的文件,即备份A3、B1、D1、E、F五个文件并删除C

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
热备份
数据库启动同时给客户端提供服务的情况下
冷备份
数据库要关掉或者不能给客户端提供服务

2,数据导入导出

表的导出和导入只备份表内记录,不会备份表结构,需要通过mysqldump备份表结构,恢复时先恢复表结构,再导入数据。

允许发生导入导出文件操作的目录限制:
mysql> show variables like "secure_file_priv";
+------------------+-----------------------+
| Variable_name | Value |
+------------------+-----------------------+
| secure_file_priv | /var/lib/mysql-files/ |
+------------------+-----------------------+

修改安全文件目录:
1.修改配置文件:
#vim /etc/my.cnf 在[mysqld]里追加
secure_file_priv=/sql

2.重启mysqld服务
3.修改权限:
#chown mysql.mysql /sql

导出数据
mysql> select * from t3 into outfile '/tmp/db5.t3.bak';
mysql> select * from t3 into outfile '/tmp/db5.t3.bak1' fields terminated by ',' lines terminated by '\n';

导入数据
mysql> load data infile '/tmp/db5.t3.bak' into table t4;
mysql> load data infile '/tmp/db5.t3.bak' into table t4 fields terminated by ',' lines terminated by '\n';

mysql 命令导出文本文件
# mysql -u root -p123 -e 'select * from student1.school' > /tmp/student1.txt
# mysql -u root -p123 --xml -e 'select * from student1.school' > /tmp/student1.xml
# mysql -u root -p123 --html -e 'select * from student1.school' > /tmp/student1.html

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
完整备份恢复过程:
备份:
1.备份表结构:用mysqldump备份表结构
# mysqldump -d -u root -p345 data t1 > t1.frm
2.用导出的方法备份数据:

恢复:
1.恢复表结构:
# mysql -u root -p345 -D data < t1.frm
2.最后用load data恢复数据

表的导入导出(补充)

SELECT... INTO OUTFILE 导出文本文件
示例:
mysql> SELECT * FROM school.student1 INTO OUTFILE '/backup/student1.txt'
FIELDS TERMINATED BY ',' //定义字段分隔符
OPTIONALLY ENCLOSED BY '”' //定义字符串使用什么符号括起来
LINES TERMINATED BY '\n' ; //定义换行符

mysql 命令导出文本文件
示例:
# mysql -u root -p123 -e 'select * from student1.school' > /tmp/student1.txt
# mysql -u root -p123 --xml -e 'select * from student1.school' > /tmp/student1.xml
# mysql -u root -p123 --html -e 'select * from student1.school' > /tmp/student1.html

LOAD DATA INFILE 导入文本文件
mysql> DELETE FROM student1;
mysql> LOAD DATA INFILE '/tmp/student1.txt'
INTO TABLE school.student1
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '”'
LINES TERMINATED BY '\n';

表的导出和导入只备份表记录,不会备分表结构。因此需要通过mysqldump备份表结构,恢复时先恢复表结构,再导入数据。

3,tar数据备份(物理)

注:备份期间,服务不可用
============================================================

备份的过程:【完全物理备份】
1. 停止数据库
2. tar备份数据
3. 启动数据库
# systemctl stop mysqld
# mkdir /backup
# tar -cf /backup/`date +%F`-mysql-all.tar /var/lib/mysql
注:备份文件应该复制其它服务器或存储上

还原的过程:
1. 停止数据库
2. 清理环境
3. 导入备份数据
4. 启动数据库
5. binlog恢复
# systemctl stop mysqld
# rm -rf /var/lib/mysql/*
# tar -xf /backup/2016-12-07-mysql-all.tar -C /
# systemctl start mysqld

4,lvm快照(物理)

Lvm快照实现物理备份 + binlog

lvm快照
/dev/vg0/lv0
mount /dev/vg0/lv0 /var/lib/mysql/

停止客户端的写功能:
mysql> flush tables with read lock;

做快照备份数据(锁写):
#lvcreate -s -L 1G /dev/vg0/lv0 -n lv0.snap

开启客户端的写功能(解锁)
mysql> unlock tables;

#mount lv0.snap /mnt
#tar cvzf /backup/beifen.tar.gz /mnt/


数据一致,服务可用
注:MySQL数据lv 和 将要创建的snapshot 必须在同一VG,因此VG必须要有一定的剩于空间
============================================================

优点:
几乎是热备 (创建快照前把表上锁,创建完后立即释放)
支持所有存储引擎
备份速度快
无需使用昂贵的商业软件(它是操作系统级别的)
缺点:
可能需要跨部门协调(使用操作系统级别的命令,DBA一般没权限)
无法预计服务停止时间
数据如果分布在多个卷上比较麻烦(针对存储级别而言)

操作流程:
1、flush table with read lock;
2、create snapshot
3、show master status; show slave status; [可选]
4、unlock tables;
5、Copy files from the snapshot
6、Unmount the snapshot.
  7、Remove snapshot

正常安装MySQL:
1. 安装系统
2. 准备LVM,例如 /dev/vg_tianyun/lv-mysql,mount /var/lib/mysql
3. 安装MySQL,默认datadir=/var/lib/mysql

============================================================
MySQL运行一段时间,数据并没有存储LVM:将现在的数据迁移到LVM
1. 准备lvm及文件系统
# lvcreate -n lv-mysql -L 2G datavg
# mkfs.xfs /dev/datavg/lv-mysql

2. 将数据迁移到LVM
# systemctl stop mysqld
# mount /dev/datavg/lv-mysql /mnt/ //临时挂载点
# cp -a /var/lib/mysql/* /mnt //将MySQL原数据镜像到临时挂载点

# umount /mnt/
# vim /etc/fstab //加入fstab开机挂载
/dev/datavg/lv-mysql /var/lib/mysql xfs defaults 0 0

# mount -a
# chown -R mysql.mysql /var/lib/mysql
# systemctl start mysqld
============================================================
LVM快照备份流程:
1. 加全局读锁
mysql> flush tables with read lock;

2. 创建快照
# lvcreate -L 500M -s -n lv-mysql-snap /dev/datavg/lv-mysql
# mysql -p'Qianfeng123!@' -e 'show master status' > /backup/`date +%F`_position.txt

3. 释放锁
mysql> unlock tables;

1-3必须同一会话中完成
# echo "FLUSH TABLES WITH READ LOCK; SYSTEM lvcreate -L 500M -s -n lv-mysql-snap /dev/datavg/lv-mysql; UNLOCK TABLES;" | mysql -p'Qianfeng123!@'

# echo "FLUSH TABLES WITH READ LOCK; SYSTEM lvcreate -L 500M -s -n lv-mysql-snap /dev/datavg/lv-mysql; " | mysql -p'Qianfeng123!@'

4. 从快照中备份
# mount -o ro /dev/datavg/lv-mysql-snap /mnt/ //xfs -o ro,nouuid
# cd /mnt/
# tar -cf /backup/`date +%F`-mysql-all.tar ./*

5. 移除快照
# cd; umount /mnt/
# lvremove -f /dev/vg_tianyun/lv-mysql-snap

LVM快照恢复流程:
1. 停止数据库
2. 清理环境
3. 导入数据
4. 修改权限
5. 启动数据库
6. binlog恢复
[root@slave2 ~]# tar -xf /backup/2016-12-07-mysql-all.tar -C /var/lib/mysql/
[root@slave2 ~]# systemctl start mysqld

Tar解压的注意事项:备份的时候要到当前目录下,不然会压缩目录结构
tar -tf 2016-12-07-mysql-all.tar |less

脚本 + Cron
#!/bin/bash
#LVM backmysql...
back_dir=/backup/`date +%F`

[ -d $back_dir ] || mkdir -p $back_dir

echo "FLUSH TABLES WITH READ LOCK; SYSTEM lvcreate -L 500M -s -n lv-mysql-snap /dev/datavg/lv-mysql; \
UNLOCK TABLES;" | mysql -p'Qianfeng123!@'

mount -o ro,nouuid /dev/datavg/lv-mysql-snap /mnt/

rsync -a /mnt/ $back_dir

if [ $? -eq 0 ];then
umount /mnt/
lvremove -f /dev/datavg/lv-mysql-snap
fi

5,binlog日志备份恢复 (逻辑)(重点掌握)

binlog日志方法备份恢复数据
记录每一个操作
默认存储位置 :
rpm : /var/lib/mysql
编译: 安装目录的var下

产生binlog日志
一.在启动服务的时候启用日志(临时的)
# mysqld_safe --log-bin --server-id=1 --user=mysql &

查看binlog日志
方法1:
# mysqlbinlog --base64-output=decode-rows -v wing-bin.000001
时间点 : 141126 14:04:49
位置点 : at 106

方法2:
mysql> show binlog events; //默认查看第一个日志
mysql> show binlog events in 'mylog.000001'; //查看指定的日志


二.配置文件(永久修改)
#vim /etc/my.cnf
[mysqld]
log-bin=mylog
server-id=1 //做AB复制的时候用

#/etc/init.d/mysqld restart

根据binlog恢复数据
根据时间点恢复数据
# mysqlbinlog --start-datetime='2014-11-25 11:56:54' --stop-datetime='2014-11-25 11:57:41' wing-bin.000001 | mysql -u root -p1

根据位置点恢复数据
# mysqlbinlog --start-position 106 --stop-position 527 wing-bin.000001 | mysql -u root -p1

注:可以同时读取多个日志文件

刷新bin-log日志
:
#mysqladmin flush-logs //方式1
# mysql -u root -p123 -e "flush logs" //方式2
实验:用计划任务实现Mysql数据库一周的增量备份
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
去除binlog加密:
transaction_isolation=repeatable-read
binlog_format=mixed

6,xtrabackup(物理)

1,安装软件

percona-xtrabackup 物理备份 + binlog
是开源免费的支持MySQL 数据库热备份的软件,它能对InnoDB和XtraDB存储引擎的数据库非阻塞地备份。它不暂停服务创建Innodb热备份
为mysql做增量备份;在mysql服务器之间做在线表迁移;使创建replication更加容易;备份mysql而不增加服务器的负载。
percona是一家老牌的mysql技术咨询公司。它不仅提供mysql的技术支持、培训、咨询,还发布了mysql的分支版本--percona Server。并围绕percona Server还发布了一系列的mysql工具。
=================================================================================
linux之mysql基础_第48张图片

安装xtrabackup
# wget http://www.percona.com/downloads/percona-release/redhat/0.1-4/percona-release-0.1-4.noarch.rpm
# yum -y install percona-release-0.1-4.noarch.rpm
# yum -y install percona-xtrabackup-24.x86_64

注意:如果依赖包perl-DBD-MySQL安装不上,wing测试需先把percona源拿掉用centos的源单独安装,然后再安装percona-xtrabackup-24.x86_64
linux之mysql基础_第49张图片

2,完整备份

完全备份流程

创建备份目录:
[root@wing full]# mkdir /xtrabackup/full

备份:
[root@wing full]# innobackupex --user=root --password='Qianfeng123!@' /xtrabackup/full

查看备份之后的文件:
[root@wing full]# ls /xtrabackup/full/
2018-01-21_18-19-25

[root@wing full]# cd 2018-01-21_18-19-25/

[root@wing 2018-01-21_18-19-25]# ls
backup-my.cnf ib_buffer_pool mysql sys xtrabackup_info
db1 ibdata1 performance_schema xtrabackup_checkpoints xtrabackup_logfile

完全备份恢复流程
1. 停止数据库
2. 清理环境
3. 重演回滚--> 恢复数据
4. 修改权限
5. 启动数据库

关闭数据库
# systemctl stop mysqld
# rm -rf /var/lib/mysql/*
# rm -rf /var/log/mysqld.log
# rm -rf /var/log/mysql-slow/slow.log

恢复之前的验证恢复:
# innobackupex --apply-log /xtrabackup/full/2018-01-21_18-19-25/

确认数据库目录
恢复之前需要确认配置文件内有数据库目录指定,不然xtrabackup不知道恢复到哪里
# cat /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql

恢复数据
[root@wing mysql]# innobackupex --copy-back /xtrabackup/full/2018-01-21_18-19-25/

修改权限
[root@wing mysql]# chown mysql.mysql /var/lib/mysql -R

启动数据库:
[root@wing mysql]# systemctl start mysqld

3,增量备份

增量备份流程
原理:每次备份上一次备份到现在产生的新数据

准备测试库和表:
mysql> create database testdb;
Query OK, 1 row affected (0.00 sec)

mysql> use testdb;
Database changed
mysql> create table test(id int);
Query OK, 0 rows affected (0.00 sec)

mysql> insert into test set id=1;
Query OK, 1 row affected (0.00 sec)

1、完整备份:周一
# innobackupex --user=root --password='(TianYunYang123)' /xtrabackup

2、增量备份:周二 —— 周六
insert into testdb.test values(2);
linux之mysql基础_第50张图片

insert into testdb.test values(3);
linux之mysql基础_第51张图片

insert into testdb.test values(4);
linux之mysql基础_第52张图片


增量备份恢复流程
1. 停止数据库
2. 清理环境
3. 依次重演回滚redo log--> 恢复数据
4. 修改权限
5. 启动数据库
6. binlog恢复
linux之mysql基础_第53张图片

# systemctl stop mysqld
# rm -rf /var/lib/mysql/*

依次重演回滚redo log
周一:full
# innobackupex --apply-log --redo-only /xtrabackup/2016-12-08_10-13-42/

周二 --- 周四
# innobackupex --apply-log --redo-only /xtrabackup/2016-12-08_10-13-42/ --incremental-dir=/xtrabackup/2016-12-09_10-32-00
# innobackupex --apply-log --redo-only /xtrabackup/2016-12-08_10-13-42/ --incremental-dir=/xtrabackup/2016-12-10_10-31-57
# innobackupex --apply-log --redo-only /xtrabackup/2016-12-08_10-13-42/ --incremental-dir=/xtrabackup/2016-12-11_10-31-29

恢复数据
cp
rsync
innobackupex copy-back (datadir)
修改权限

# innobackupex --copy-back /xtrabackup/2016-12-08_10-13-42/
# chown -R mysql.mysql /var/lib/mysql
# systemctl start mysqld
linux之mysql基础_第54张图片
linux之mysql基础_第55张图片

4,差异备份

差异备份流程
1、完整备份:周一
create database testdb;
use testdb;
create table test2(id int);
insert into test values(1);
select * from test;

# innobackupex --user=root --password=888 /xtrabackup

2、差异备份:周二 —— 周六
insert into testdb.test2 values(2);
# innobackupex --user=root --password=888 --incremental /xtrabackup --incremental-basedir=/xtrabackup/完全备份目录(周一)

insert into testdb.test2 values(3);
# innobackupex --user=root --password=888 --incremental /xtrabackup --incremental-basedir=/xtrabackup/完全备份目录(周一)

insert into testdb.test values(4);
# innobackupex --user=root --password=888 --incremental /xtrabackup --incremental-basedir=/xtrabackup/完全备份目录(周一)

差异备份恢复流程
1. 停止数据库
2. 清理环境
3. 重演回滚redo log(周一,某次差异)--> 恢复数据
4. 修改权限
5. 启动数据库
6. binlog恢复

1.恢复全量的redo log
# innobackupex --apply-log --redo-only /xtrabackup/完全备份目录(周一)

2.恢复差异的redo log
# innobackupex --apply-log --redo-only /xtrabackup/完全备份目录(周一)--incremental-dir=/xtrabacku/某个差异备份

3.复制数据文件(cp,rsync)修改权限

4.启动mysqld

5.通过binlog增量恢复

5,xtrabackup(物理)各种备份的整个流程的过程

percona-xtrabackup 物理备份 + binlog

它是开源免费的支持MySQL 数据库热备份的软件,它能对InnoDB和XtraDB存储引擎的数据库非阻塞地备份。它不暂停服务创建Innodb热备份
为mysql做增量备份;在mysql服务器之间做在线表迁移;使创建replication更加容易;备份mysql而不增加服务器的负载。
percona是一家老牌的mysql技术咨询公司。它不仅提供mysql的技术支持、培训、咨询,还发布了mysql的分支版本--percona Server。并围绕percona Server还发布了一系列的mysql工具。
=================================================================================
linux之mysql基础_第56张图片

安装xtrabackup


[ wget http://www.percona.com/downloads/percona-release/redhat/0.1-3/percona-release-0.1-3.noarch.rpm
# yum -y install percona-release-0.1-3.noarch.rpm
# yum -y install percona-xtrabackup-24.x86_64

linux之mysql基础_第57张图片


==案例1 完全备份流程==

linux之mysql基础_第58张图片
linux之mysql基础_第59张图片

==案例1 完全备份恢复流程==


1. 停止数据库
2. 清理环境
3. 重演回滚--> 恢复数据
4. 修改权限
5. 启动数据库

# systemctl stop mysqld
# rm -rf /var/lib/mysql/*
# rm -rf /var/log/mysqld.log
# rm -rf /var/log/mysql-slow/slow.log
linux之mysql基础_第60张图片
linux之mysql基础_第61张图片
linux之mysql基础_第62张图片
linux之mysql基础_第63张图片
linux之mysql基础_第64张图片
linux之mysql基础_第65张图片

==案例2 增量备份流程==

linux之mysql基础_第66张图片

1、完整备份:周一
# innobackupex --user=root --password='(TianYunYang123)' /xtrabackup

2、增量备份:周二 —— 周六
insert into testdb.test values(2);
linux之mysql基础_第67张图片

insert into testdb.test values(3);
linux之mysql基础_第68张图片

insert into testdb.test values(4);
linux之mysql基础_第69张图片

==案例2 增量备份流程==

1. 停止数据库
2. 清理环境
3. 依次重演回滚redo log--> 恢复数据
4. 修改权限
5. 启动数据库
6. binlog恢复
linux之mysql基础_第70张图片


# systemctl stop mysqld
# rm -rf /var/lib/mysql/*

依次重演回滚redo log
周一:full
# innobackupex --apply-log --redo-only /xtrabackup/ 2016-12-08_10-13-42/

周二 --- 周四
# innobackupex --apply-log --redo-only /xtrabackup/ 2016-12-08_10-13-42/ --incremental-dir=/xtrabackup/ 2016-12-09_10-32-00
# innobackupex --apply-log --redo-only /xtrabackup/ 2016-12-08_10-13-42/ --incremental-dir=/xtrabackup/ 2016-12-10_10-31-57
# innobackupex --apply-log --redo-only /xtrabackup/ 2016-12-08_10-13-42/ --incremental-dir=/xtrabackup/ 2016-12-11_10-31-29

恢复数据
cp
rsync
innobackupex copy-back (datadir)
修改权限

# innobackupex --copy-back /xtrabackup/ 2016-12-08_10-13-42/
# chown -R mysql.mysql /var/lib/mysql
# systemctl start mysqld
linux之mysql基础_第71张图片
linux之mysql基础_第72张图片

==案例3 差异备份流程==

1、完整备份:周一
create database testdb;
use testdb;
create table test2(id int);
insert into test values(1);
select * from test;

[root@tianyun ~]# innobackupex --user=root --password=888 /xtrabackup

2、差异备份:周二 —— 周六
insert into testdb.test2 values(2);
[root@tianyun ~]# innobackupex --user=root --password=888 --incremental /xtrabackup --incremental-basedir=/xtrabackup/完全备份目录(周一)

insert into testdb.test2 values(3);
[root@tianyun ~]# innobackupex --user=root --password=888 --incremental /xtrabackup --incremental-basedir=/xtrabackup/完全备份目录(周一)

insert into testdb.test values(4);
[root@tianyun ~]# innobackupex --user=root --password=888 --incremental /xtrabackup --incremental-basedir=/xtrabackup/完全备份目录(周一)

==案例3 差异备份恢复流程==

1. 停止数据库
2. 清理环境
3. 重演回滚redo log(周一,某次差异)--> 恢复数据
4. 修改权限
5. 启动数据库
6. binlog恢复

1.恢复全量的redo log
[root@tianyun ~]# innobackupex --apply-log --redo-only /xtrabackup/完全备份目录(周一)

2.恢复差异的redo log
[root@tianyun ~]# innobackupex --apply-log --redo-only /xtrabackup/完全备份目录(周一)--incremental-dir= /xtrabacku/某个差异备份

3.复制数据文件(cp,rsync)修改权限

4.启动mysqld

5.通过binlog增量恢复

7,mysqldump(逻辑)

mysqldump实现逻辑完全备份 + binlog
数据一致,服务可用
备份表
# mysqldump -u root -p1 db1 t1 > /db1.t1.bak
# mysqldump -u root -p1 db1 t1 t2 > /db1.t1_t2.bak

备份一个库
# mysqldump -u root -p1 db1 > /db1.bak

备份多个库
#mysqldump -u root -p1 -B db1 db2 db3 > /db123.bak

备份所有的库
#mysqldump -u root -p1 -A > /alldb.bak

恢复数据库
为保证数据一致性,应在恢复数据之前停止数据库对外的服务,停止binlog日志
因为binlog使用binlog日志恢复数据时也会产生binlog日志
mysql> set sql_log_bin=0

mysql> source db1.t1.bak
或者
#mysql -u root -p1 -D db1 < db1.t1.bak

常用备份选项:
-A, --all-databases

备份所有库

-B, --databases bbs test mysql
备份多个数据库

-F, --flush-logs             
备份之前刷新binlog日志

--single-transaction    
该选项在导出数据之前提交一个 BEGIN SQL语句,BEGIN 不会阻塞任何应用程序且能保证导出时数据库的一致性状态。它只适用于事务表,例如 InnoDB

--master-data=1|2       
该选项将会记录备份时binlog的日志位置与文件名并追加到文件中,内容如下:
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000016',
MASTER_LOG_POS=107;
表示备份的是日志文件16里位置为107之前的数据

这个参数在建立slave数据库的时候会用到,当这个参数的值为1的时候,mysqldump出来的文件就会包括CHANGE MASTER TO这个语句CHANGE MASTER TO后面紧接着就是file和position的记录,file和position记录的位置就是slave从master端复制文件的起始位置。默认情况下这个值是1,当这个值是2的时候,chang master to也是会写到dump文件里面去的,但是不会有上面那个作用了

--default-character-set
指定导出数据时采用何种字符集,如果数据表不是采用默认的 latin1 字符集的话,那么导出时必须指定该选项,否则再次导入数据后将产生乱码问题。

--quick,-q         
该选项在导出大表时很有用,它强制 mysqldump 从服务器查询取得记录直接输出而不是取得所有记录后将它们缓存到内存中。

--no-data,-d    
不导出任何数据,只导出数据库表结构。

-x, --lock-all-tables        
在开始导出之前,提交请求锁定所有数据库中的所有表,以保证数据的一致性。这是一个全局读锁,并且自动关闭

--lock-tables         
它和 --lock-all-tables 类似,不过是锁定当前导出的数据表,而不是一下子锁定全部库下的表。本选项只适用于 MyISAM 表

-R, --routines        备份存储过程和存储函数
--triggers              备份触发器

mysqldump导出数据对表的控制: 主要有两种控制
一种是导出的全过程都加锁 lock-all-tables, 另一种则是不加。前者会在导出开始时执行 FLUSH TABLES WITH READ LOCK; 也就是加全局读锁,会阻塞其它写操作,以保证导出是一致性的;因此只有在导出测试数据时或导出时没有业务连接操作时可不加 lock-all-tables .
至于说一致性导出的另一种方式 single-transaction, 则是有适用范围的,见下边。

single-transaction 选项和 lock-all-tables 选项是二选一的,前者是在导出开始时设置事务隔离状态并使用一致性快照开始事务,而后马上unlock tables,然后执行导出,导出过程不影响其它事务或业务连接,但只支持类似innodb多版本特性的引擎,因为必须保证即使导出期间其它操作(事务点t2)改变了数据,而导出时仍能取出导出开始的事务点t1时的数据。而lock-all-tables则一开始就 FLUSH TABLES WITH READ LOCK; 加全局读锁,直到dump完毕。

master_data 选项开启时默认会打开lock-all-tables,因此同时实现了两个功能,一个是加锁,一个是取得log信息。
master_data取1和取2的区别,只是后者把 change master ... 命令注释起来了,没多大实际区别;

当master_data和 single_transaction 同时使用时,先加全局读锁,然后设置事务一致性和使用一致性快照开始事务,然后马上就取消锁,然后执行导出

总结:
1.如果需要binlog信息则使用 master_data;
2.如果不想阻塞同时表是innodb引擎可使用 single_transaction 取得一致性快照(取出的数据是导出开始时刻事务点的状态)
3.如果表不支持多版本特性,则只能使用 lock-all-tables 阻塞方式来保证一致性的导出数据。
4.如果能保证导出期间没有任何写操作,可不加或关闭 lock-all-tables

案例模拟:完全 + 增量 binlog

备份之前:


school.t1
1
2

备份流程:

linux之mysql基础_第73张图片
linux之mysql基础_第74张图片

业务正常推进。

恢复流程:

1. 停止数据库
2. 清理环境
3. 启动数据库 【初始密码 /var/log/mysqld.log】
4. 重置密码 【新密码 】

5. mysql恢复数据 【新密码 】
6. 刷新授权 【备份时密码 】

[root@slave2 ~]# systemctl stop mysqld
[root@slave2 ~]# rm -rf /var/lib/mysql/*
[root@slave2 ~]# rm -rf /var/log/mysql-bin/*
[root@slave2 ~]# rm -rf /var/log/mysql-slow/*
[root@slave2 ~]# rm -rf /var/log/mysqld.log

[root@slave2 ~]# systemctl start mysqld
[root@slave2 ~]# grep 'password' /var/log/mysqld.log

[root@slave2 ~]# mysql -p'(TianYunYang131420)' < /backup/2016-12-08-04-mysql-all.sql

[root@slave2 ~]# mysql -p'(TianYunYang131420)' -e 'flush privileges'

linux之mysql基础_第75张图片

建议在逻辑备份恢复时,暂停BINLOG

linux之mysql基础_第76张图片

案例模拟1:完全 + 增量binlog

备份之前:

school.t1
1
2

备份流程:

mysqldump

模拟操作:

DQL DDL DCL DML
school.t1
1
2
3
4

恢复流程:

恢复完全备份
恢复增量备份binlog
恢复配置文件
创建所需的目录及权限

linux之mysql基础_第77张图片


案例模拟2:误删除表


insert
drop
create


[root@slave2 mysql-bin]# mysqlbinlog --start-position=154 slave2.000004 slave2.000005

[root@slave2 mysql-bin]# mysqlbinlog --stop-position=768 slave2.000006
[root@slave2 mysql-bin]# mysqlbinlog --start-position=1045 slave2.000006

linux之mysql基础_第78张图片

备份脚本

#!/bin/bash
fullday=`date +%w`
backfile=`find /var/lib/mysql/ -name mylog.00* | head -1`

if [ $fullday -eq 0 ]
then
mysqldump -A > /mysql_backup/full_`date +%Y%m%d%H%M`.sql
else
if [ -z $backfile ]
then
echo 'file not found,create new binlog!'
mysqladmin flush-logs
else
mysqladmin flush-logs
tar cvzf /mysql_backup/`date +%Y%m%d%H%M`.tar.gz $backfile
rm -rf $backfile
fi
fi



你可能感兴趣的:(linux之mysql)