朝花夕拾 Mysql笔记3

朝花夕拾 Mysql笔记3_存储过程


欢迎扫码关注微信公众号 “野心与​


6.1 事务管理

> 6.1.1 事务的概念


所谓的事务就是针对数据库的一组操作,它可以由一条或多条SQL语句组成,同一个事务的操作具备同步的特点,即事务中的语句要么都执行,要么都不执行


开启事务的语法: start transaction


上述语句用于开启事务,事务开启之后就可以执行SQL语句,SQL语句执行成功后,需使用相对应语句提交事务,语法如下:


提交事务的语法: commit


在操作一个事务时,如果发现当前事务中的操作是不合理的,此时只要还没有提交事务,就可以通过回滚来取消当前事务


事务回滚语句: rollback

6.2 存储过程的创建

> 6.2.1 创建存储过程


存储过程就是一条或多条SQL语句的集合,当对数据库进行一系列复杂操作时,存储过程可以将这些复杂操作封装成一个代码块,以便重复使用,大大减少数据库开发人员的工作量


语法格式: 
CREATE PROCEDURE sp_name([proc_parameter])
[characteristics…]routine_body
CREATE PROCEDURE:为用来创建存储过程的关键字。
sp_name: 为存储过程的名称。
proc_parameter: 为指定存储过程的参数列表。
characteristics : 用于指定存储过程的特性。


演示存储过程的创建


1.首先创建一个student表:
mysql> create table student(
-> id int(3) primary key auto_increment,
-> name varchar(20) not null,
-> grade float,
-> gender char(2)
-> );
2.插入数据
mysql> insert into student(name,grade,gender)
-> values('tom',60,'男'),
-> ('jack',70,'男'),
-> ('rose',90,'女'),
-> ('lucy',100,'女');
3.创建一个查看student表的存储过程
创建一个存储过程proc,每次调用这个存储过程的时候都会执行select语句查看表的内容
mysql> delimiter // --------> 作用: 将MySQL的结束符设置为 //
mysql> create procedure proc()
-> begin
-> select * from student;
-> end //

> 6.2.2 变量的使用


在MySQL中, 变量可以在子程序中声明, 用于保存数据处理过程中的值, 这些变量的作用范围在BEGIN…END程序中


语法格式: DECLARE var_name[,varname]…date_type[DEFAULT value];
例如: 定义一个名称为v1的变量,类型为INT类型,默认值为100,查询这个变量的值
mysql> delimiter //
mysql> create procedure proc2()
-> begin
-> declare v1 int default 100;
-> select v1;
-> end //
mysql> delimiter ;
mysql> call proc2();
+------+
| v1 |
+------+
| 100 |
+------+

例如: 声明三个变量,使用set为变量赋值
mysql> delimiter //
mysql> create procedure proc2()
-> begin
-> declare v1,v2,v3 int;
-> set v1=10,v2=20;
-> set v3=v1+v2;
-> select v1,v2,v3;
-> end //
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> call proc2();
+------+------+------+
| v1 | v2 | v3 |
+------+------+------+
| 10 | 20 | 30 |
+------+------+------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)


除了使用set语句为变量赋值外,MySQL中还可以通过select…into为一个或多个变量赋值,
该语句可以把选定的列直接储存到对应的位置的变量
语法格式如下:


select col_name[...] into var_name [...] table_expr


上述语法格式中,col_name表示字段名称;var_name表示定义的变量名称,table_expr 表示查询条件表达式,包括表名称和where子句.

例如:


select grade, gender into s_grade, s_gender from student where name= 'rose' ;


例:声明变量s_grade 和 s_gender,通过select …into 语句 查询指定记录并为变量赋值

注意: 查询时如果不执行 select s_grade,s_gender; 则无返回结果


mysql> delimiter //
mysql> create procedure proc4()
-> begin
-> declare s_grade float;
-> declare s_gender char(4);
-> select grade,gender into s_grade,s_gender from student where name='rose';
-> select s_grade,s_gender;
-> end //
Query OK, 0 rows affected (0.00 sec)

mysql> call proc4()//
+---------+----------+
| s_grade | s_gender |
+---------+----------+
| 90 | 女 |
+---------+----------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.01 sec)

> 6.2.3 定义条件和处理程序

> 1.定义条件


定义条件是指事先定义程序执行过程中遇到的问题。定义条件使用DECLARE语句,语法格式如下:


DECLARE condition_name CONDITION FOR [condition_type];
// condition_type的两种形式:
[condition_type]:
SQLSTATE[VALUE] sqlstate_value|mysql_error_code


condition_name:表示所定义的条件的名称;
condition_type:表示条件的类型;
sqlstate_value和mysql_error_code:表示MySQL的错误,sqlstate_value是长度为5的字符串类型错误代码,mysql_error_code为数值类型的错误代码。例如:ERROR1142(42000)中,sqlstate_value的值是42000,mysql_error_code的值是1142



例如


// 方法一: 使用sqlstate_value
declare commad_not_allowed condition for sqlstate '42000';
// 方法二: 使用 mysql_error_code
declare commad_not_allowed condition for 1064;
> 2. 定义处理程序


处理程序定义了在程序执行过程中遇到问题时应当采取的处理方式,并且保证存储过程在遇到警告或错误时能继续执行处理过程使用DECLARE语句定义,语法格式如下 :


DECLARE handler_type HANDLER FOR condition_value[,…] sp_statement
handler_type:
CONTINUE|EXIT|UNDO
condition_value: //包括5个字符的字符串错误值 ;
|condition_name //表示declare condition 定义的错误条件名称
|SQLWARNING //匹配所有以01开头的sqlstate错误代码
|NOT FOUND //匹配所有以02开头的sqlstate错误代码
|SQLEXCEPTION //匹配所有没有被sqlwarning 或 not found捕获的sqlstate错误代码
|mysql_error_code //匹配数值类型错误代码


handler_type:为错误处理方式,参数取值
有3个:CONTINUE、EXIT和UNDO。CONTINUE:表示遇到错误不处理,继续执行;
EXIT:遇到错误马上退出。
UNDO:表示遇到错误后撤回之前的操作,MySQL中暂时不支持这样的操作。sp_statement:参数为程序语句段,表示在遇到定义的错误时,需要执行的存储过程。
condition_value:表示错误类型



例如 :


// 方法一:捕获sqlstate_value
declare continue handler for sqlstate '42S02' set @info = 'no_such_table';
// 方法二:捕获mysql_error_code
declare continue handler for 1146 set @info = 'no_such_table'
// 方法三:先定义条件,然后调用
declare continue handler for no_such_table set @info='error';
// 方法四:使用sqlwarning
declare exit handler for sqlwarning set @info='error';
// 方法五:使用not found
declare exit handler for not found set @info='no_such_table';
// 方法六:使用sqlexception
declare exit handler for sqlexception set @info='error';

> 6.2.4 光标的使用

在编写存储过程时,查询语句可能会返回多条记录,如果数据量非常大,则需要使用光标来逐条读取查询结果集中的记录。光标是一种用于轻松处理多行数据的机制

> 1. 光标的声明


想要使用光标处理结果集中的数据, 需要先声明光标 。光标必须声明在声明变量, 条件之后


语法: DECLARE cursor_name CURSOR FOR select_statement
cursor_name表示光标的名称;
select_statement表示select语句的内容, 返回一个用于创建光标的结果集
例如: 声明一个名为cursor_student的光标
DECLARE cursor_student CURSOR FOR select s_name,s_gender FROM student;
> 2. 光标的使用


首先要打开光标


语法: open cursor_name;
select cursor_name into var_name[,var_name]...

cursor_name 表示参数的名称;
var_name 表示将光标中的select语句查询出来的信息存入该参数中, 需要注意的是, var_name必须在声明光标之前就定义好
例如: 使用名称为cursor_student的光标, 将查询出来的信息存入s_name和s_gender中
fetch cursor_student into s_name, s_gender;
> 3. 光标的关闭


使用完光标后要将光标关闭, 关闭光标的语法格式为


close cursor_name;

> 6.2.5 流程控制的使用

流程控制语句用于将多个sql语句划分或组合成符合业务逻辑的代码块

>1. if语句


是指如果条件满足


mysql> delimiter //
mysql> create procedure proc6() //定义一个存储过程;
-> begin //开始;
-> declare var int; //定义一个变量 var;
-> set var=10; //设置var的值,可不设置;
-> if var is null //if语句开始;
-> then select 'val is null';
-> else select 'val is not null';
-> end if; //if语句结束;
-> end // //结束;
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;
mysql> call proc6(); //查看
+-----------------+
| val is not null |
+-----------------+
| val is not null |
+-----------------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)
> 2. case 语句
mysql> delimiter //
mysql> create procedure proc7()
-> begin
-> declare var int;
-> set var=1;
-> case var
-> when 1 then select 'val is 1';
-> when 2 then select 'val is 2';
-> else select 'val is not 1 or 2';
-> end case;
-> end //
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;
mysql> call proc7();
+----------+
| val is 1 |
+----------+
| val is 1 |
+----------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.01 sec)
> 3.loop 语句


loop循环语句用来重复执行某些语句,并不会进行条件判断。

loop语句内的语句会一直重复执行直到跳出循环语句



基本语法如下 :


[loop_label:]LOOP   // loop_label 表示loop语句的标记名称,该参数可以省略
statement_list // statement_list 表示需要循环执行的语句
END LOOP [loop_label]
> 4. leave语句


当不满足循环条件时, 需要用leave语句退出循环


语法: leave label


例如:


mysql> create procedure proc8()
-> begin
-> declare id int default 0;
-> add_loop:LOOP
-> set id=id+1;
-> if id>=10 then leave add_loop;
-> end if;
-> end LOOP add_loop;
-> select id;
-> end //
Query OK, 0 rows affected (0.00 sec)

mysql> call proc8() //
+------+
| id |
+------+
| 10 |
+------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.01 sec)
> 5. iterate 语句
mysql> delimiter //
mysql> create procedure proc9()
-> begin
-> declare p1 int default 0; //p1初始值为0;
-> my_loop:loop
-> set p1=p1+1;
-> if p1<10 then iterate my_loop; //如果p1的值小于10是,重复执行p+1
-> elesif p1>20 then leave my_loop; //当p1的值大于或等于10并且小于20时
-> end if;
-> select 'p1 is between 10 and 20'; //当p1的值大于或等于10并且小于20时,打印"p1 is bet..."
-> end loop my_loop;
-> end //
> 6. repeat 语句


作用: 创建一个带有条件判断的循环过程, 每次语句执行完毕后, 会对条件表达式进行判断, 如果表达式为真, 则循环结束; 否则重复执行循环中的语句


语法: [repeat_lable:] repeat    //repeat_label为repeat语句的标注名称,该参数可选
statement_list
utill expr_condition //reapeat语句内的语句或语句群被重复,直至expr_condition为真
end repeat [repeat_lable]


例如


mysql> create procedure proc40()
-> begin
-> declare id int default 0;
-> repeat //
-> set id=id+1;
-> select id; //遍历 1-10;
-> until id>=10 --------->> 不带分号
-> end repeat; //
-> end //
Query OK, 0 rows affected (0.00 sec)
> 7. where 语句


作用: 创建一个带条件判断的循环过程, 与repeat 不同的是, where在语句执行时, 先对指定的表达式进行判断, 如果为真, 则执行循环内的语句, 否则退出循环


语法: [where_lable:] where expr_condition DO
Statement_list
end where [where_lable]
mysql> create procedure proc42()
-> begin
-> declare i int default 0;
-> while i<10 do
-> set i=i+1;
-> select i; //遍历1-10;
-> end while;
-> end //
Query OK, 0 rows affected (0.01 sec)

6.3 存储过程的使用

> 6.3.1 调用存储过程


1.定义存储过程


mysql> create procedure test2(in s_gender varchar(50),out num int )
-> begin
-> select count(*) into num from student where gender=s_gender;
-> end //
Query OK, 0 rows affected (0.00 sec)


2调用存储过程


mysql> delimiter ;
mysql> call test2("女",@num);
Query OK, 1 row affected (0.01 sec)


3.查看返回结果


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

>6.3.2 查看存储过程

> 1. show status 语句中查看存储过程的状态
mysql> show procedure status like 'proc%' \G
*************************** 1. row ***************************
Db: chapter06
Name: proc
Type: PROCEDURE
Definer: root@localhost
Modified: 2020-11-25 08:32:11
Created: 2020-11-25 08:32:11
Security_type: DEFINER
Comment:
character_set_client: gbk
collation_connection: gbk_chinese_ci
Database Collation: utf8_general_ci
*************************** 2. row ***************************
Db: chapter06
Name: proc1
Type: PROCEDURE
Definer: root@localhost
Modified: 2020-11-25 09:15:20
Created: 2020-11-25 09:15:20
Security_type: DEFINER
Comment:
character_set_client: gbk
collation_connection: gbk_chinese_ci
Database Collation: utf8_general_ci
> 2. show create 语句中查看存储过程的状态&创建语句
mysql> show create procedure chapter06.proc1 \G
*************************** 1. row ***************************
Procedure: proc1
sql_mode: STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
Create Procedure: CREATE DEFINER=`root`@`localhost` PROCEDURE `proc1`()
begin
select * from student;
end
character_set_client: gbk
collation_connection: gbk_chinese_ci
Database Collation: utf8_general_ci
1 row in set (0.00 sec)
> 3.从information_schema.Routine 表中查看存储过程的信息
mysql> select * from information_schema.Routines
-> where routine_name='proc1'
-> and routine_type='procedure' \G
*************************** 1. row ***************************
SPECIFIC_NAME: proc1
ROUTINE_CATALOG: def
ROUTINE_SCHEMA: chapter06
ROUTINE_NAME: proc1
ROUTINE_TYPE: PROCEDURE
DATA_TYPE:
CHARACTER_MAXIMUM_LENGTH: NULL
CHARACTER_OCTET_LENGTH: NULL
NUMERIC_PRECISION: NULL
NUMERIC_SCALE: NULL
CHARACTER_SET_NAME: NULL
COLLATION_NAME: NULL
DTD_IDENTIFIER: NULL
ROUTINE_BODY: SQL
ROUTINE_DEFINITION: begin
select * from student;
end
EXTERNAL_NAME: NULL
EXTERNAL_LANGUAGE: NULL
PARAMETER_STYLE: SQL
IS_DETERMINISTIC: NO
SQL_DATA_ACCESS: CONTAINS SQL
SQL_PATH: NULL
SECURITY_TYPE: DEFINER
CREATED: 2020-11-25 09:15:20
LAST_ALTERED: 2020-11-25 09:15:20
SQL_MODE: STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
ROUTINE_COMMENT:
DEFINER: root@localhost
CHARACTER_SET_CLIENT: gbk
COLLATION_CONNECTION: gbk_chinese_ci
DATABASE_COLLATION: utf8_general_ci
1 row in set (0.01 sec)

根据学号查询

mysql> delimiter //
mysql> create procedure proc43(in myid int)
-> begin
-> select name from student where id=myid;
-> end //
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;
mysql> call proc43(1) ;
+------+
| name |
+------+
| tom |
+------+

根据输入的ID从学生表中查询该ID对应的姓名,并输出姓名

mysql> delimiter //
mysql> create procedure test1(in myid int,out myname varchar(36))
-> begin
-> select name into myname from student where id=myid;
-> end //
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;
mysql> call test1(3,@myname) ; //调用存储过程
Query OK, 1 row affected (0.00 sec)

mysql> select @myname ; //查看返回结果
+---------+
| @myname |
+---------+
| rose |
+---------+
1 row in set (0.00 sec)

> 6.3.3 修改存储过程


在MySQL中可以使用alter语句修改存储过程

语法格式如下:


ALTER {PROCEDURE|FUNCTION} sp_name[characteristic…]


sp_name:表示存储过程或函数的名称。characteristic:表示要修改存储过程的哪个部分



characteristic 的取值如下:


1.contains sql 表示子程序中包括sql语句, 但不包含读或写数据的语句;
2.no sql 表示子程序中不包括sql语句;
3.reads sql data 表示表示子程序中包括读数据的语句;
4.modifies sql data 表示子程序中包括写数据的语句;
5.sql security{definer|invoker} 指明谁有权限来执行;
6.definer 表示只有定义者自己才能执行;
7.invoker 表示调用者可以执行;
8.comment 'string' 表示注释信息;


注意: 目前此版本Mysql还不提供对已存在的存储过程代码的修改, 如果一定要修改存储过程代码, 必须先将存储过程删除之后, 再重新编写代码, 或创建一个新的存储过程



> 6.3.4 删除存储过程


在MySQL中使用DROP语句修改存储过程,语法如下:


DROP{ procedure|function }[if exists] sp_name


if exists 表示如果程序不存在, 它可以避免发生错误, 产生一个警告




7.1 视图概述

视图是从基本表中导出来的表,是一种虚拟存在的表, 并且表的结构和数据都依赖于基本表

通过视图不仅可以看到放在基本表中的数据, 并且还可以像操作基本表一样, 对视图中存放的数据进行查询

删除,修改 .与直接操作表相比视图具有以下优点:


1.简化查询语句
日常开发中我们可以将经常使用的查询定义为视图,从而使用户避免大量重复的操作。
2安全性
通过视图用户只能查询和修改他们所能见到的数据,数据库中的其他数据则既看不到也取不到。
3逻辑数据独立性
视图可以帮助用户屏蔽真实表结构变化带来的影响。



7.2 视图管理

> 7.2.1 创建视图的语法格式:

create [or replace] [algorithm={undefined | merge | temptable]
view view_name [(column_list)]
as select_statement
[where [cascaded|local] check option]


CREATE:表示创建视图的关键字。
OR REPLACE:表示该语句能够替换已有视图。
ALGORITHM:可选,表示视图选择的算法。
UNDEFINED:表示MySQL将自动选择所要使用的算法。
MERGE:使得视图定义的某一部分取代语句的对应部分。
TEMPTABLE:表示将视图的结果存入临时表,然后使用临时表执行语句。
view_name:表示要创建的视图名称。
column_list:可选,表示属性清单。
AS:表示指定视图要执行的操作。
SELECT_statement:表示从某个表或视图中查出满足条件的记录,并导入视图中。
WITH CHECK OPTION:可选,表示创建视图时要保证在该视图的权限范围之内。
CASCADED:需要满足跟该视图有关的所有相关视图和表的条件,该参数为默认值。
LOCAL:可选。表示创建视图时,只要满足该视图本身定义的条件即可。



>7.2.2 在单标上创建视图


在student表上创建view_stu视图和view_stu2视图(自定义字段名)


1.创建数据库,表,插入数据

mysql> create database chapter07;
Query OK, 1 row affected (0.04 sec)

mysql> use chapter07
Database changed
mysql> create table student(
-> s_id int(3),
-> name varchar(20),
-> math float,
-> chinese float
-> );
Query OK, 0 rows affected (0.05 sec)

mysql> insert into student(s_id,name,math,chinese) values
-> (1,'Tom',80,78),
-> (2,'Jack',70,80),
-> (3,'Lucy',97,95);
Query OK, 3 rows affected (0.05 sec)
Records: 3 Duplicates: 0 Warnings: 0

mysql> select * from student;
+------+------+------+---------+
| s_id | name | math | chinese |
+------+------+------+---------+
| 1 | Tom | 80 | 78 |
| 2 | Jack | 70 | 80 |
| 3 | Lucy | 97 | 95 |
+------+------+------+---------+
3 rows in set (0.00 sec)

2.创建视图并查询

mysql> create view view_stu as select math,chinese,math+chinese from student;
mysql> select * from view_stu;
+------+---------+--------------+
| math | chinese | math+chinese |
+------+---------+--------------+
| 80 | 78 | 158 |
| 70 | 80 | 150 |
| 97 | 95 | 192 |
+------+---------+--------------+
3 rows in set (0.00 sec)

mysql> create view view_stu2(math,chinese,sum) as select math,chinese,math+chinese from student;
Query OK, 0 rows affected (0.02 sec)

mysql> select * from view_stu2;
+------+---------+------+
| math | chinese | sum |
+------+---------+------+
| 80 | 78 | 158 |
| 70 | 80 | 150 |
| 97 | 95 | 192 |
+------+---------+------+
3 rows in set (0.00 sec)

> 7.2.3 在多表上创建视图


在student表和stu_info表中创建stu_class视图, 查询s_id号,姓名和班级


1.创建数据库,表,插入数据

mysql> create table stu_info(
-> s_id int(3),
-> class varchar(50),
-> addr varchar(100)
-> );
Query OK, 0 rows affected (0.01 sec)

mysql> insert into stu_info(s_id,class,addr) values
-> (1,'erban','anhui'),
-> (2,'sanban','chongqing'),
-> (3,'yiban','shandong');
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0

mysql> select * from stu_info;
+------+--------+-----------+
| s_id | class | addr |
+------+--------+-----------+
| 1 | erban | anhui |
| 2 | sanban | chongqing |
| 3 | yiban | shandong |
+------+--------+-----------+
3 rows in set (0.00 sec)

2.创建视图并查询

mysql> create view stu_class(id,name,class) as select student.s_id,student.name,stu_info.class from student,stu_info where student.s_id=stu_info.s_id;
Query OK, 0 rows affected (0.02 sec)

mysql> select * from stu_class;
+------+------+--------+
| id | name | class |
+------+------+--------+
| 1 | Tom | erban |
| 2 | Jack | sanban |
| 3 | Lucy | yiban |
+------+------+--------+
3 rows in set (0.00 sec)

> 7.2.4 查看视图

> 1. 使用describe 语句查看视图


作用: 使用DESCRIBE语句可以查看视图的字段信息

语法: DESCRIBE 视图名; 或 DESC 视图名;


例如: desc stu_class;
> 2. 使用 show table status


作用: 可以查看视图的基本信息

语法: SHOW TABLE STATUS LIKE ‘视图名’; ----> 注意like 引号


例如: show table status like 'stu_class' \G;
> 3. 使用 show create view


作用: 不仅可以查看创建视图时的定义语句,还可以查看视图的字符编码

语法: SHOW CREATE VIEW 视图名;


例如: show create view stu_class \G;

> 7.2.5 修改视图

> 1. 使用 create or replace view 语句修改视图;


语法 : create or replace view 视图名 as select 表中字段 from 表名


create or replace view view_stu as select * from student;
> 2. 使用 alter 语句修改视图;


语法 : alter view 视图名 as select 表中字段 from 表名


alter view view_stu as select chinese from student;

> 7.2.6 更新视图

1. 使用update 语句更新视图
update view_stu set chinese=100;
2. 使用insert 语句更新视图
insert into student values(4,'Lily',100,100);
3. 使用delete语句更新视图
delete from view_stu2 where math=10;

7.2.7 删除视图

视图不在需要时,可以将其删除,删除视图只会删除视图的定义,不会删除数据.

删除一个或多个视图可以使用dorp view语句, 删除视图的基本语法格式如下所示:

drop view [if exists]
view_name [,view_name1] ...
[restrict|cascade]

view_name 是指要删除的视图的名称,视图名称可以添加多个,各个名称用逗号隔开,删除视图必须有root权限
例如: 删除view_stu2视图
drop view if exists view_stu2;


8.1 数据备份与还原

8.1.1 数据的备份

通过MySQL的mysqldump命令实现数据的备份

1. 备份单个数据库


mysqldump 命令备份数据库的语法格式如下 :


mysqldump -u username -p password dbname [tbname] [tbname2...] > filename.sql


上述语法格式中, -u后面的参数username 表示用户名, -p 后面的参数 password表示登录密码, dbname 表示需要备份的数据库的名称, tbname表示数据库中的表名, 可以指定一个表或多个表, 多个表之间用空格隔开, 如果不指定则备份整个数据库, filename.sql 表示备份文件的名称, 文件名前可以加上绝对路径

注意: 在使用mysqldump命令备份数据库时, 直接在dos命令行窗口中执行该命令即可, 不需要登录到mysql数据库


例如:

例如: 创建一个名称为chapter08的数据库, 并在数据库中创建表student, 插入相应数据
mysql> create database chapter08
mysql> use chapter08
Database changed
mysql> create table student(
-> id int primary key auto_increment,
-> name varchar(20),
-> age int
-> );
Query OK, 0 rows affected (0.01 sec)

mysql> insert into student(name,age) values
-> ('Tom',20),
-> ('Jack',16),
-> ('Lucy',18);
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0

mysql> select * from student;
+----+------+------+
| id | name | age |
+----+------+------+
| 1 | Tom | 20 |
| 2 | Jack | 16 |
| 3 | Lucy | 18 |
+----+------+------+
3 rows in set (0.00 sec)


首先在C盘创建一个名为backupdb的 文件夹用来存备份好的文件夹, 然后重新开启一个dos命令行窗口( 不需要登录到MySQL数据库), 使用mysqldump命令登录备份chapter08


语法: 
C:\Users\ASUS>mysqldump -u root -p chapter08 > C:/backupdb/chapter08.sql
Enter password: ****

查看备份:

-- MySQL dump 10.13  Distrib 5.5.28, for Win32 (x86)
--
-- Host: localhost Database: chapter08
-- ------------------------------------------------------
-- Server version 5.5.28

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `student`
--

DROP TABLE IF EXISTS `student`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `student` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(20) DEFAULT NULL,
`age` INT(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `student`
--

LOCK TABLES `student` WRITE;
/*!40000 ALTER TABLE `student` DISABLE KEYS */;
INSERT INTO `student` VALUES (1,'Tom',20),(2,'Jack',16),(3,'Lucy',18);
/*!40000 ALTER TABLE `student` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2020-12-16 8:30:50
2. 备份多个数据库
mysqldump –u username –p password -–database dbname1 [dbname2 dbname3…]
>filename.sql
3. 备份所以数据库
mysqldump –uusername –ppassword -–all-databases>filename.sql

8.1.2 数据的还原

语法: mysql –uusername –ppassword [dbname] <filename.sql
1. 删除数据库
mysql> drop database chapter08;
2. 创建数据库
mysql> create database chapter08;
Query OK, 1 row affected (0.01 sec)
3. 还原数据库
C:\Users\ASUS>mysql -u root -p chapter08 < C:/backupdb/chapter08-1.sql
Enter password: ****
4. 查看数据
mysql> use chapter08
Database changed
mysql> select * from student;
+----+------+------+
| id | name | age |
+----+------+------+
| 1 | Tom | 20 |
| 2 | Jack | 16 |
| 3 | Lucy | 18 |
+----+------+------+
3 rows in set (0.00 sec)

8.2 用户管理

8.2.1 user表


在安装数据库的时候会自动安装一个名为mysql的数据库, 该数据库中的表都是权限表, 如user, db, host ,table_priv

其中user表是最重要的一个权限表, 它记录了允许链接到服务器的账号信息以及一些全局级的权限信息, 通过操作表就可以对这些信息进行修改


mysql> use mysql
mysql> desc 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 | |
| Update_priv | enum('N','Y') | NO | | N | |
| Delete_priv | enum('N','Y') | NO | | N | |
| Create_priv | enum('N','Y') | NO | | N | |
| Drop_priv | enum('N','Y') | NO | | N | |
| Reload_priv | enum('N','Y') | NO | | N | |
| Shutdown_priv | enum('N','Y') | NO | | N | |
| Process_priv | enum('N','Y') | NO | | N | |
| File_priv | enum('N','Y') | NO | | N | |
| Grant_priv | enum('N','Y') | NO | | N | |
| References_priv | enum('N','Y') | NO | | N | |
| Index_priv | enum('N','Y') | NO | | N | |
| Alter_priv | enum('N','Y') | NO | | N | |
| Show_db_priv | enum('N','Y') | NO | | N | |
| Super_priv | enum('N','Y') | NO | | N | |
| Create_tmp_table_priv | enum('N','Y') | NO | | N | |
| Lock_tables_priv | enum('N','Y') | NO | | N | |
| Execute_priv | enum('N','Y') | NO | | N | |
| Repl_slave_priv | enum('N','Y') | NO | | N | |
| Repl_client_priv | enum('N','Y') | NO | | N | |
| Create_view_priv | enum('N','Y') | NO | | N | |
| Show_view_priv | enum('N','Y') | NO | | N | |
| Create_routine_priv | enum('N','Y') | NO | | N | |
| Alter_routine_priv | enum('N','Y') | NO | | N | |
| Create_user_priv | enum('N','Y') | NO | | N | |
| Event_priv | enum('N','Y') | NO | | N | |
| Trigger_priv | enum('N','Y') | NO | | N | |
| Create_tablespace_priv | enum('N','Y') | NO | | N | |
| ssl_type | enum('','ANY','X509','SPECIFIED') | NO | | | |
| ssl_cipher | blob | NO | | NULL | |
| x509_issuer | blob | NO | | NULL | |
| x509_subject | blob | NO | | NULL | |
| max_questions | int(11) unsigned | NO | | 0 | |
| max_updates | int(11) unsigned | NO | | 0 | |
| max_connections | int(11) unsigned | NO | | 0 | |
| max_user_connections | int(11) unsigned | NO | | 0 | |
| plugin | char(64) | YES | | | |
| authentication_string | text | YES | | NULL | |
+------------------------+-----------------------------------+------+-----+---------+-------
1. 用户列


用户列包括Host、User、Password,分别代表主机名、用户名和密码

其中Host和User列为user表的联合主键

当修改密码时,只需要修改,user表中Password字段的值即可


2. 权限列


user表的权限列包括Select_priv、Insert_priv、Update_priv等以priv结尾的字段,这些字段决定了用户的权限,其中包括查询权限、修改权限、关闭服务等权限。


3.安全列


user表的安全列用于管理用户的安全信息,其中包括6个字段,具体如下:
ssl_type和ssl_cipher:用于加密
x509_issuer和x509_subject标准:可以用来标识用户
plugin和authentication_string:用于存储与授权相关的插件


4. 资源控制列


资源控制列是用于限制用户使用的资源,包括4个字段,具体如下:
max_questions:每小时允许用户执行查询操作的次数
max_updates:每小时允许用户执行更新操作的次数
max_connections:每小时允许用户建立连接的次数
max_user_connections:允许单个用户同时建立连接的次数


8.2.2 创建普通用户

1. 使用 grant 语句创建用户
GRANT privileges ON database.table
TO 'username'@'hostname' [IDENTIFIED BY [PASSWORD]'password']
[,'username'@'hostname [IDENTIFIED BY [PASSWORD]'password']] …


privileges 参数表示该用户具有的权限信息, database.table 表示新用户的权限范围表, 可以在指定的数据库, 表上使用自己的权限, username参数是新用户的名称, hostname参数是主机名, password参数是新用户的密码


例如: 使用grant 语句创建一个新用户, 用户名是user1, 密码是 123, 并授予该用户对chapter08.student 表具有查询权限

grant select on chapter08.student to 'user1'@'localhost' identified by '123';
mysql> select host,user,password from user;
+-----------+-------+-------------------------------------------+
| host | user | password |
+-----------+-------+-------------------------------------------+
| localhost | root | *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B |
| localhost | user1 | *23AE809DDACAF96AF0FD78ED04B6A265E05AA257 |
| % | root | *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B |
+-----------+-------+-------------------------------------------+
3 rows in set (0.00 sec)
2. 使用 create user 语句创建用户
CREATE USER 'username'@'hostname'[IDENTIFIED BY [PASSWORD]'password']
[,'username'@'hostname'[IDENTIFIED BY [PASSWORD]'password']]…


username参数是新用户的名称, hostname参数是主机名,identified by关键字用于设置用户的密码, password 表示用户的密码, [PASSWORD] 关键字表示使用哈希值设置的密码, 该参数是可选的, 如果密码是一个普通的字符串, 就不需要使用PASSWORD 关键字


例如: 使用create user语句创建一个新用户, 用户名为user2, 密码是123, create user语法如下:
create user 'user2'@'localhost' identified by '123';
3. 使用 insert 语句创建用户
INSERT INTO mysql.user(Host,User,Password,ssl_cipher、x509_issuer、x509_subject)
VALUES('hostname','username',PASSWORD('password'),'','','');


上述语法格式中, mysql.user表示操作的表, Host,User,Password,ssl_cipher、x509_issuer、x509_subject 为相应字段

PASSWORD( ) 是一个加密函数, 用于给密码加密

注意: 使用insert添加用户时, 通常只需要添加host, user和password这三个字段即可, 其他字段取默认值,但由于

Host,User,Password,ssl_cipher、x509_issuer、x509_subject 字段是没有默认值的, 因此insert语句创建用户时, 还需要为这几个字段设置初始值


例如: 使用insert 语句直接在mysql.user表中创建一个新用户, 用户名为user3, 密码为123 ,insert语句如下: 
insert into mysql.user(Host,User,Password,scl_cipher,x509_issuer,x509_subject)
values('localhost','user3',password('123'),'','');


注意: insert语句没有刷新权限表的功能, 因此,user3用户暂时不能使用,为了让当前用户生效, 还需要手动刷新当前的权限表或重新启动mysql服务, 刷新权限表的语句如下:


flush privileges;

8.2.3 删除普通用户

1. 使用drop user 语句删除用户

drop user语句与drop database 语句有些相似, 如果删除某个用户, 只需在 drop user 后面指定要删除的用户信息即可


语法:


drop user 'username'@'hostname'[,'username'@'hostname'];


username 表示要删除的用户, hostname表示主机名, drop user语句可以同时删除一个或多个用户, 多个用户之间可以使用逗号隔开

注意: 使用drop user语句来删除用户时, 必须拥有drop user 权限



使用drop user语句删除用户 user1


drop user 'user'@'localhost';
2. 使用 delete 语句删除用户


delete语句不仅可以删除普通表中的数据, 还可以删除 user表中的数据, 使用该语句删除 user表中的数据时, 只需要指定表名为mysql.user, 以及要删除的用户信息即可, 同样的, 在使用delete语句时必须拥有对mysql.user表的delete权限


语法格式如下: delete from mysql.user where host='hostname' and user='username';


上述语法格式中, mysql.user 参数指定要操作的表, where 指定条件语句, host和user 都是mysql.user 表的字段,

这两个字段可以确定唯一的一条记录


例如: 使用delete语句删除用户 user2
delete from mysql.user where host='localhost' and user='user2';


注意: 由于直接对user表进行操作, 执行完命令后需要使用’flush privileges’ 语句重新加载用户权限


8.2.4 修改用户密码

1. 修改 root用户密码


一. 通过mysqladmin命令修改root用户的密码


mysqladmin命令通常用于执行一些管理性工作


语法格式如下:


mysqladmin -u username [-h hostname] -p password new_password;


username为要修改的用户名, 这里指的是root用户, 参数 -h 用于指定对应的主机, 可以省略不写, 默认为 localhost

-p 后面的password为关键字, 而不是修改后的密码, new_password 为新设置的密码

注意: 在使用mysqladmin命令修改root用户密码时, 需要在 C: \document and setting\administrator>目录下进行修改


例如: 在命令行窗口中使用mysqladmin命令, 将root用户的密码修改为mypwd1,sql语句如下: 
mysqladmin -u root -p password mypwd1


二. 通过update语句修改root用户的密码


由于所以的用户信息都存放在mysql.user表中, 因此,只有root用户登录到MySQL服务器, 使用update语句就可以直接修改自己的密码


语法格式如下


update mysql.user set password=password('mypwd2') where user='root' and host='localhost';


上述语法执行成功后, 还需要使用 flush privileges 重新加载权限表, 然后就可以使用新密码登录 mysql数据库

结果如下 :




三. 使用set 语句修改root用户的密码


root用户登录到mysql数据库后, 还可以通过set语句修改root用户的密码


set语句修改密码的语法格式如下:


set password=password('new_password');


注意: 由于set语句没有对密码加密的功能, 因此, 新密码必须使用password() 函数加密, 并且新密码需要使用引号括起


例如: root用户登录到mysql数据库, 使用set 语句将root用户的密码修改为mypwd3, set语句如下:
set password=password('mypwd3');
2. root 用户修改普通用户的密码


1.使用grant语句修改普通用户密码



grant语句的作用比较多, 不仅可以创建用户授权, 还可以修改用户的密码, 通常情况下, 为了不影响当前账户的权限, 可以使用grant usage语句修改指定的账户的密码



grant语句修改密码语法格式如下:


grant usage on * . * to 'username'@'localhost' identified by [password] 'new_password';


2.使用update语句修改普通用户的密码



root用户具有操作数据库的所有权限, 因此, 它不仅可以使用update语句修改自己的密码, 还可以使用update语句修改普通用户的密码



update的语法格式为与root修改用户密码的语法格式相同


update mysql.user set password=password('new_password')
where user='username' and host='hostname';


注意: 通过上述语句修改完普通用户的密码后, 还需要使用flush privileges语句重新加载权限表



3.使用set语句修改普通用户的密码



set 不仅可以修改root用户的密码, 而且还可以修改普通用户密码, 在修改普通用户密码时, 还需要增加一个for子句, 指定要修改哪一个用户即可



set语句修改密码的语法格式如下


set password for 'username'@'hostname'=password('new_password');
3. 普通用户修改密码


普通用户也可以修改自己的密码, 这样普通用户就不需要每次修改密码时都通知管理员, 普通用户登录到MySQL服务器后, 可以通过set语句来设置自己的密码



set语句的基本格式如下:


set password=password('new_password');


set语句修改普通用户密码时, 和修改root用户是一样的, 都需要使用password() 函数进行加密



8.3 权限管理

8.3.1 MySQL的权限

Mysql中的权限信息被储存在mysql 数据库的 user,db,host,table_priv,column_priv和procs_priv表中, 当MySQL启动时会自动加载这些权限信息, 并将这些权限信息读取到内存中

朝花夕拾 Mysql笔记3_sql_02


权限解释:


8.3.2 授予权限


我们之所以可以对数据进行增删改查的操作,是因为数据库中的用户拥有不同的权限,合理的授权可以保证数据库的安全



MySQL中的GRANT语句可以为用户授权,语法格式如下:


GRANT privileges [(columns)][,privileges[(columns)]] ON database.table
TO 'username'@'hostname' [IDENTIFIED BY [PASSWORD]'password']
[,'username'@'hostname' [IDENTIFIED BY [PASSWORD]'password']] …
[WITH with_option [with_option]…]


privileges:表示权限类型。
columns:参数表示权限作用于某一列,该参数可以省略不写,此时权限作用于整个表,username:表示用户名。
hostname表示主机名。
IDENTIFIED BY:参数为用户设置密码。
PASSWORD参数为关键字.
password为用户的新密码。



WITH关键字后面可以带有多个参数with_option,这个参数有五个取值

具体如下:

GRANT OPTION:将自己的权限授予其他用户MAX_QUERIES_PER_HOUR count:设置每小时最多可以执行多少次(count)查询。
MAX_UPDATES_PER_HOUR count:设置每小时最多可以执行多少次更新。
MAX_CONNECTIONS_PER_HOUR count:设置每小时最大的连接数量。
MAX_USER_CONNECTIONS:设置每个用户最多可以同时建立连接的数量。


8.3.3 查看权限


虽然使用SELECT语句可以查询user表中的权限信息,但是该语句需要指定用户和查询的权限,比较麻烦,MySQL还提供了一个查看权限的简单语句-SHOW GRANTS语句



SHOW GRANTS的语法格式如下:


SHOW GRANTS FOR 'username'@'hostname';


语法格式相对简单, 只需要指定查询的用户名和主机名即可



例1: 使用show grants语句查询root用户的权限信息


show grants for 'root'@'hostname';


例2: 使用show grants语句查询user4 用户的权限信息


show grants for 'user4'@'hostname';

8.3.4 收回权限


为了保证数据库的安全性,需要将用户不必要的权限收回,收回用户权限使用REVOKE语句



收回用户指定权限, 语法格式如下所示 :


REVOKE privileges [columns][,privileges[(columns)]] ON database.table 
FROM 'username'@'hostname'[,'username'@'hostname'] …


revoke语法格式中的参数与grant语句中的参数意思相同, privileges参数表示收回的权限,columns表示权限作用于哪列上, 如果不指定该参数表示作用于整个表



使用revoke语句收回user4用户的insert权限, revoke语句如下:


revoke insert on * . * from 'user'@'localhost';

另外如果权限比较多可以使用收回所以权限的功能


收回用户全部权限, 语法格式如下所示 :


REVOKE ALL PRIVILEGES,GRANT OPTION 
FROM 'username'@'hostname' [,'username'@'hostname'] …


使用revoke语句收回user4用户的insert权限, revoke语句如下:


revoke all privileges,grant option from 'user4'@'localhost';