朝花夕拾 Mysql笔记3

朝花夕拾 Mysql笔记3

欢迎扫码关注微信公众号"野心与家"回复"12.11MySQL3"获取源文件

点击此处回顾上一篇 : 朝花夕拾 Mysql笔记2

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启动时会自动加载这些权限信息, 并将这些权限信息读取到内存中

在这里插入图片描述

权限解释:

1. createdrop的权限, 可以创建数据库,,索引,或者删除已有的数据库,, 索引
2. insert, delete,update,select 权限,可以对数据库中的表进行增删改查操作
3. index权限,可以创建或删除索引, 适用于所以的表
4. alter权限.可以用于修改表的结构或重命名表
5. grant权限, 允许为其他用户授权, 可用于数据库和表
6. file权限, 被赋予该权限的用户能读写MySQL服务器上的任何文件

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';

猜你喜欢

转载自blog.csdn.net/m0_46653702/article/details/111043376