• MySQL进阶


    1.视图

    概述:视图就相当于一个临时表,但是只定义了对应关系,用这个视图的时候,就会自行执行视图里定义好的sql语句,视图是只能去查原表的数据,不能去修改原表里面的数据的;

    视图的增删改查:

    1.创建视图:

    语法:CREATE VIEW 视图名称 AS SQL语句

    示例:

    CREATE VIEW v1 AS 
    SELECT nid, name FROM user
    WHERE nid > 3;
    

    2.删除视图:

    语法:DROP 视图名称

    3.修改视图

    语法:ALTER VIEW 视图名称 AS sQL语句

    示例:

    ALTER VIEW v1 AS 
    SELECT sex, birthday FROM user
    WHERE nid > 1
    

    4.使用视图:

    示例:

    select nid, name from v1;
    

    2.触发器

    概述:对某个表进行【增/删/改】操作的前后如果希望触发某个特定的行为时,可以使用触发器,触发器用于定制用户对表的行进行【增/删/改】前后的行为。

    触发器的创建

    # 插入前
    CREATE TRIGGER tri_before_insert_tb1 BEFORE INSERT ON tb1 FOR EACH ROW
    BEGIN
        ...
    END
    
    # 插入后
    CREATE TRIGGER tri_after_insert_tb1 AFTER INSERT ON tb1 FOR EACH ROW
    BEGIN
        ...
    END
    
    # 删除前
    CREATE TRIGGER tri_before_delete_tb1 BEFORE DELETE ON tb1 FOR EACH ROW
    BEGIN
        ...
    END
    
    # 删除后
    CREATE TRIGGER tri_after_delete_tb1 AFTER DELETE ON tb1 FOR EACH ROW
    BEGIN
        ...
    END
    
    # 更新前
    CREATE TRIGGER tri_before_update_tb1 BEFORE UPDATE ON tb1 FOR EACH ROW
    BEGIN
        ...
    END
    
    # 更新后
    CREATE TRIGGER tri_after_update_tb1 AFTER UPDATE ON tb1 FOR EACH ROW
    BEGIN
        ...
    END
    

    示例1:

    delimiter //
    CREATE TRIGGER tri_before_insert_tb1 BEFORE INSERT ON tb1 FOR EACH ROW
    BEGIN
    
    IF NEW. NAME == 'alex' THEN
        INSERT INTO tb2 (NAME)
    VALUES
        ('aa')
    END
    END//
    delimiter ;
    

    示例2:

    delimiter //
    CREATE TRIGGER tri_before_insert_tb1 BEFORE INSERT ON tb1 FOR EACH ROW
    BEGIN
    
    IF NEW. NAME == 'alex' THEN
        INSERT INTO tb2 (NAME)
    VALUES
        ('aa')
    END
    END//
    delimiter ;
    

    注意:delimiter // 把默认以“;”作为结束符改为了以//作为结束符,NEW表示即将插入的数据行,OLD表示即将被删除的数据行

    触发器的删除

    语法:DROP TRIGGER 触发器的名称;

    使用触发器

    触发器无法由用户直接调用,而知由于对表的【增/删/改】操作被动引发的

    3.存储过程

    概述:存储过程是一个SQL语句集合,当主动去调用存储过程时,其中内部的SQL语句会按照逻辑执行

    创建存储过程

    1.无参数的存储过程

    示例:

    -- 创建存储过程
    
    delimiter //
    create procedure p1()
    BEGIN
        select * from t1;
    END//
    delimiter ;
    
    
    
    -- 执行存储过程
    
    call p1()
    

    2.有参数的存储过程

    对于存储过程,可以接收三类参数:

    • in:仅用于传入参数用
    • out:仅用于返回值用
    • inout:既可以传入又可以当作返回值

    创建有参数的存储过程示例:

    -- 创建存储过程
    delimiter \
    create procedure p1(
        in i1 int,
        in i2 int,
        inout i3 int,
        out r1 int
    )
    BEGIN
        DECLARE temp1 int;
        DECLARE temp2 int default 0;
        
        set temp1 = 1;
    
        set r1 = i1 + i2 + temp1 + temp2;
        
        set i3 = i3 + 100;
    
    end\
    delimiter ;
    
    -- 执行存储过程
    set @t1 =4;
    set @t2 = 0;
    CALL p1 (1, 2 ,@t1, @t2);
    SELECT @t1,@t2;
    

    事务型存储过程示例:

    delimiter \
        create PROCEDURE p1(
            OUT p_return_code tinyint
        )
        BEGIN 
          DECLARE exit handler for sqlexception 
          BEGIN 
            -- ERROR 
            set p_return_code = 1; 
            rollback; 
          END; 
         
          DECLARE exit handler for sqlwarning 
          BEGIN 
            -- WARNING 
            set p_return_code = 2; 
            rollback; 
          END; 
         
          START TRANSACTION; 
            DELETE from tb1;
            insert into tb2(name)values('seven');
          COMMIT; 
         
          -- SUCCESS 
          set p_return_code = 0; 
         
          END\
    delimiter ;
    

    删除存储过程

    drop procedure 存储过程名称

    4.函数

    MySQL中的内置函数

    • INSTR(str, len):返回字符串str从开始的len位置的子序列字符
    • LEFT(str, len):返回字符串str从开始的len位置的子序列字符
    • LOWER(str):变小写
    • UPPER(str):变大写
    • ...

    自定义函数

    1.定义一个函数:

    delimiter \
    create function f1(
        i1 int,
        i2 int)
    returns int
    BEGIN
        declare num int;
        set num = i1 + i2;
        return(num);
    END \
    delimiter ;
    
    -- 执行函数:
    f1(1, 3);
    

    2.删除函数:

    drop function 函数名称
    

    5.事务

    概述:事务用于将某些操作的多个SQL作为原子性操作,一旦有某一个出现错误,即可回滚到原来的状态,从而保证数据库数据完整性

    6.索引

    概述:索引是数据库中专门用于帮助用户快速查询数据的一种数据结构,类似于字典中的目录,查找字典内容时可以根据目录查找找到数据的存放位置,然后直接获取即可

    MySQL中常见索引有:

    1.普通索引:仅有一个功能,那就是加快查询

    • create index 索引名 ob 表名(列名)

    2.唯一索引:加速查询和唯一约束(可为null)

    • create unique index 索引名 on 表名(列名)

    3.主键索引:加速查询和唯一约束(不可为null)

    • alter table 表名 add primary key(列名);

    4.联合索引:将n个列组合成一个索引

    • create index 索引名 on 表名(列名1,列名2。。。);

    联合索引需要注意的点:

    • 联合索引的最左匹配原则,即最左优先,以最左边的为起点任何连续的索引都能匹配上。同时遇到范围查询(>、<、between、like)就会停止匹配。
    • 多字段的联合索引在查询单个字段时是否可以用到索引:如下面的联合索引的语法所示,如果你查询单个字段时,查询的是列名1和列名2或者查询列名1的话,就能命中索引,如果只查询列名2就中不了索引

    索引相关命令

    查看表结构:

    desc 表名
    

    查看生成表的sql

    show create table 表名
    

    查看执行时间:

    set profilling = 1;
    SQL语句...
    show profiles
    

    查看执行计划:

    explain select * from tb2;
    

    执行计划里面type属性的值代表的意思

    type
    查询时的访问方式,性能:all < index < range < index_merge < ref_or_null < ref < eq_ref < system/const
    ALL 全表扫描,对于数据表从头到尾找一遍
    select * from tb1;
    特别的:如果有limit限制,则找到之后就不在继续向下扫描
    select * from tb1 where email = 'seven@live.com'
    select * from tb1 where email = 'seven@live.com' limit 1;
    虽然上述两个语句都会进行全表扫描,第二句使用了limit,则找到一个后就不再继续扫描。

    INDEX           全索引扫描,对索引从头到尾找一遍
                    select nid from tb1;
    
    RANGE          对索引列进行范围查找
                    select *  from tb1 where name < 'alex';
                    PS:
                        between and
                        in
                        >   >=  <   <=  操作
                        注意:!= 和 > 符号
    
    
    INDEX_MERGE     合并索引,使用多个单列索引搜索
                    select *  from tb1 where name = 'alex' or nid in (11,22,33);
    
    REF             根据索引查找一个或多个值
                    select *  from tb1 where name = 'seven';
    
    EQ_REF          连接时使用primary key 或 unique类型
                    select tb2.nid,tb1.name from tb2 left join tb1 on tb2.nid = tb1.nid;
    
    
    
    CONST           常量
                    表最多有一个匹配行,因为仅有一行,在这行的列值可被优化器剩余部分认为是常数,const表很快,因为它们只读取一次。
                    select nid from tb1 where nid = 2 ;
    
    SYSTEM          系统
                    表仅有一行(=系统表)。这是const联接类型的一个特例。
                    select * from (select nid from tb1 where nid = 1) as A;
    

    7.动态执行sql语句

    示例:

    delimiter \
    DROP PROCEDURE IF EXISTS proc_sql \
    CREATE PROCEDURE proc_sql ()
    BEGIN
        declare p1 int;
        set p1 = 11;
        set @p1 = p1;
    
        PREPARE prod FROM 'select * from tb2 where nid > ?';
        EXECUTE prod USING @p1;
        DEALLOCATE prepare prod; 
    
    END\
    delimiter ;
    

    8.如何优化SQL语句

    1.列类型尽量定义成数值类型,且长度尽可能短,如主键和外键,类型字段等等

    2.建立单列索引

    3.根据需要建立多列联合索引

    • 当单个列过滤之后还有很多数据,那么索引的效率将会比较低,即列的区分度较低,那么如果在多个列上建立索引,那么多个列的区分度就大多了,将会有显著的效率提高。

    4.根据业务场景建立覆盖索引

    • 只查询业务需要的字段,如果这些字段被索引覆盖,将极大的提高查询效率

    5.多表连接的字段上需要建立索引这样可以极大的提高表连接的效率

    6.where条件字段上需要建立索引

    7.排序字段上需要建立索引

    8.分组字段上需要建立索引

    9.where条件上不要使用运算函数,以免索引失效

  • 相关阅读:
    js编码中常用的知识点
    oracle函数的使用
    oracle 临时表的使用
    oracle11G归档日志管理
    oracle中 高水位线详解
    oracle并行模式(Parallel)
    oracle常用函数详解(详细)
    oracle系统表的查询
    15000 字的 SQL 语句大全
    oracle_单引号问题和execute immediate 赋值问题
  • 原文地址:https://www.cnblogs.com/luyi001/p/13706991.html
Copyright © 2020-2023  润新知