存储过程(在命令行里执行)

delimiter //
create procedure 存储过程名称(参数列表)
begin
sql语句
end
//
delimiter ;


说明:delimiter用于设置分割符,默认为分号
在“sql语句”部分编写的语句需要以分号结尾,此时回车会直接执行,所以要创建存储过程前需要指定其它符号作为分割符,此处使用//,也可以使用其它字符,输完SQL语句后,需要运行程序再输入//运行
实例
要求:创建存储过程,查询学生信息
1:设置分割符

delimiter //


2:创建存储过程

create procedure proc_stu()
begin
select * from students;
end
//


3:还原分割符

delimiter ;


创建完后在Navicat里的函数可以看见创建的名字,因为用法与自定义函数相似所有存于此
调用
语法如下
call 存储过程(参数列表);
调用存储过程proc_stu
call proc_stu();(意思是调用之前写入的语句,执行之前语句)
存储过程和函数都是为了可重复的执行操作数据库的 sql 语句的集合.
存储过程和函数都是一次编译,就会被缓存起来,下次使用就直接命中缓存中已经编译好的 sql, 不需要重复编译
减少网络交互,减少网络访问流量
用人话说就是,第一次把函数存储到服务器后,第二次开始,只需要call+名字,就可以直接在服务端执行,然后服务端只需要返回结果,而客户端第二次开始只需要发送call+名字几个字就可以实现

视图(不是真实存在的表,是一个select语句,已经存到服务器的语句,使用时可以当成一张表就行,但不能增加删除里面的数据。当一个同样的数据需要很多处多次运行,就需要存成视图的形式。视图可以真正隐藏表的结构,在安全领域里可以隐藏真实数据。)
对于复杂的查询,在多个地方被使用,如果需求发生了改变,需要更改sql语句,则需要在多个地方进行修改,维护起来非常麻烦
解决:定义视图
视图本质就是对查询的封装(所以说视图只能写select语句)
定义视图,建议以v_开头
create view 视图名称 as select语句;
例:创建视图,查询学生对应的成绩信息

create view v_stu_score_course as 
select stu.*,cs.courseNo,cs.name courseName,sc.score from students stu
inner join scores sc on stu.studentNo = sc.studentNo
inner join courses cs on cs.courseNo = sc.courseNo(因为一些表里的字段名称相同,需要起别名,否则报错)


查看视图:查看表会将所有的视图也列出来

show tables;


删除视图
drop view 视图名称;
例:

drop view v_stu_score_course;


使用:视图的用途就是查询

select * from v_stu_score_course;

事务:操作要么都执行,要么都不执行,它是一个不可分割的工作单位,如,银行转帐工作:从一个帐号扣款并使另一个帐号增款,这两个操作要么都执行,要么都不执行。所以,应该把他们看成一个事务。事务是数据库维护数据一致性的单位,在每个事务结束时,都能保持数据一致性【事务里有很多个事件,一个事件失败代表事务失败,事务的意思是要不所有事件成功要么全部失败】
查看表的创建语句,可以看到engine=innodb
show create table students;
修改数据的命令会触发事务,包括insert、update、delete
开启事务,命令如下:
开启事务后执行修改命令,变更会维护到本地缓存中,而不维护到物理表中
begin;
提交事务,命令如下
将缓存中的数据变更维护到物理表中
commit;
回滚事务,命令如下:
放弃缓存中变更的数据
rollback;
未正式commit时,数据存于缓存区,只有操作数据的客户端才能看到数据,另外打开的窗口也看不到,只有commit后数据才会真正修改,如:

begin 
select * from studens;
insert into......
commit;
rollback;(数据有误可以回滚,回滚后begin后的命令都是无效的)

索引(实现原理:B-Tree,树状结构)
查看索引:show index from 表名;
创建索引
方式一:建表时创建索引

create table create_index(
id int primary key,(任何一个表创建时设为了主键,会自动添加成索引,索引字段就叫primary)
name varchar(10) unique,(unique是唯一,跟主键一样,自动创建索引)
age int,
key (age)(这就是索引字段key后面加字段名,手动添加的索引)
);


方式二:对于已经存在的表,添加索引
如果指定字段是字符串,需要指定长度,建议长度与定义字段时的长度一致
字段类型如果不是字符串,可以不填写长度部分
create index 索引名称 on 表名(字段名称(长度))
例:

create index age_index on create_index(age);
create index name_index on create_index(name(10));


删除索引
drop index 索引名称 on 表名;
创建测试表testindex

create table test_index(title varchar(10));


向表中加入十万条数据
创建存储过程proc_test,在存储过程中实现插入数据的操作
1、定义分割符

delimiter //


2、定义存储过程

create procedure proc_test()
begin
declare i int default 0;
while i<100000 do
insert into test_index(title) values(concat('test',i));
set i=i+1;
end while;
end 
//


3、还原分割符

delimiter ;


执行存储过程proc_test

call proc_test();


查询
开启运行时间监测

set profiling=1;


查找第1万条数据test10000

select * from test_index where title='test10000';


查看执行的时间

show profiles;


为表title_index的title列创建索引:

create index title_index on test_index(title(10));


执行查询语句:

select * from test_index where title='test10000';


再次查看执行的时间

show profiles;

缺点
虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行INSERT、UPDATE和DELETE,因为更新表时,MySQL不仅要保存数据,还要保存一下索引文件
但是,在互联网应用中,查询的语句远远大于增删改的语句,甚至可以占到80%~90%,所以也不要太在意,只是在大数据导入时,可以先删除索引,再批量插入数据,最后再添加索引
分析查询(加个explain后,返回的是分析的结果,看key 字段,代表已经运用到索引的功能;rows字段代表可能在查询中搜寻到的数据,越大越效率低)

explain
select * from test_index where title='test10000'