目录
1 数据准备
2 视图(view)
3 MySQL存储过程(procedure)
4.触发器(trigger)
5 DCL
6 数据库备份与还原
1 数据准备
1.创建db3_2数据库。
# 创建db3_2数据库,并指定编码
CREATE DATABASE my_db CHARACTER SET utf8;
2.创建分类表与商品表。
# 创建分类表(一方:主表)
CREATE TABLE category (
cid VARCHAR(32) PRIMARY KEY,
cname VARCHAR(50)
);
# 创建商品表(多方:从表)
CREATE TABLE products(
pid VARCHAR(32) PRIMARY KEY,
pname VARCHAR(50),
price INT,
flag VARCHAR(2), -- 是否上架标记为:1表示上架、0表示下架
category_id VARCHAR(32),
FOREIGN KEY (category_id) REFERENCES category (cid) -- 添加外键约束
);
3.插入相关数据。
# 添加分类数据
INSERT INTO category (cid,cname) VALUES ('c001','家电');
INSERT INTO category (cid,cname) VALUES ('c002','鞋服');
INSERT INTO category (cid,cname) VALUES ('c003','化妆品');
INSERT INTO category (cid,cname) VALUES ('c004','汽车');
# 添加商品数据
INSERT INTO products (pid,pname,price,flag,category_id) VALUES ('p001','小米电视机',5000,'1','c001');
INSERT INTO products (pid,pname,price,flag,category_id) VALUES ('p002','格力空调',3000,'1','c001');
INSERT INTO products (pid,pname,price,flag,category_id) VALUES ('p003','美的冰箱',4500,'1','c001');
INSERT INTO products (pid,pname,price,flag,category_id) VALUES ('p004','篮球鞋',800,'1','c002');
INSERT INTO products (pid,pname,price,flag,category_id) VALUES ('p005','运动裤',200,'1','c002');
INSERT INTO products (pid,pname,price,flag,category_id) VALUES ('p006','T恤',300,'1','c002');
INSERT INTO products (pid,pname,price,flag,category_id) VALUES ('p007','冲锋衣',2000,'1','c002');
INSERT INTO products (pid,pname,price,flag,category_id) VALUES ('p008','神仙水',800,'1','c003');
INSERT INTO products (pid,pname,price,flag,category_id) VALUES ('p009','大宝',200,'1','c003');
2 视图(view)
2.1什么是视图
- 视图是一张虚表(建立在table表的基础之上)
- 首先需要创建一张表,在表的基础上,指定的列映射成一个视图
- 映射:就是一个select语句(过滤掉安全隐患的数据),把它查到的数据作为视图的数据进行映射
- 数据的来源还是对应的table(是视图的基表)
2.2 视图的语法
2.2.1 语法格式
create view 视图名称 as select 语句;
create view 视图名称 e_id,e_user,e_age as select语句;
语法解析:
Create view :表示创建的是视图
as:表示视图要执行的操作(就是表示视图映射表中的数据)
select语句:提供给视图的数据内容
as前面是列名
2.2.2 视图案例
1.创建视图
#查询所有的商品分类详情信息(来自两张表)
CREATE VIEW products_category_view
AS
SELECT * FROM
products p
LEFT JOIN category c
ON p.category_id = c.cid
2.查询视图中的数据
直接将视图作为一张表的名称进行操作,视图只有查询操作,表有增删改操作
1.查询各个分类下商品的平均价格
- 基于表进行操作
SELECT
c.`cname`,
AVG(p.`price`)
FROM
products p LEFT JOIN category c ON p.category_id = c.cid
GROUP BY c.`cname`
- 基于视图完成操作
SELECT
cname,
AVG(price)
FROM products_category_view
GROUP BY cname
2.查询各个鞋服类最贵的商品的所有信息
- 基于表完成
SELECT
*
FROM
products p LEFT JOIN category c ON p.category_id = c.cid
WHERE c.cname = '鞋服' AND
p.price = (
SELECT
MAX(p.price) as '最贵商品'
FROM
products p LEFT JOIN category c ON p.category_id = c.cid
WHERE
c.cname = '鞋服'
)
- 基于视图完成
SELECT * FROM products_category_view pcv WHERE cname = '鞋服'
AND price = (SELECT MAX(price) FROM products_category_view WHERE cname='鞋服')
2.3 视图和表的区别
1.视图建立在表的基础上的,表中存储的是数据, 而视图只是做一个数据的展示。
2.通过视图是不可以做数据的更新操作(例如:删除修改)
3.可以直接删除视图,不会有任何影响;表如果直接删除,数据会永久删除,还会影响基于此表创建的所有视图
2.4视图的作用
1.权限控制时可以使用,让视图只创建某些列
2.简化复杂的多表联查,可以直接在视图里查询
3 MySQL存储过程(procedure)
3.1 什么是存储过程
是数据库里中很复杂,供外部程序调用的一种数据库对象,外部可通过指定存储过程的名字并给定参数来进行调用
3.2 存储过程创建方式
存储过程创建方式:
1.创建无参存储过程
1.语法格式
delimiter $$ -- 表示声明一个存储过程的定义开始
create procedure 存储过程名称() -- 声明当前存储过程的名称
begin -- 表示存储过程内部的SQL语句声明的开始
# 表示将要执行的SQL操作
end $$ -- 表示当声明这个存储过程的定义结束;end:表示存储过程内部SQL语句的声明结束
2.调用方式
call 存储过程名称();
# 简写
call 存储过程名称;
3.案例演示
3.1数据准备
# 商品表
CREATE TABLE goods (
gid INT,
name VARCHAR(20),
num INT -- 库存
);
# 订单表
CREATE TABLE orders (
oid INT,
gid INT,
price INT -- 订单价格
);
# 向商品表中添加3条数据
INSERT INTO goods VALUES(1, '奶茶', 20);
INSERT INTO goods VALUES(2, '绿茶', 100);
INSERT INTO goods VALUES(3, '花茶', 25)
3.2创建存储过程
delimiter $$
create procedure goods_proc()
begin
select * from goods;
end $$
3.3调用存储过程
call goods_proc();
# 简写
call goods_proc;
2.创建有参存储过程
1.语法格式
delimiter $$
create procedure 存储过程名称(IN 参数名称 参数数据类型)
begin
# SQL语句操作
end $$
IN关键字:用来指定当前存储过程可以接收参数列表
参数名称 参数数据类型:在接收参数的时候,存储过程需要指定参数名称和当前参数的类型。
2.调用方式
call 存储过程名称(参数值);
3.案例演示
3.1创建存储过程
delimiter $$
create procedure delete_goodById(IN goods_id int)
begin
delete from goods where gid = goods_id;
end $$
3.2调用存储过程
call delete_goodById(3);
3.创建有参存储过程
IN: 表示接收传递给存储过程的数据
OUT: 表示被修饰的参数返回数据给调用者
1.语法格式
delimiter $$
create procedure 存储过程名称(
IN 参数名称1 参数数据类型1,
IN 参数名称2 参数数据类型2,
....
OUT 参数名称1 参数数据类型1,
....)
begin
# SQL语句操作
# 设置参数值(操作:传递参数、输出参数)
set @参数名称 = 值;
# 返回变量的值
select @参数名称;
end $$
2.案例演示
2.1创建存储过程
delimiter $$
create procedure orders_proc(
in o_oid int,
in o_gid int,
in o_price int,
out out_num int
)
begin
insert into orders values (o_oid,o_gid,o_price);
-- 给输出变量赋值
set @out_num = 10;
-- 将参数返回
select @out_num;
end $$
3.2调用存储过程
call orders_proc(1,2,100,@out_num);
语法:
1.如果存储过程有多个参数列表使用逗号分隔
2.set用来设置变量的,select用来返回变量的值
3.存储过程内部访问变量,需要使用@作为变量的修饰进行访问 (在外部调用存储过程的时候也要带@符号)
- 阿里的代码规范提出了禁用存储过程,维护起来太麻烦了(没有其他意思,自己理解)
4.触发器(trigger)
顾名思义,在触发某些条件之后被执行。这个过程叫做触发器。
4.1触发器的四要素
1.监视地点(table)
2.监听事件(insert/delete/update)
3.触发事件(在条件之前或之后:before\after)
4.触发事件(insert/delete/update)
4.2 创建触发器
1.语法结构
1.1 简单触发器
create trigger
触发器名称 触发器时间 触发事件 ON 监视地点
for each row
目标SQL语句
触发器的执行时间:
- before: 表示在触发时间之前被调用
- after:在触发事件之后调用
1.2 案例演示:
# 定义一个简单的触发器
create TRIGGER
del_trigger after delete on goods
for each row
delete from orders where gid = 2;
#触发条件为在goods表有删除操作
delete from goods where gid = 2;
2.1 复杂触发器
delimiter $
create trigger
触发器名称 触发器时间 触发事件 )ON 表名
for each row
begin
SQL1; # 分号用来唯一的标记一条一条的SQL独立语句
SQL2;
SQL3;
....;
end $
解决方案:使用begin....end来维护多条SQL语句(作为一个SQL集合来看待)。
2.2案例演示
delimiter $$
CREATE TRIGGER
t1 after INSERT ON orders
FOR EACH ROW
BEGIN
UPDATE goods set num = num-1 where gid = 1;
END $$
# 在订单表进行增加事件的时候商品数目减一
INSERT INTO orders values (1,1,15);
4.3触发器操作
1.查询触发器
show triggers;
2.删除触发器:
- 简单的删除触发器:
drop trigger 触发器名称;
- 如果触发器存在则删除:
if(object_id('触发器名称') is not null)
-- 删除触发器
drop trigger 触发器名称
go
4.4触发器的局限性
1.一个表最多只能有三种触发器(insert\delete\update)
2.触发器只能在一张表上
3.视图和临时表不能添加触发器
4.在删除表的时候(truncate table),触发器不会被删除的
4.5 触发器的总结
1.触发器:
CREATE TRIGGER
trigger_name trigger_time trigger_event ON tbl_name
FOR EACH ROW
trigger_stmt
trigger_name
触发器的名称,触发器在当前数据库中必须具有唯一的名称。如果要在某个特定数据库中创建,名称前面应该加上数据库的名称。
tirgger_time
触发时间,取值BEFORE或AFTER。触发器被触发的时刻,表示触发器是在激活它的语句之前或之后触发。若希望验证新数据是否满足条件,则使用BEFORE选项;若希望在激活触发器的语句执行之后完成几个或更多的改变,则通常使用AFTER选项。
trigger_event
触发事件,用于指定激活触发器的语句的种类,取值INSERT、DELETE或UPDATE。
- INSERT:将新行插入表时激活触发器。例如,通过INSERT、LOAD DATA和REPLACE语句。
- DELETE:从表中删除某一行数据时激活触发器,例如,通过DELETE和REPLACE语句。
- UPDATE:更改表中某一行数据时激活触发器,例如,通过UPDATE语句。
FOR EACH ROW
一般是指行级触发,对于受触发事件影响的每一行都要激活触发器的动作。例如,使用INSERT语句向某个表中插入多行数据时,触发器会对每一行数据的插入都执行相应的触发器动作。
注意:每个表都支持INSERT、UPDATE和DELETE的BEFORE与AFTER,因此每个表最多支持6个触发器。每个表的每个事件每次只允许有一个触发器。单一触发器不能与多个事件或多个表关联。
tbl_name
与触发器相关联的表名,此表必须是永久性表,不能将触发器与临时表或视图关联起来。在该表上触发事件发生时才会激活触发器。同一个表不能拥有两个具有相同触发时刻和事件的触发器。例如,对于一张数据表,不能同时有两个BEFORE UPDATE触发器,但可以有一个BEFORE UPDATE触发器和一个BEFORE INSERT触发器,或一个 BEFORE UPDATE 触发器和一个AFTER UPDATE触发器。
trigger_stmt
是当触发程序激活时执行的SQL语句。如果你打算执行多个语句,可使用BEGIN...END复合语句结构。
5 DCL
DCL-数据控制语言(Data Control Lanuage),在SQL语句中,对数据库中的表进行权限的相关控制、数据库做控制、存储过程进行过程、定义函数控制、表的操作控制。。。等控制权限。
两个关键:grant|revoke关键字。
默认的用户root, 超级管理权限。
5.1 创建用户
1.语法格式:
create user 'username'@'host' identified by 'password';
username: 表示创建的普通数据库用户的名称
host: 指定该用户在那个主机上可以登录访问当前的数据。
- localhost: 创建出来的用户只能在本机上访问数据库
- %:创建出来的用户可以在任意主机上访问目标数据
password: 创建的用户访问数据库时对应的密码(可以为空)
2.完成部分的案例:创建不用用户。
5.2 用户权限
创建好的用户(访问数据库的用户),可以添加数据库的访问权限。
5.2.1 语法结构
语法:
grant 权限1,权限2,... on 数据库名.表名 to '用户名'@'主机名称';
解析:
- 权限:create、alter、select、insert、update、delete等。如果要把一个表的访问权限设置最大:all
- on:表示当前的权限作用在那个库中的那个表上。
- to: 表示将以上定义的权限授予那个用户。
5.2.2 查询权限
语法:
show grants for '用户名'@'主机名';
解析:
- GRANT ALL PRIVILEGES ON 表示的是所有权限
- localhost: 表示数据库的主机名称(IP地址)
5.2.3 删除用户
语法:
drop user '用户名'@'主机名称';
注意:
如果在删除对用的数据库用户名,需要保证【主机名称】和创建用户时分配的主机名称保持一致。
6 数据库备份与还原
备份的应用场景,在服务器进行数据传输、数据存储和数据交换,就有可能产生数据故障。比如发生意外停机或存储介质损坏。 这时,如果没有采取数据备份和数据恢复手段与措施,就会导致数据的丢失,造成的损失是无法弥补与估量的。
6.1 Navicat备份与还原
1.Navicat完成数据库的备份。
2.Navicat完成数据库的还原。
6.2 使用命令备份与还原
1.备份:
mysqldump -u用户名称 -p密码 数据库名称 > 文件路径
2.还原:
# 1。通过命令登录数据库
mysql -u用户名 -p密码;
# 2。执行SQL脚本文件
source 目标文件的路径;