返回顶部

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;
语句流程及自定义函数

 

posted on 2021-07-26 14:48  物有本末,事有终始  阅读(117)  评论(0编辑  收藏  举报

导航