MySQL数据库板书

一、课程介绍

《数据库原理和应用》是一个前导课程,也是一个基础课程。是《应用程序开发》类的课程的基础课程。

二、数据库产品介绍

目前主流的关系数据库有:

Oracle(美国甲骨文公司),大中型应用程序。(Java+Oracle)

SQL Server(美国微软公司),.NET应用程序。(C#+SQL Server)

MySQL(美国甲骨文公司),中小型网站。(Java+MySQL,PHP+MySQL)

PS:数据库排行版编程语言排行版

三、MySQL基础

软件环境

  mysql服务器

    安装:MySQL8.0 社区共享版在windows下的安装

    查看服务:"我的电脑"右键->"管理"->"服务"->列表中找到mysql服务

  mysql客户端

    图形客户端工具navicat,MySQL Workbench,SQLyog

    命令行客户端mysql

      格式:mysql -u <用户名> -p<密码>  --连接本地的mysql服务器

mysql常用命令

  show databases;  --查看所有的数据库

  use <数据库名>;  --切换数据库

  show tables;  --查看当前数据库下的所有表

  desc <表名>;  --查看表结构

 

一、查询(SELECT)

1、基本格式:select   <字段列表>   from    <表名>

说明:

  表示所有字段:*

    如:select * from product;

    如果查部分字段,需要指定,字段间用逗号隔开。

  指定字段的别名:AS

    如:select  id  as  '编号', name  as  '名称'  from product; -- 也可使用空格替代

  去重的关键字:DISTINCT

    例如:select distinct position from player; 

 2、条件子句where

  格式:where  <条件>

  说明:条件是一个逻辑表达式。

  (1)比较运算符:>(大于),  <(小于),  >=(大于等于),  <=(小于等于),  !=或<>(不等于),<=>(安全等于)

    1)除“<=>”外,其它运算符与NULL的运算结果都是NULL。如:1 =NULL为NULL,NULL=NULL为NULL,1>NULL为NULL

    2)只有NULL<=>NULL为1,其它<=>NULL都为0。

  (2)逻辑运算符:not(非)   and(与)    or(或)

  (3)范围运算符:<字段> between <值1> and <值2>

  (4)in运算符:<字段> in (<值1>,<值2>,...)

  (5)like运算符:like '含通配符的字符串',主要作模糊查询

    mysql的通配符:

      %表示任意个字符(0~n)

      _表示任意1个字符

  (6)is null运算符:

    <字段> is [not] null

    说明:null is null结果为1,其它 is null均为0。

3、排序子句

  格式:order by <字段> [desc | asc]

  说明: desc表示降序(值由大到小),asc表示升序(值由小到大),默认为升序。

4、limit子句

  格式:limit([位置偏移量],<记录个数>)

  说明:如果省略位置偏移量,则表示从第1条开始取,第1条记录的位置偏移量为0,第n条记录的位置偏移量为n-1.

    如:limit 10  --从开始取前10条。

    如:limit 20,10  --则表示从第20+1条开始取10条,即(21~30)。

5、分组子句

  格式:group by <字段> [having <条件>]

  说明:having <条件>表示限定分组,即对分组后的结果进行筛选。

  聚合函数(统计函数):

    count(<字段>):记录个数

    sum(<数值字段>):求和

    avg(<数值字段>):求平均值

    max(<数值字段>):求最大值

    min(<数值字段>):求最小值

 6、多表的连接查询

  (1)简单的连接查询(内连接)

  格式:select <字段列表> from <表1>,<表2> where <表1>.<连接字段>=<表2>.<连接字段>

  功能:从多张表查询数据

   (2)join连接

    a、内连接(inner join)

    格式:select <字段列表> from <表1> t1 inner join <表2> t2 on <表1>.<连接字段>=<表2>.<连接字段>

    说明:格式中t1和t2分别表示表1和表2的别名;inner join也简写为join。

    b、外连接

      左外连接(left join)

       格式:select <字段列表> from <表1>left join <表2> on <表1>.<连接字段>=<表2>.<连接字段>

       说明:左表中所有的记录都显示,左表中不符合连接条件的记录的对应的右表数据为null。

      右外连接(right join)

       格式:select <字段列表> from <表1>right join <表2> on <表1>.<连接字段>=<表2>.<连接字段>

       说明:右表中所有的记录都显示,右表中不符合连接条件的记录的对应的左表数据为null。

      满外连接(full join)

       格式:select <字段列表> from <表1>full join <表2> on <表1>.<连接字段>=<表2>.<连接字段>

       说明:两表符合连接条件的记录和两表不符合条件的记录,mysql不支持这种连接

    c、交叉连接(cross join)

    格式:select <字段列表> from <表1>cross join <表2>

    说明:交叉连接有时也叫全连接

  (3)子查询

    概念:子查询就是一个SQL语句中嵌套的一个select语句。  

    a、比较子查询

    格式:select <字段列表> from <表名> where <字段>  <比较运算符>  <子查询>

    说明:

      (1)如果子查询的结果是单值,则直接使用“=”、“>”等比较运算符

        例:

          # 找出比平均工资高的员工的姓名和工资

          select last_name,salary from employees where salary > (select avg(salary) from employees)

      (2)如果子查询的结果是多值,则需要使用SOME、ANY、ALL等关键字。

           ALL:子查询结果所有值

           例:90> ALL (70,80,85) 结果为真

           例:

              # 找出比60部门所有员工工资都高的员工的姓名和工资

              select last_name,salary from employees where salary > ALL (select salary from employees where department_id=60)

          SOME | ANY:子查询结果其中某一个值

           例:75> ANY(70,80,85)结果为真

      

    b、in子查询

    格式:select <字段列表> from <表名> where <字段>  in  <子查询>

    说明:该子查询结果应是一个单列多值的结果集。

    举例: 

      # 查找及格的学生的学号和姓名

      select distinct s_no,s_name from students st where s_no in  (select s_no from score where report>=60)

    c、exists子查询

    格式:select <字段列表> from <表名> where  exists <子查询>

    说明:此内外查询需要通过连接字段关联,这种exists子查询也可通过in子查询来实现。

    举例:

      # 查找及格的学生的学号和姓名

      select distinct s_no,s_name from students st where exists (select * from score sc where report>=60 and st.s_no=sc.s_no)

    

二、数据类型

1、数值型

(1)整数

  tinyint,smallint,mediumint,int,bigint。占用字节数分别为1B、2B、3B、4B、8B。

  如果是无符号整型,在类型后面加unsigned

(2)浮点数和定点数

  a、浮点数

    float(M,D)  #单精度浮点数,M表示数位宽度,D表示精度(保留小数位数)

    double(M,D) #双精度浮点数

  b、定点数

    decimal(M,D) # 定点数

  说明:浮点数型在数据库中存放的是近似值,而定点数类型在数据库中存放的是精确值。

2、字符串

(1)定长字符串

  char(n)   # n表示字符个数,最多为255

(2)变长字符串

  varchar(n)  #n表示最大字符数,最多为65535

(3)text类型

  tinytext # 最多255个字符

  text  #最多65535

  mediumtext  #最多2^24-1个字符

  longtext  #最多2^32-1个字符。

(4)枚举类型

  enum('<值1>','<值2>',...)  # 该类型的取值比较固定,只能单选。

  举例:sex enum('男','女')

(5)集合类型

  set('<值1>','<值2>',...) # 该类型的取值比较固定,可以多选。

  举例:fav set('体育','音乐','游戏')  # fav字段取值可以是'体育,游戏'

3、日期和时间

(1)year

  'YYYY'  # '1901'-'2155'

(2)time

  'hh:mm:ss'

(3)date

  'YYYY-MM-DD'  # '1000-01-01' 到 '9999-12-31'

(4)datetime

  'YYYY-MM-DD hh:mm:ss'  # 年份'1000'-'9999',不支持时区

(5)timestamp

  'YYYY-MM-DD hh:mm:ss'  # 年份'1970'-'2038',支持时区

  TIMESTAMP类型比较特殊,如果定义一个字段的类型为TIMESTAMP,这个字段的时间会在其他字段修改的时候自动刷新。所以这个数据类型的字段可以存放这条记录最后被修改的时间,而不是真正的存放时间。  

 

4、二进制类型

(1)binary和varbinary

  以字节为存储单位,对比char和varchar

(2)blob

  tinyblob,smallblob,mediumblob,longblob

  255B,64KB,16MB,4GB

  以字节为单位,对比text

 

三、DDL--数据库和表的创建

1、管理数据库

概念:数据库是一个容器,里面有表、视图、存储过程等。

(1)创建数据库

基本格式:create database [if not exists] <数据库名> [character set <字符集>]

说明:[]括起来表示可选项,表示根据需要添加。

简单格式:create  database  <数据库名>;

(2)查看数据库

  查看所有数据库:show databases;

  查看创建数据库的脚本:show create database <数据库名>

(3)使用数据库

  格式:use  <数据库名>;

(4)删除数据库

  格式:drop database <数据库名>

 

2、管理表

概念:表是用来存储数据,表是数据库中最重要的一个对象。

(1)创建表

格式1:create  table  [if not exists]  <表名>(

  <字段名>  <字段类型>(宽度) ,

  ...

);

格式2:create table <表名> as <select语句>

说明:根据查询结果创建表

拓展选项:

  auto_increment:

    auto_increment表示自增,即自动编号,只有整型字段才可以设置,一个表只能有一个自增字段。

示例:

create table product(
  id int auto_increment primary key, --auto_increment表示自增,primary key表示主键。
  name varchar(50),
  price float,
  image varchar(255)
);

(2)查看表

  查看表结构:

    desc <表名>

  查看表数据(查询):

    select  *  from <表名>

  查看创建表的脚本:

    show create table <表名>

(3)修改表结构

  基本格式:alter table <表名> ...

  a)增加字段

    格式:alter table <表名> add <字段的定义> [first | after 字段名 ] 

    说明:first和after表示字段添加的位置

  b)删除字段

    alter table <表名> drop <字段名>

  c)修改字段

    alter table <表名> modify <字段的定义> [first | after 字段名 ] 

  d)重命名字段

    alter table <表名> change <旧字段名> <新字段的定义> 

  e)重命名表

    alter table <旧表名> rename to <新表名>

(4)重命名表

   基本格式:rename table <旧表名> to <新表名>

(5)删除表

  基本格式:drop table [if exists]<表名> 

 

四、DML--数据的基本操作:增、删、改 

  1、增(insert)

  (1)指定数据添加记录

    格式:insert | replace into <表名>[(<字段列表>)] values(<值列表>)

    说明:

      replace into :表示如果有该主键的记录,则进行替换;没有的话,则和insert into相同,插入新的一条。

      如果一次要插入多行,则数据行之间用","分隔。

    举例:

      # 一次添加3名学生记录

      insert into student(id,name) values(1,'tom'),(2,'jack'),(3,'rose')

  (2)从查询结果中添加记录

    格式:insert into <表名>[(<字段列表>)] <select语句>

    举例:

      # 将student1表中的全部记录复制到student2表,两表结构一样

      insert into student2 select * from student1

  2、删(delete)

  格式:delete from <表名> where <条件>

  说明:还可以加上order by 子句和limit子句

  举例:delete from score order by maths limit 3; --删除成绩表中数学成绩最低的3行记录。

  3、改(update)

  格式:update <表名> set <字段1>=<值1>,...where <条件>

    说明:可以加上order by 子句和limit子句

 

五、约束(constraint)

1、非空

  not null

  只能位于字段的后面,可以在创建表时指定,也可以在表创建后添加。如果不指定非空约束,该字段默认允许为空。

  举例:

    create table student(id int not null,name varchar(15));  # 创建表时添加非空约束

    alter table student modify name varchar(15) not null;  # 表创建后添加非空约束

2、默认值

  default <值>

  举例:

     create table student(id int not null,name varchar(15),sex char(1) default '男');

3、主键约束

  Primary Key

  主键是用来唯一地表示一个实体,为了防止出现重复的记录,确保实体的完整性

  主键值必须唯一不能为空,一个表只能有一个主键。

  例如:学生(学号,姓名,……)

  (1)在创建表时候创建主键约束

    create table <表名>(

            <字段1> <类型1>  primary key,  --列级约束

            <字段2> <类型2>  ,

            ...

             )

    

    create table <表名>(

            <字段1> <类型1> 

            <字段2> <类型2>  ,

            primay key(<字段1>)  --表级约束

             )

    说明:如果使用复合主键时,只能采用表级约束

  (2)在表创建后添加主键约束

    alter table <表名>  add primary key(<字段名>) 

  (3)删除主键约束

    alter table <表名> drop  primary key

4、唯一约束

  unique

  限制某个字段不要出现重复值,unique字段可以为空,一个表可以有多个唯一约束。

(1)在创建表时候创建唯一约束

    create table <表名>(

            <字段1> <类型1> unique,  --列级约束

            <字段2> <类型2>  ,

            ...

             )

    

    create table <表名>(

            <字段1> <类型1> 

            <字段2> <类型2>  ,

            unique(<字段1>)  --表级约束

             )

(2)在表创建后添加唯一约束

    alter table <表名>  add unique(<字段名>)

 

5、检查约束

  check

  设置某个字段取值范围,确保域的完整性

(1)在创建表时候创建检查约束

    create table <表名>(

            <字段1> <类型1> check(<条件>),  --列级约束

            <字段2> <类型2>  ,

            ...

             )

(2)在表创建后添加检查约束

      alter table <表名>  add check(<条件>)

  MySQL的存储引擎均能对check子句进行分析,但会忽略check子句,即check子句约束还不起作用,MySQL8.0.15以后支持check约束。

6、外键约束

  Foreign Key

    外键不是当前表的主键,是关联表的主键。

  外键的值一定要取自于父表的主键,以保证引用完整性(参照完整性)

   (1)在创建表的时候定义外键约束

    格式:

      create table <表名>(

            <字段1> <类型1> ,

            <字段2> <类型2>  ,

            foreign key(<外键字段>) references <父表>(<主键字段>)  --表级约束

             )

      说明:外键的定义应放在所有字段定义的后面,不能放在某列的定义里面

      举例:

        create table class(class_id int primary key,class_name varchar(20))  # 班级表

        create table student(student_id int,student_name varchar(15),class_id int,foreign key(class_id) references class(class_id));  # 学生表

   (2)在表创建后添加外键约束

      alter table <表名>  add foreign key(<外键字段>) references <父表>(<主键字段>) 

    说明:

      在外键的定义的最后可加上以下几种选项:

      on update cascade  --级联更新,即更新了父表的主键值,子表中对应的外键值也会随之更新。

      on delete cascade   --级联删除,即删除了父表中某主键对应的记录,那么子表中外键值和主键相同的记录也会随之删除。

      on update restrict  --禁止更新,即如果父表中有和外键值相同的主键值,则禁止修改此外键值

      on delete restrict  --禁止删除,即如果父表中有和外键值相同的主键值,则禁止删除该记录

六、视图

  从用户角度看,视图是从特定的角度查看数据库中的数据的窗口,从数据库系统内部看,它是由SELECT语句查询定义的虚拟表。

1、创建视图

格式:CREATE VIEW <视图名> AS <SELECT语句>

作用1:保护数据安全

  隔离或屏蔽数据,对于一些用户无权查看的重要的或隐私的数据,起到了隔离和保护的作用,保证了数据安全。

-- 对60号部门的管理员,只能允许查看本部门的数据,
-- 不能查看其它部门的数据,这样起到数据隔离的作用
CREATE VIEW view_employees_60 
AS
SELECT * FROM employees WHERE department_id=60;

SHOW TABLES; -- 查看视图对象

SELECT * FROM view_employees_60; -- 查看视图数据,准确地说通过视图观察表中的数据

-- 员工的email、phone_number、salary、commission_pct这些是隐私的数据,对普通用户来说,应该屏蔽
CREATE VIEW view_employees_common 
AS
SELECT employee_id,first_name,last_name,department_id FROM employees;

SELECT * FROM view_employees_common;
举例

作用2:简化查询

  对于一些经常使用的复杂的多表连接查询语句,可以使用视图保存这些SQL语句,以后直接查询视图就可以了。

-- 查询每个部门位于的大洲、国家、城市等信息
-- 创建视图
CREATE VIEW view_departments_full
AS
SELECT department_id,department_name,region_name,country_name,city
FROM regions r JOIN countries c
ON r.region_id=c.region_id
JOIN locations l
ON c.country_id=l.country_id
JOIN departments d
ON l.location_id=d.location_id;


SELECT * FROM view_departments_full; -- 查询视图
举例

2、查看视图

SHOW TABLES  -- 查看当前数据库下所有表或视图,视图是虚拟表

DESC <视图名>  -- 查看视图的结构 

SHOW CREATE VIEW <视图名>  -- 查看视图的定义

3、修改视图

格式:ALTER VIEW <视图名> AS <SELECT语句>

4、删除视图

格式:DROP VIEW [IF EXISTS] <视图名>

5、使用视图更新数据

  (1)若视图依赖于一个基本表,则直接通过更新视图来更新基本表的数据。

  (2)若视图依赖于多个基本表,则一次更新(INSERT/UPDATE)只能修改一个基本表的数据,不能同时更新多个基本表的数据。

  (3)若视图依赖于多个基本表,则不能使用DELETE语句。

 

七、索引

  索引(Index)是帮助MySQL高效获取数据的数据结构。

1、索引的分类

  从 功能逻辑 上说,索引主要有 4 种,分别是普通索引、唯一索引(UNIQUE)、主键索引(PRIMARY KEY)、全文索引(FULLTEXT)、空间索引(SPATIAL)。
  按照物理实现方式 ,索引可以分为 2 种:聚簇索引和非聚簇索引。
  按照作用字段个数 进行划分,分成单列索引和联合索引。

2、创建索引

2.1 在创建表时创建索引

格式:

CREATE TABLE <表名>(

  <列1的定义>,

  <列2的定义>,

  ...

  PRIMARY KEY(<字段>),    --主键索引

  UNIQUE INDEX <索引名>(<字段>),   -- 唯一索引

  INDEX <索引名>(<字段>)   -- 普通索引

2.2 在已存在的表上创建索引 

 (1)使用ALTER TABLE创建索引
格式:
ALTER TABLE <表名> 
  ADD PRIMARY KEY(<字段>),   --主键索引
  ADD UNIQUE INDEX <索引名>(<字段>),  -- 唯一索引
  ADD INDEX <索引名>(<字段>)  -- 普通索引

(2)使用CREATE INDEX创建索引

格式:CREATE [UNIQUE] INDEX <索引名> ON <表>(<字段>)

说明:使用UNIQUE创建的是唯一索引,不使用则是创建普通索引,该命令无法创建主键索引

3、查看索引

格式:SHOW INDEX FROM <表名>

4、分析索引

格式:EXPLAIN <SELECT语句>
 
explain结果中的type字段:
  • system:系统表,少量数据,往往不需要进行磁盘 IO
  • const:常量连接,通常是主键等值扫描
  • eq_ref:主键索引 (primary key) 或者非空唯一索引 (unique not null) 等值扫描
  • ref:非主键非唯一索引等值扫描,即普通索引等值扫描
  • range:范围扫描
  • index:索引树扫描
  • ALL:全表扫描 (full table scan)

type 类型从快到慢:system>const>eq_ref>ref>range>index>ALL

5、删除索引

(1) 使用ALTER TABLE删除索引
格式:ALTER TABLE <表名> DROP INDEX <索引名>;
说明:可删除各种索引,包括主键索引,但删除主键索引应该写成:ALTER TABLE <表名> DROP PRIMARY KEY;
(2) 使用DROP INDEX语句删除索引 
格式:DROP INDEX <索引名> ON <表名>;
说明:可删除普通索引和唯一索引等,但不能删除主键索引。
 
 

 八、存储过程和存储函数

(一)、存储过程

  存储过程是将能完成特定功能的SQL语句集,经过编译后存储在数据库中,用户可以通过存储过程的名字来执行它,这样的语句集就称为存储过程。

1、创建存储过程

格式:

  CREATE PROCEDURE <存储过程名>(IN|OUT|INOUT <参数名> <参数类型>,...)

  BEGIN

    存储过程体

  END

说明:

  IN:表示该参数为输入参数,简称入参,IN也可省略。

  OUT:表示该参数为输出参数,简称出参,客户端调用完后,就可以读该参数的返回值。

  INOUT:表示既可以为入参,也可以是出参。

  局部变量的声明:

    格式:DECLARE <变量名> <类型> [DEFAULT <初值>]

    举例:DECLARE n INT DEFAULT 0;  -- 声明整型变量n,初值为0

  变量的赋值:

    格式:SET <变量名>=<值>

    举例:SET n=n+1;

2、查看存储过程

(1)查看创建信息

  SHOW CREATE PROCEDURE <存储过程名>

(2)查看状态信息

  SHOW PROCEDURE STATUS  [LIKE '通配符字符串']

3、调用存储过程

格式:CALL <存储过程名>(<参数>,...)

举例:

  (1)IN模式参数:CALL sp_get_salary(102);

  (2)OUT模式参数:

    SET @max_salary=0;  -- 声明会话变量

    CALL sp_max_salary(@max_salary);  -- 传入会话变量

    SELECT @max_salary;  -- 输出调用后的会话变量

  (3)INOUT模式参数:

    SET @ename='Chen';  -- 声明会话变量,并指定要传入的值

    CALL sp_manager(@ename);  -- 传入会话变量

    SELECT @ename;  -- 输出调用后的会话变量

4、删除存储过程

  DROP PROCEDURE <存储过程名>

(二)、存储函数

  存储函数和存储过程类似,都是对预先编译的SQL语句的封装,不同点是函数必须有返回值。

1、定义存储函数

格式: 

  CREATE FUNCTION <函数名>(<参数名> <参数类型>,...)
  RETURNS <返回值类型>
  BEGIN
    函数体
    RETURN <返回值>;
  END
SELECT函数名(实参列表)
 
举例:
  CREATE FUNCTION avg_salary(d_id INT)
  RETURNS FLOAT
  BEGIN
    DECLARE s FLOAT;
    SELECT AVG(salary) INTO s FROM employees WHERE department_id=d_id;
    RETURN s;
  END
 

2、查看存储函数

(1)查看创建信息
  SHOW CREATE FUNCTION <函数名>;
(2)查看状态信息
  SHOW FUNCTION STATUS [LIKE '通配符字符串']

3、调用存储函数

格式:SELECT <函数名>(<参数>)
举例:SELECT avg_salary(90);
 

4、删除存储函数

  DROP FUNCTION <函数名>
 

 九、变量与流程控制

1、变量

1.1 系统变量

  系统变量是由系统定义的,以'@@'开头,可分为全局系统变量和会话系统变量。

  全局系统变量针对所有的会话(连接)有效,会话系统变量仅针对当前会话有效。

(1)查看系统变量

  查看mysql官方文档

a)查看所有或部分变量

  格式:SHOW [GLOBAL | SESSION] VARIABLES [LIKE  '通配符字符串'];

  举例:SHOW GLOBAL VARIABLES LIKE 'char%'

  说明:GLOBAL表示全局系统变量,SESSION表示会话系统变量,也可省略不写。

b)查看某一个变量

  格式:SELECT @@[GLOBAL | SESSION] .<变量名>

  举例:SELECT @@GLOBAL.max_connections

  说明:如果是会话系统变量,SESSION可省略。

(2)修改系统变量

  格式1:SET @@[GLOBAL | SESSION] .<变量名>=<值>;

  举例:SET @@GLOBAL.auto_commit=0;

  格式2:SET [GLOBAL | SESSION] <变量名>=<值>;

1.2 用户变量

  用户变量是用户自己定义的,可分为会话用户变量和局部变量。

  会话用户变量也是针对当前连接会话有效;局部变量只在BEGIN...END语句块中有效,即通常在存储过程或存储函数中用。

(1)用户变量的定义

a)会话用户变量的定义

  格式:SET @<用户变量>=<值>

  举例:SET @n=0;

  说明:会话变量直接使用,无需声明,变量名前一定要有'@'。

b)局部变量的定义

  格式:DECLARE <变量名> <类型> [DEFAULT <初始值>];

  举例:DECLARE i INT DEFAULT 0;

  说明:若省略[DEFAULT <初始值>],则初始值为NULL。

(2)用户变量的赋值

  方式1:SET [@]<用户变量>=<值>;

  方式2:SELECT <字段或表达式> INTO [@]<用户变量> FROM <表>;

  说明:会话用户变量和局部变量赋值时一样,唯一不同的是会话用户变量名前要加'@'。

(3)用户变量的查看

  格式:SELECT [@]<用户变量>

2、流程控制

 2.1 分支结构

(1)IF分支

 格式:

  IF <条件1>  THEN 语句1;

    [ELSEIF <条件2> THEN 语句2;]

    ……
    [ELSE <语句n>]

  END IF

-- 编程实现判断一个数是正数、负数还是0。
CREATE PROCEDURE test_if(num FLOAT)
BEGIN
    IF num>0 THEN SELECT '正数';
    ELSEIF num=0 THEN SELECT '0';
    ELSE SELECT '负数';
    END IF;
END

CALL test_if(3.25);
举例

(2)CASE分支

格式1: 

  CASE <表达式>
    WHEN <值1> THEN <结果1或语句1>
    WHEN <值2> THEN <结果2或语句2>
    ...
    ELSE <结果n或语句n>
  END [CASE]

说明:

  类似于Java或C中的switch语句。

  如果THEN后面是结果,则不要加分号,如果是语句则需要加分号。

  如果整个CASE分支是放在BEGIN...END中,则分支结尾需要加上CASE,如果放在SELECT后面不需要。

-- 输入四季英文单词,输出相应的中文。
CREATE PROCEDURE test_case1(season VARCHAR(10))
BEGIN
    CASE season
    WHEN 'spring' THEN SELECT '';
    WHEN 'summer' THEN SELECT '';
    WHEN 'autumn' THEN SELECT '';
    WHEN 'winter' THEN SELECT '';
    ELSE SELECT '';
    END CASE;
END

CALL test_case1('summer');
举例

格式2: 

  CASE
    WHEN <条件1> THEN <结果1或语句1>
    WHEN <条件2> THEN <结果2或语句2>
    ...
    ELSE <结果n或语句n>
  END [CASE]

-- 编程实现判断一个数是正数、负数还是0。
CREATE PROCEDURE test_case2(num FLOAT)
BEGIN
    CASE
    WHEN num>0 THEN SELECT '正数';
    WHEN num=0 THEN SELECT '0';
    ELSE SELECT '负数';
    END CASE;
END

CALL test_case2(-32.51);
举例

2.2 循环结构

 (1)LOOP循环

格式:

  [loop_label:]LOOP

    ...

    IF <条件> THEN LEAVE loop_label;

    END IF;

  END LOOP [loop_label];

说明:

  loop_label是循环标签,方便使用LEAVE命令退出该循环。

  <条件>是退出循环的条件。

-- 使用loop循环实现1+2+...+100。
CREATE PROCEDURE test_loop()
BEGIN
    DECLARE i INT DEFAULT 1;
    DECLARE s INT DEFAULT 0;
    loop1:LOOP
        SET s=s+i;
        SET i=i+1;
        IF i>100 THEN LEAVE loop1;
        END IF;
    END LOOP;
    SELECT s;
END

CALL test_loop();
举例

(2)WHILE循环

格式:

  [while_label:]WHILE <条件> DO

    <循环体>

  END WHILE [while_label];

-- 使用while循环实现1+2+...+100。
CREATE PROCEDURE test_while()
BEGIN
    DECLARE i INT DEFAULT 1;
    DECLARE s INT DEFAULT 0;
    WHILE i<=100 DO
        SET s=s+i;
        SET i=i+1;
    END WHILE;
    SELECT s;
END

CALL test_while();
举例

(3)REPEAT循环

格式:

  [repeat_label:]REPEAT

    <循环体>

  UNTIL <循环结束的条件>

  END REPEAT [repeat_label];

-- 使用repeat循环实现1+2+...+100。
CREATE PROCEDURE test_repeat()
BEGIN
    DECLARE i INT DEFAULT 1;
    DECLARE s INT DEFAULT 0;
    REPEAT
        SET s=s+i;
        SET i=i+1;
        UNTIL i>100 -- 此处不能加分号
    END REPEAT;
    SELECT s;
END

CALL test_repeat();
举例

 

十、触发器

  触发器是一种特殊的存储过程,当对数据进行INSERT、UPDATE和DELETE事件时,数据库系统就会自动执行触发器中定义的程序语句,以进行维护数据完整性或其他一些特殊的任务。

1、创建触发器

格式:

CREATE TRIGGER <触发器名>

BEFORE | AFTER   INSERT | DELETE | UPDATE 

ON <表名> FOR EACH ROW

BEGIN

   -- 执行程序的代码

END

 

举例:

 -- 创建一个触发器,当更改表COURSE中某门课的课程号时,同时将SCORE表课程号全部更新。

CREATE TRIGGER CNO_UPDATE

AFTER UPDATE

ON COURSE FOR EACH ROW

BEGIN

  UPDATE SCORE SET c_no=NEW.c_no WHERE c_no=OLD.c_no;

END

说明:

  NEW.<列名>:表示新行的一列

  OLD.<列名>:表示旧行的一列,即更新或删除之前的已有行的列。

测试:  

-- 将course表的c_no由'A001'改为'A011',观察score表的课程号是否自动更新 ?

UPDATE course SET c_no='A011' WHERE c_no='A001';

SELECT * FROM score;

2、查看触发器

(1)SHOW TRIGGERS

(2)SELECT * FROM information_schema.triggers

3、删除触发器

格式:DROP TRIGGER <触发器名>

 

 

 十一、用户和权限

1、创建用户

1.1 使用CREATE USER命令创建用户

格式:CREATE USER <用户名> [IDENTIFIED BY '<密码>']

举例:CREATE USER  'mike'@'localhost'  IDENTIFIED BY '123456'

说明:

  1)<用户名>的格式应该为:'用户名'@'主机名',如果是本地主机,主机名为localhost;如果是非本地的其它任意主机,主机名为'%'。

  2)刚创建的用户是没有任何权限。

  3)密码会自动加密存储。

1.2 向user表添加记录创建用户

格式:INSERT INTO user(host,user,authentication_string) VALUES('<主机名>','<用户名>',password('<密码>'));

举例:INSERT INTO user(host,user,authentication_string) VALUES('localhost','david',password('123456')); 

说明:

  1)这种方式密码不会自动加密,需要使用password()函数手动加密。

  2)这种方式创建的用户,权限不会立即生效,需要使用'FLUSH PRIVILEGES;'命令刷新权限。

  3)如果执行INSERT命令失败,提示ssl_cipher,x509_issuer,x509_subject这几个字段不能为空,可将这几个字段都赋值为0。

2、查看用户

2.1 查看全局权限表user

格式:SELECT * FROM mysql.user

说明:mysql5.7后,密码字段由password变为authentication_string  

2.2、用户登录(命令行)

mysql -u <用户名> -p<密码>  -- 本地登录

mysql -h <主机名或IP>  -u <用户名>  -p<密码> -- 其它主机登录 

3、重命名用户

格式:RENAME USER <旧用户名> TO <新用户名>

举例:RENAME USER 'mike'@'localhost' TO 'michael'@'localhost'

4、修改密码

格式:SET PASSWORD [FOR <用户名>] =password('<新密码>')

举例:SET PASSWORD FOR 'king'@'localhost'=password('queen');

说明:如果省略[FOR <用户名>] 则表示给当前用户修改密码

5、删除用户

5.1 使用DROP USER删除

格式:DROP USER <用户名>

举例:DROP USER mike@localhost

5.2  使用DELETE命令

举例:DELETE FROM user WHERE host='localhost' AND user='mike';

说明:删除记录后,使用'FLUSH PRIVILEGES;'刷新系统权限表

6、权限

  mysql权限信息存储在'mysql'数据库的授权表中。其中,user表是全局权限表;db表是数据库权限表;tables_priv表是表层级权限表;columns_priv表是列层级权限表。

6.1 授权

6.1.1 GRANT授权

格式:GRANT <权限1>,<权限2>,.. ON <数据库>.<表> TO <用户名>  [IDENTIFIED BY '<密码>'] 

举例:GRANT SELECT,UPDATE ON jxgl.students TO mike@localhost

说明:

  1)若<用户名>指定的用户不存在,使用[IDENTIFIED BY '<密码>']时,则可创建该用户并赋予权限。

  2)也可指定具体到某些列权限,如:GRANT UPDATE(s_no,s_name) ON jxgl.students TO peter@localhost

  3)如果授予所有权限,则可使用ALL,如:GRANT  ALL  ON jxgl.* TO peter@localhost  -- *表示所有表 

  4)如果针对所有数据库的所有表(*.*)设置权限,则是全局权限,则权限信息在user表中。 

  5)如果针对某一数据库的所有表(如:jxgl.*)设置权限,则是库级权限,则权限信息在db表中。

  6)如果针对某一数据库的某一表(如:jxgl.students)设置权限,则是表级权限,则权限信息在tables_priv表中。

  7)如果针对某一数据库的某一表的某些列(如:GRANT update(s_no,s_name) on jxgl.students)设置权限,则是列级权限,则权限信息在columns_priv表中。

6.1.2 UPDATE或INSERT更改权限表

举例:授予mike对所有表的SELECT和UPDATE权限

UPDATE user SET Select_priv='Y',Upade_prive='Y' WHERE host='localhost' AND user='mike';

FLUSH PRIVILEGES; -- 刷新权限

6.2 收回权限

格式:REVOKE <权限1>,<权限2>,.. ON <数据库>.<表> FROM  <用户名>

举例:REVOKE UPDATE ON jxgl.students FROM mike@localhost

 十二、事件

定时任务机制,即在指定的时间单元内完成特定的任务。

查看事件调度器是否开启:@@global.event_scheduler

1、创建事件

格式:

CREATE EVENT <事件名>

ON SCHEDULE <时间调度>

DO

BEGIN

  语句;

END

说明:

<时间调度>表示事件何时发生或者每隔多久发生一次。

1)AT <时刻> [+ INTERVAL <n> <时间单位>]

例:AT CURRENT_TIMESTAMP()+INTERVAL 5 MINUTE

2) EVERY <n> <时间单位> [STARTS <起始时间>] [ENDS <终止时间>]

例:EVERY 1 DAY

2、查看事件

格式:

SHOW EVENTS   --查看所有事件

SHOW CREATE EVENT <事件名>  --查看事件的创建信息

3、修改事件

格式:

ALTER EVENT <事件名>

[ON SCHEDULE <时间调度>]

[RENAME TO <新事件名>]

[ENABLE | DISABLE]

举例:

ALTER EVENT e_test DISABLE;  -- 临时关闭事件

4、删除事件

格式:DROP EVENT <事件名>

 

 

 

 

 

 

 
posted @ 2020-04-14 11:27  框框A  阅读(4964)  评论(0编辑  收藏  举报