1、存储过程procedure
(1)概念
存储过程是数据库中的一个对象,存储在服务端,用来封装多条SQL语句且带有逻辑性,可以实现一个功能,由于他在创建时,就已经对SQL进行了编译,所以执行效率高,而且可以重复调用,类似于Java中的方法。
(2)使用
语法
DELIMITER $$
CREATE
PROCEDURE 数据库名.存储过程名(参数)
BEGIN
-- SQL语句
END$$
DELIMITER ;
参数
- in:输入参数
- out:输出参数
- inout:输入输出参数
变量
全局变量:可以在多个会话中去访问他。
show variables --查看所有全局变量
select @@变量名 -- 查看某个全局变量
SET character_set_client=gbk –- 设置数据库编码
SELECT @@character_set_client -- 查看数据库编码
会话变量:只存在于当前客户端与数据库服务端的一次连接当中,如果连接断开,那么会话变量全部丢失。
set @变量=值 -- 定义会话变量
select @变量 -- 查看会话变量
局部变量:在存储过程中使用的变量就叫局部变量,只要存储过程执行完毕,局部变量就丢失。
declare i int default 1;-- 定义局部变量的语法
set i=10;-- 给变量设置值
存储过程的操作
- 调用:call 存储过程名(参数);
- 删除:drop procedure 存储过程名;
- 查看所有存储状态:show procedure status\G;
- 查看创建存储过程的语句:show create procedure 存储过程名字\G;
(3)案例演示
if逻辑的存储过程
DELIMITER $$
CREATE
PROCEDURE `mytest2`.`procedure1`(IN num INT,OUT str VARCHAR(10))
BEGIN
IF num=1 THEN
SET str='星期一';
ELSEIF num=2 THEN
SET str='星期二';
ELSE
SET str='输入错误';
END IF;-- 结束if 要有条件
END$$
DELIMITER ;
-- CALL procedure1(1,@str);
-- SELECT @str;
带有循环的存储过程while do
-- 求1-100的和
DELIMITER $$
CREATE
PROCEDURE `mytest2`.`procedure2`(IN num INT,OUT result INT)
BEGIN
-- 定义一个局部变量
DECLARE i INT DEFAULT 1;
DECLARE sum1 INT DEFAULT 0;
WHILE i<=num DO
SET sum1=sum1+i;
SET i=i+1;
END WHILE;-- 结束循环
SET result=sum1;
END$$
-- CALL procedure2(100,@sum);
-- SELECT @sum;
2、触发器Trigger
(1)概念
触发器:数据库中的一个对象,相当于JS中的监听器,触发器可以监听增删改三个动作。
例如:监听一个表,当这个表中的数据发生了改变,就会触发这个触发器,在另一个表中记录日志。
(2)语法
DELIMITER $$
CREATE
TRIGGER `mytestdb`.`myTriger` BEFORE/AFTER INSERT/UPDATE/DELETE ON 数据库名.触发器名
FOR EACH ROW -- 行级触发 每操作一行就触发
BEGIN
-- 语句
END$$
DELIMITER ;
(3)案例演示
删除数据时添加记录
-- 建表
CREATE TABLE `demo` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(10) NOT NULL,
`sex` char(2) NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `logger` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`msg` varchar(20) NOT NULL,
`time` datetime NOT NULL,
PRIMARY KEY (`id`)
) ;
-- 删除demo表中的一行数据时,在日志表中logger添加一条记录
DELIMITER $$
CREATE
TRIGGER `mytest2`.`trigger` AFTER DELETE ON `mytest2`.`demo`
FOR EACH ROW BEGIN
INSERT INTO logger VALUES(NULL,'你删除了一条数据',NOW());
END$$
DELIMITER ;
修改一个表中的数据,另一个表中也要修改,会利用到两个字段。
- old:可以获取被监听的表中的字段的旧值。
- new:可以获取到被监听表中更新后的字段的新值。
-- 创建表
CREATE TABLE `demo1` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`username` VARCHAR(10) NOT NULL,
`sex` CHAR(2) NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `demo2` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`username` VARCHAR(10) NOT NULL,
`sex` CHAR(2) NOT NULL,
PRIMARY KEY (`id`)
);
-- 往demo1中添加一条数据,另一张表demo2中也要添加一条同样的数据
DELIMITER $$
CREATE
TRIGGER `mytest2`.`trigger1` AFTER INSERT ON `mytest2`.`demo1`
FOR EACH ROW BEGIN
INSERT INTO demo2 VALUES(new.id,new.username,new.sex);
END$$
DELIMITER ;
-- 修改demo1中的数据 demo2中的数据也要改
DELIMITER $$
CREATE
TRIGGER `mytest2`.`trigger2` AFTER UPDATE ON `mytest2`.`demo1`
FOR EACH ROW BEGIN
UPDATE demo2 SET id=new.id,username=new.username,sex=new.sex WHERE id=old.id;
END$$
DELIMITER ;
3、视图
(1)概念
视图:是一种由结构(行,列),但没有结果(结构中不真实存储数据)的虚拟的表。
注意:虚拟表的结构来源不是自己定义,而是从对应的基表中产生。
(2)视图操作
-- 创建
create view 视图名称 as select查询语句;
-- 查看
show create view 视图名;
-- 删除
drop view 视图名;
-- 修改视图
alter view 视图名 as 新的select语句;
注意:MySQL中的视图不支持封装子查询查出来的数据。
(3)案例演示
CREATE TABLE `demo1` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`username` VARCHAR(10) NOT NULL,
`sex` CHAR(2) NOT NULL,
PRIMARY KEY (`id`)
);
CREATE VIEW view1 AS SELECT *FROM demo1;
(4)视图的意义
- 视图可以节省SQL语句,将一条复杂的查询语句,使用视图进行保存,以后可以直接对视图进行操作。
- 数据安全,视图操作注意是针对查询语句的,如果对视图结构进行处理(比如删除),不会影响基表的数据,所以相对来说数据比较安全。
- 视图往往是在大项目中去使用,而且是多系统中去使用,我可以对外提供一些有用的数据,隐藏一些关键的数据。
- 视图对外可以提供友好的数据:不同的视图提供不同的数据,对外提供的数据好像是经过专门设计的一样。
- 视图可以更好的进行权限控制,比如对外隐藏我的一些基表的名称。
4、函数
函数:内置函数和自定义函数
(1)函数和存储过程的区别
- 存储过程没有返回值,函数必须要有返回值。但是存储过程可以用out能实现返回值这个作用。
- 存储过程有in out inout 这几个参数类型 函数的参数全是用来收实参。
(2)语法
-- 自定义函数
DELIMITER $$
CREATE
FUNCTION 数据库名.函数名(参数 参数类型)
RETURNS INT
BEGIN
-- 逻辑代码
END$$
DELIMITER ;
-- 调用
select 函数名();
(3)案例演示
自定义函数
-- 加这一行是为了解决This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA 。。。这个问题
SET GLOBAL log_bin_trust_function_creators=TRUE;
DELIMITER $$
CREATE
FUNCTION `mytest2`.`funct`(num INT)
RETURNS INT
BEGIN
DECLARE i INT DEFAULT 100;
SET i=i+num;
RETURN i;
END$$
DELIMITER;
-- SELECT funct(100);调用
内置函数
-- 1.获取系统日期
SELECT NOW();
-- 2.格式化日期
SELECT DATE_FORMAT(NOW(),'%Y-%M-%D');-- 2020-April-6th
SELECT DATE_FORMAT(NOW(),'%y-%m-%d');-- 20-04-06
-- 3.sysdate 在函数执行时动态得到值
SELECT SYSDATE();
-- 4.获取当前日期
SELECT CURDATE();-- 2020-04-06
5、三大范式
数据库的设计原则:尽量遵守三大范式。
(1)第一范式
要求表的每个字段必须是不可分割的独立单元。
student:name 张小凡|狗蛋 -- 违反第一范式
student:name 张小凡 old_name 狗娃 -- 符合第一范式
(2)第二范式
在第一范式的基础上,要求每张表只表达一个意思,表的每个字段都和表的主键有关系。
employee:员工编号 员工姓名 部门名称 订单名称 -- 违反第二范式
员工表:员工编号 员工姓名 部门名称
订单表:订单编号 订单名称 -- 符合第二范式
(3)第三范式
在第二范式基础,要求每张表的主键之外的其他字段都只能和主键有直接决定依赖关系。
员工表: 员工编号(主键) 员工姓名 部门编号 部门名 --符合第二范式,违反第三范式 (数据冗余高)
员工表:员工编号(主键) 员工姓名 部门编号 --符合第三范式(降低数据冗余)
部门表:部门编号 部门名
6、索引
(1)索引简介
索引在MySQL中也叫做’键 key’,是存处引擎用于快速找到记录的一种数据结构。索引对于良好的性能非常关键,尤其是当表中的数据越来越多,索引对于性能的影响愈发重要。索引优化应该是对查询性能优化的最有效手段了,索引能够轻易将查询性能提高好几个数量级。索引相当于新华字典的音序表,如果要查某个汉字,不使用音序表,则需要从几百页中的数据中去找找个汉字。简单理解就是,索引就像一本书的目录,让你很快能够查询到你想要的数据。
(2)分类
- 普通索引
- 唯一索引
- 全文索引
- 单列索引
- 多列索引
- 空间索引
注意:在MySQL 5.6版本以前。只有MyISAM存储引擎支持全文引擎。在5.6版本中,InnoDB加入了对全文索引的支持,但是不支持中文全文索引。在5.7.6版本,MySQL内置了ngram全文解析器,用来支持亚洲语种的分词。
(3)创建索引
方式1:创建表的时候创建索引
create table student(
sid int,
sname varchar(32),
index(sname) -- 给name 字段建立普通索引 注意字段不要带引号
)
方式2:表创建好时候,再去创建索引
创建普通索引例子
create index myIndex on student (sname);
方式3:表已创建,通过alter table语句创建
创建普通索引的例子
alter table student add index MyIndex(sname);
(4)管理索引
查看索引
show create table 表名\G;
删除索引
drop index 索引名 on 表名;
测试索引是否提高了效率
explain select * from student where sid=19999;
explain select * from test where id=19999;
注意:你在建表的时候,如果有主键,这个主键就带有所有主键索引。