Mysql(三)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: Mysql(三)

存储


1.创建语法

create procedure 存储过程名(参数列表)
begin 
     存储过程体(一组合法的sql语句)
end


注意:


①.参数列表包括三部分 参数模式 参数名 参数类型

eg:in stuname varchar(20)

参数模式:

in:该参数可以作为输入,也就是改参数需要调用方法传入值

out: 该参数可以作为输出,也就是改参数可以作为返回值

inout:该参数既可以作为输入又可以作为输出,也就是该参数既需要传入值,也可以返回值


②如果存储过程体仅仅只有一句话,begin end可以省略,存储过程中的每条sql语句要求必须要加分号;存储过程的结尾可以使用delimiter


语法:

delimiter 结束标记 -->delimiter $

注意:delimiter的作用


其实就是告诉mysql解释器,该段命令是否已经结束了,mysql是否可以执行了。默认情况下,delimiter是分号;。在命令行客户端中,如果有一行命令以分号结束,那么回车后,mysql将会执行该命令。


如输入下面的语句mysql> select * from test_table;然后回车,那么MySQL将立即执行该语句。但有时候,不希望MySQL这么做。在为可能输入较多的语句,且语句中包含有分号。


2.调用:call 存储过程名(实参列表)


input


#案列1:创建存储过程实现 根据女神名,查询对应的男神信息
create procedure my2(in beautyName VARCHAR(20))
begin 
     select bo.* 
     from boys bo
     right join 
     beauty b 
on bo.id=b.boyfriend_id  
where b.name=beautyName;
end $
#调用
call my4('柳岩')$
create table if not exists user(
    id int primary key auto_increment,
    username varchar(20),
    password varchar(20)
);
insert into user values(1,'xiaozhi','123'),(2,'xiaoxing','123');
#比较是否登录成功
delimiter $
create procedure my7(in username varchar(20),in password varchar(20))
begin 
    declare result int DEFAULT 0;#声明局部变量
   select count(*) into result
   from user 
   where USER.username=username
   and USER.password=password; 
   select if(result>0,'成功','失败');#调用局部变量
end $
#调用
call my6('xiaozhi','123')$

20190318133514115.png


3.带out模式的存储过程

#3.创建带out模式的存储过程
#根据女神名,返回对应的男神名
delimiter $
create procedure cc1(in beautyName varchar(20),out boysName varchar(20))
BEGIN
     select bo.boyName into boysName
     from boys bo
     inner join beauty b 
     on bo.id=b.boyfriend_id
     where b.`name`=beautyName;
end $
#调用
set @bname$
call cc1('小昭',@bname)$
select @bname$

20190319133913137.png


#案列2:根据女神名,返回对应的男神名和男神魅力值'
delimiter $
create procedure cc2(in beautyName varchar(20),out boysName varchar(20),out userCP int)
BEGIN
 select bo.boyName,bo.userCP into boysName,userCP
     from boys bo
     inner join beauty b 
     on bo.id=b.boyfriend_id
     where b.`name`=beautyName;
end $
#调用
call cc2('小昭',@bName,@usercp)$
select @bName,@usercp$


20190319134555604.png


4.创建带inout模式参数的存储过程


#案例一 传入a和b两个值,最终a和b都翻倍返回
create procedure cc3(inout a int,inout b int)
begin 
     set a =a*2;
     set b=b*2;
end $
set @m=10$
set @n=20$
call cc3(@m,@n)$
select @m,@n$

20190319135132670.png


5.存储过程的删除


语法:drop procedure 存储过程名;

注意:一次只能删除一个


drop procedure cc3;


20190319135754438.png


函数


1.函数与存储的区别


存储过程:可以有0个返回,也可以有多个返回,适合做批量的插入,批量的更新

函数:有且仅有一个返回,适合做处理数据后返回一个结果

2.创建语法[掌握]

create function 函数名(参数列表) returns 返回类型
begin
        函数体
end

3.注意:


①参数列表 包括两部分:参数名,参数类型


②函数体:肯定会有return语句,如果没有会报错


③如果return语句没有放在函数体的最后也不会报错,不建议


④函数体中仅有一句话,则可以省略begin end


⑤使用delimiter语句设置结束标志

4.调用select 函数名(参数列表)[掌握]


案列:无参有返回的

#案例:返回公司的员工个数
delimiter $
create function myf1() returns int
begin
     declare c int default 0;#定义变量
     select count(*) into c
     from employees;
     return c;
end $
select myf1()$

20190320102823620.png

有参有返回

#案列1: 根据员工名返回工资
desc employees;
select * from employees;
create function myf4(empName varchar(20)) returns double
begin
    set @sal=0;#定义用户变量
    select salary into @sal
    from employees
    where last_name=empName;
    return @sal;
end $
select myf4('Hunold')$

20190320104004170.png


根据部门名,返回该部门的平均工资


#根据部门名,返回该部门的平均工资
desc departments;
select * from departments;
create function myf5(employeesName varchar(20)) returns double
begin
     declare sal double;
     select avg(salary) into sal
     from employees e
     inner join departments d
     on e.department_id=d.department_id
     where d.department_name=employeesName;
     return sal;
end $
select myf5('Adm')$

2019032010510754.png


5.查看函数:show create function myf3;


6.删除函数:drop function myf3;


存储和函数习题


#一、创建存储过程实现传入用户名和密码,插入到admin表中
desc admin;
delimiter $
create procedure ccp1(in usernamec varchar(10),in password varchar(10))
begin
     insert into admin(username,password) values(usernamec,password);
end $
call ccp1('aaa','aaa')$
select * from admin$
show create PROCEDURE ccp1;
#二、创建存储过程实现传入女神编号,返回女神名称和女神电话
desc beauty;
select * from beauty;
create procedure ccp2(in id int,out name varchar(20),out  phone varchar(20))
begin 
     select b.name,b.phone into name,phone
     from beauty b
     where b.id=id;
end $
call ccp2(1,@gname,@gphone)$
drop PROCEDURE ccp2$
#三、创建存储存储过程或函数实现传入两个女神生日,返回大小
#DATEDIFF(expr1,expr2):返回两个日期之间的时间,expr2-expr1
desc beauty $
select * from beauty;
CREATE PROCEDURE test_pro3(IN birth1 DATETIME,IN birth2 DATETIME,OUT result INT)
BEGIN
  SELECT DATEDIFF(birth1,birth2) INTO result;
END $
call test_pro3('1999-02-03',NOW(),@result)$


流程控制结构


顺序结构:程序从上往下依次执行

分支结构:程序从两条或多条路径中选择一条去执行

循环结构:程序在满足一定条件的基础上,重复执行一段代码


顺序结构


①if函数:实现简单的双分支


语法:select if(表达式1,表达式2,表达式3)


如果表达式1成立,则IF 函数返回表达式2的值,否则返回表达式3的值


②case结构


情况1:类似于java中农的switch语句,一般用于实现等值的判断


语法:

case 变量|表达式|字段

when 要判断的值 then 返回的值1 或语句

when 要判断的值 then 返回的值2 或语句

else 要返回的值n 或语句n

end case


情况2:类似于java中的多重if语句,一般用于实现区间判断


语法

case

when 要判断的条件1 then 返回的值1

when 要判断的条件1 then 返回的值2

else 要返回的值n


end


20190321095325418.png


20190321095342403.png


特点:


①可以作为表达式,嵌套在其他语句中使用,可以放在任何地方,begin end中或begin end外面


②可以作为独立的语句去使用,只能放在begin end中


#创建存储过程,根据传入的成绩,来显示等级,比如传入成绩:90-100,显示A 
#80-90 显示B 60-80,显示C  否则 显示D
delimiter $
create procedure cc_case1(in score int)
begin
     case  
     when score >90 and socre<100 then select 'A';
     when score >80 then select 'B';
     when score >60 then select 'C';
     else select 'D';
     end case;
end $

数据库的设置


1. 多表之间的关系

20190803203800843.png


1>. 分类


一对一(了解):人和身份证

一个人只有一个身份证,一个身份证只能对应一个人


一对多、多对一(掌握)部门和员工

一个部门有多个员工

一个员工只能对应一个部门


多对多:学生和课程

一个学生可以选择很多门课程

一个课程也可以被很多学生选择


2>. 一对一


一对一关系实现,可以在任意一方添加唯一外键指向另一方的主键

一对一可以把两张表合成一张表

20190803201946240.png


3>. 一对多(多对一)

实现方式:在多的一方建立外键,指向一的一方的主键 [ 如:部门和员工 ]

20190803200330687.png

4>. 多对多

多对多关系实现需要借助第三张中间表。中间表至少包含两个字段,这两个字段作为第三张表的外键,分别指向两张表的主键

20190803201252484.png

2. 数据库设置的范式

          -- 创建旅游线路分类表 tab_category
      -- cid 旅游线路分类主键,自动增长
      -- cname 旅游线路分类名称非空,唯一,字符串 100
      CREATE TABLE tab_category (
        cid INT PRIMARY KEY AUTO_INCREMENT,
        cname VARCHAR(100) NOT NULL UNIQUE
      );
      -- 创建旅游线路表 tab_route
      /*
      rid 旅游线路主键,自动增长
      rname 旅游线路名称非空,唯一,字符串 100
      price 价格
      rdate 上架时间,日期类型
      cid 外键,所属分类
      */
      CREATE TABLE tab_route(
        rid INT PRIMARY KEY AUTO_INCREMENT,
        rname VARCHAR(100) NOT NULL UNIQUE,
        price DOUBLE,
        rdate DATE,
        cid INT,
        FOREIGN KEY (cid) REFERENCES tab_category(cid)
      );
      /*创建用户表 tab_user
      uid 用户主键,自增长
      username 用户名长度 100,唯一,非空
      password 密码长度 30,非空
      name 真实姓名长度 100
      birthday 生日
      sex 性别,定长字符串 1
      telephone 手机号,字符串 11
      email 邮箱,字符串长度 100
      */
      CREATE TABLE tab_user (
        uid INT PRIMARY KEY AUTO_INCREMENT,
        username VARCHAR(100) UNIQUE NOT NULL,
        PASSWORD VARCHAR(30) NOT NULL,
        NAME VARCHAR(100),
        birthday DATE,
        sex CHAR(1) DEFAULT '男',
        telephone VARCHAR(11),
        email VARCHAR(100)
      );
      /*
      创建收藏表 tab_favorite
      rid 旅游线路 id,外键
      date 收藏时间
      uid 用户 id,外键
      rid 和 uid 不能重复,设置复合主键,同一个用户不能收藏同一个线路两次
      */
      CREATE TABLE tab_favorite (
        rid INT, -- 线路id
        DATE DATETIME,
        uid INT, -- 用户id
        -- 创建复合主键
        PRIMARY KEY(rid,uid), -- 联合主键
        FOREIGN KEY (rid) REFERENCES tab_route(rid),
        FOREIGN KEY(uid) REFERENCES tab_user(uid)
      );

20190803203619733.png

20190803203306751.png


3. 数据库设置的范式


1>. 范式的概念


设置数据库时,需要遵循一些规范。要遵循后边的范式要求,必须先遵循前边的所有范式要求


设计关系数据时,遵从不同的范式要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小(重复少)


目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式、第四范式(4NF)、第五范式(5NF,又称完美范式)


2>. 分类


这部分内容了解知道即可

20190804212030661.png


第一范式(1NF):每一列都是不可分割的原子数据项

2019080421134362.png

第二范式(2NF):在1NF的基础上,非码属性必须完全依赖于码(在1NF基础上消除非主属性对主码的部分函数依赖)


几个概念:


1. 函数依赖:A–>B,如果通过A属性(属性组)的值,可以确定唯一B属性的值。则称B依赖于A例如:学号–>姓名。 (学号,课程名称) --> 分数


2. 完全函数依赖:A–>B, 如果A是一个属性组,则B属性值得确定需要依赖于A属性组中所有的属性值。例如:(学号,课程名称) --> 分数


3. 部分函数依赖:A–>B, 如果A是一个属性组,则B属性值得确定只需要依赖于A属性组中某一些值即可。例如:(学号,课程名称) – > 姓名


4. 传递函数依赖:A–>B, B – >C . 如果通过A属性(属性组)的值,可以确定唯一B属性的值,在通过B属性(属性组)的值可以确定唯一C属性的值,则称 C 传递函数依赖于A

例如:学号–>系名,系名–>系主任


5. 码:如果在一张表中,一个属性或属性组,被其他所有属性所完全依赖,则称这个属性(属性组)为该表的码例如:该表中码为:(学号,课程名称)


* 主属性:码属性组中的所有属性

* 非主属性:除过码属性组的属性

20190804212008795.png

第三范式(3NF):在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)

20190804212331456.png



相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
4月前
|
SQL 关系型数据库 MySQL
MySQL
MySQL
28 1
|
关系型数据库 MySQL Linux
mysql 如何 才是真正的mysql
mysql 如何 才是真正的mysql
48 0
|
SQL 算法 关系型数据库
|
关系型数据库 MySQL
MySQL小总结
mysql基本操作 增删改查
|
存储 SQL 缓存
初识MySQL
什么是MySQL,如何安装MySQL的使用环境以及简单的库操作
|
SQL 存储 Oracle
MySQL总结
一.SQL语句简介 1.什么是SQL? SQL(Structured Query Language):结构化查询语言 其实就是定义了操作所有关系型数据库的规则。每一种数据库操作的方式存在不一样的地方,称为“方言”
131 0
MySQL总结
|
SQL JSON Oracle
MySQL 8.0来了,逆之者亡...
MySQL 8.0来了,逆之者亡...
190 0
MySQL 8.0来了,逆之者亡...
|
存储 关系型数据库 MySQL
【MySQL】MySQL知识总结
【MySQL】MySQL知识总结
1026 0
【MySQL】MySQL知识总结
|
SQL Oracle 关系型数据库