MySQL(04)索引&存储过程
视图 view
把结果集创建成视图, 当每次想再利用结果集时可以直接调用
比如之前用到的 左外连接
create view v1 as
SELECT department.department_name,employee.employee_name
from department left join employee
on department.department_id = employee.department_id
之前结果集是无法直接使用的,用一次就要select一次,创建成视图后 可以直接通过 v1 来对该结果集进行处理
比如 select * from v1 就会把结果集再次显示
视图:
用户只关心数据,不用关心表之间的连接操作, (通俗说就是有些表不能全给你看, 我只给出每张表你能看的字段并连接到一起)
视图因为是结果集封装的所以和源表的数据都是相对独立的,只要源表不对视图相关的字段做操作,对视图无影响, 但源表对视图匹配的字段更新时,也要对视图更新
索引 index : 不同的存储引擎对索引的实现是不同的
myisam 和 innodb 存储引擎 支持 btree
memory heap 存储引擎 支持 btree hash
普通索引: 允许定义索引的字段重复和空值
create index 索引名 on 表名(字段1,字段2, ...);
alter table 表名 add index 索引名(字段1,字段2, ...);
drop index 索引名 on 表名;
show index from 表名;
唯一索引: 允许定义索引的字段空值
创建唯一约束时,就会自动创建唯一索引
主键索引: 不允许定义索引的字段重复和空值
创建主键时,就会自动创主键索引, 外键是映射了参考表的主键
全文索引: 查询文本中的关键字, 全文索引只有 myisam引擎 支持 , 只有char varchar 类型能使用全文索引
alter table 表名 add fulltext(字段);
空间索引: 对空间数据类型建立索引
空间数据类型: 一般用作地图的数据存储, 点代表某个地点 线代表道路 面可以表示建筑物
point(点) 0维 multipoint(point集合)
linestring(线) 1维 multilinestring(linestring集合)
( line包含两个point , linestring简单封闭)
polygon(面) 2维 multipolygon(polygon集合)
create table tb_geo ( id int primary key auto_increment, name varchar(64) not null, pt point not null )engine innodb default charset utf8; #创建空间索引 alter table tb_geo add spatial index spaIndex(pt); #插入空间数据类型 #无法以普通的方式插入空间数据需要转换编码格式(有两种, ASCII和二进制流) #以文本(ACSII)的编码格式插入, pointfromtext只能转换点的数据, 而geomfromtext点 线 面 都可转换 insert into tb_geo values(null,'point_a',pointfromtext('point(10 20)')); insert into tb_geo values(null,'point_b',geomfromtext('point(20 20)')); #select * from tb_geo; 无法查询空间数据, 因为表默认是utf8编码格式的, 而插入的是ACSII编码格式的数据 select id,name,astext(pt) from tb_geo; #MySQL5.7不支持二进制流的编码了,当然也不一定非要空间数据类型来存放,字符串也是可以的 (10,20) 只要能读出坐标都行
定义索引, 对数据的 增 删 改 是需要动态维护(由数据库维护)的 降低了数据的维护效率
对于量小, 频繁更新的表避免使用索引, 但对于需要频繁查询的字段应该创建索引
最适合创建索引 的字段是where子句里的字段,而不是select子句的字段 比如
select admin, password, name, ... from admin where admin='abc' and passwod='123' ;
admin 和 password 就该使用索引,因为需要频繁的查询
存储过程 (SQL语句的集合封装成类似函数的方式,方便调用) 和函数
区别 存储过程参数可以用 IN OUT INOUT 没有返回值
函数参数 IN 必须有返回值
delimiter // #因为的语法的缘故,防止编译时存储过程实体提前结束, 要先重定义界定符 #创建存储过程 获取平均花费的最大的用户 #存储过程实现 先分组再获取两组价格的平均值并降序, 获取第一条记录 create procedure GetMaxCustomer() BEGIN select customer,avg(pirce) from orders group by customer order by avg(pirce) desc limit 1; END// #获取指定日期最大的订单 #有参的存储过程, in代表传入参数, 传入日期查询指定日期的最大订单 create procedure GetDateMaxOrder(in odate date) BEGIN select customer,max(pirce) from orders where orders_date = odate; END// #通过存储过程插入数据 create procedure InsertData(in customerdata varchar(20),in pircedata int) begin insert into orders values(null,customerdata,now(),pircedata); select * from orders; end// delimiter ; #改变界定符后会一直关闭当前连接所以要改回来 #调用存储过程 call GetMaxCustomer(); call GetDateMaxOrder('2021-07-25'); call InsertData('猪',2000); #删除存储过程 drop procedure GetMaxCustomer; drop procedure GetDateMaxOrder; drop procedure InsertData;
流程控制
变量:
delimiter // create procedure mysum(in a int,in b int) begin declare m_sum int default 0; set m_sum = a+b; select m_sum as 'sum'; end// delimiter ; call mysum(10,20); drop procedure mysum;
set @a=10; set @b=20; set @c=@a+@b; select @c;
会话变量和全局变量 都是系统定义和设置好默认值的变量
show session variables; 生命周期, 当前连接有效
show global variables; 当前服务有效
delimiter // #if语句 create procedure testif(in x int) BEGIN if x > 10 THEN select '大于10'; elseif x=10 THEN select '等于10'; else select '小于10'; end if; END// #case语句 create procedure testcase(in x int) BEGIN case x/10 when 10 then select 'A'; when 9 then select 'B'; when 8 then select 'C'; else select 'D'; end case; END// #while循环语句 create procedure testwhile(out sum int) BEGIN declare i int default 1; declare s int default 0; while i<=10 DO set s=s+i; set i=i+1; end WHILE; set sum=s; END// #iloop循环语句 无限循环,设置好退出条件 create procedure testloop() BEGIN declare i int default 0; m_name:LOOP set i=i+1; if i=10 THEN leave m_name; end if; end loop; select i; END// #repeat 循环语句 类似 do while 先执行再判断 create procedure testrepeat() BEGIN declare i int default 0; repeat set i=i+1; until i=10 end repeat; select i; END// #循环语句还有有一个关键字 iterate ,和 continue 一样 退出当前循环,执行下一轮循环 delimiter; #自定义函数 create function GetGrade(mark int) returns varchar(10) BEGIN return ( #floor取整 case floor(mark/10) when 10 then 'A' when 9 then 'B' when 8 then 'C' else '不及格' end); END; call testif(7); call testcase(80); call testwhile(@s); select @s; call testloop(); call testrepeat(); select GetGrade(88); drop procedure testif; drop procedure testcase; drop procedure testwhile; drop procedure testloop; drop procedure testrepeat; drop function GetGrade;