zoukankan      html  css  js  c++  java
  • 数据库补充

    视图

    1.什么是视图

    视图就是通过得到一张虚拟表,然后保存下来,下次直接使用即可

    2.为什么要用视图

    如果要频繁使用一张虚拟表,可以不用重复查询

    3.如何用视图

    create view 视图名 as + 虚拟表
    create view teacher2course as 
    select * from teacher inner join course on teacher.tid = course.teacher_id;
    

    注意:
    1.在硬盘中,视图只有表结构文件,没有表的数据

    2.视图通常是用于查询,尽量不要修改视图中的数据

    删除

    drop view teacher2course;
    

    注意:
    这里开发过程中一般不会去使用视图,而是通过重新修改sql语句来扩展功能

    触发器:
    在满足对某张表数据的增删改情况下,自动触发的功能称之为触发器

    为什么要使用触发器:
    触发器专门会针对一张表在增删改的情况下,会触发触发器的执行,就是会自动运行另一段sql代码

    创建触发器的语法

    create trigger tri_after/before_insert/delete/update_t1 after/before insert on 表名 for each row begin
    sql代码...
    end
    # 针对插入
    create trigger tri_after_insert_t1 after insert on 表名 for each row
    begin
        sql代码。。。
    end 
    create trigger tri_after_insert_t2 before insert on 表名 for each row
    begin
        sql代码。。。
    end
    
    # 针对删除
    create trigger tri_after_delete_t1 after delete on 表名 for each row
    begin
        sql代码。。。
    end
    create trigger tri_after_delete_t2 before delete on 表名 for each row
    begin
        sql代码。。。
    end
    
    # 针对修改
    create trigger tri_after_update_t1 after update on 表名 for each row
    begin
        sql代码。。。
    end
    create trigger tri_after_update_t2 before update on 表名 for each row
    begin
        sql代码。。。
    end
    
    
    
    # 触发器的案例
    CREATE TABLE cmd (
        id INT PRIMARY KEY auto_increment,
        USER CHAR (32),
        priv CHAR (10),
        cmd CHAR (64),
        sub_time datetime, #提交时间
        success enum ('yes', 'no') #0代表执行失败
    );
    
    CREATE TABLE errlog (
        id INT PRIMARY KEY auto_increment,
        err_cmd CHAR (64),
        err_time datetime
    );
    
    delimiter $$  # 将mysql默认的结束符由;换成$$
    create trigger tri_after_insert_cmd after insert on cmd for each row
    begin
        if NEW.success = 'no' then  # 新记录都会被MySQL封装成NEW对象
            insert into errlog(err_cmd,err_time) values(NEW.cmd,NEW.sub_time);
        end if;
    end $$
    delimiter ;  # 结束之后记得再改回来,不然后面结束符就都是$$了
    
    #往表cmd中插入记录,触发触发器,根据IF的条件决定是否插入错误日志
    INSERT INTO cmd (
        USER,
        priv,
        cmd,
        sub_time,
        success
    )
    VALUES
        ('egon','0755','ls -l /etc',NOW(),'yes'),
        ('egon','0755','cat /etc/passwd',NOW(),'no'),
        ('egon','0755','useradd xxx',NOW(),'no'),
        ('egon','0755','ps aux',NOW(),'yes');
    
    # 查询errlog表记录
    select * from errlog;
    # 删除触发器
    drop trigger tri_after_insert_cmd;
    

    事务

    什么是事务

    ​ 开启一个事务可以包含一些sql语句,这些sql语句要么同时成功,要么都失败

    这是事务的原子性

    事务的作用

    保证了对数据操作时的数据的安全性

    事务应该具有4个属性:原子性,一致性,隔离性,持久性这四个称之为ACID特性

    原子性:
    一个事务是一个不可分割的单位,要么一起成功,要么一起失败。

    一致性:

    ​ 和原子性差不多

    隔离性:
    一个事务的执行不能被其他事务干扰

    持久性:
    也称之为永久性,指的是事务一旦提交,它对数据库中数据的改变是永久的

    使用:

    create table user(
    id int primary key auto_increment,
    name char(32),
    balance int
    );
    
    insert into user(name,balance)
    values
    ('wsb',1000),
    ('egon',1000),
    ('ysb',1000);
    
    # 修改数据前先开启事务操作
    start transaction;
    
    # 修改操作
    update user set balance=900 where name ='wsb'; #买东西支付了100
    update user set balance=1010 where name='egon'; #中介拿走了10元
    update user set balance=1090 where name ='ysb'; #卖家拿到90元
    
    # 回滚到上一个状态
    rollback;
    
    # 开启事务后,只要没执行到commit,数据其实都没有真正刷新到硬盘
    commit;
    
    

    存储过程

    存储过程包含了一系列可执行的SQL语句,存储过程存放于mysql中,通过调用它的名字可以执行它的内部的一堆sql

    三种开发模式

    一:
    """
    应用程序:只需要开发应用程序的逻辑
    mysql:编写好存储过程,以供应用程序调用
    优点:开发效率,执行效率都高
    缺点:考虑到人为因素、跨部门沟通等问题,会导致扩展性差
    """
    二:
    """
    应用程序:除了开发应用程序的逻辑,还需要编写原生sql
    优点:比方式1,扩展性高(非技术性的)
    缺点:
    1、开发效率,执行效率都不如方式1
    2、编写原生sql太过于复杂,而且需要考虑到sql语句的优化问题
    """
    三:
    """
    应用程序:开发应用程序的逻辑,不需要编写原生sql,基于别人编写好的框架来处理数据,ORM
    优点:不用再编写纯生sql,这意味着开发效率比方式2高,同时兼容方式2扩展性高的好处
    缺点:执行效率连方式2都比不过
    """
    
    

    创建存储过程

    delimiter $$
    create procedure p1(
        in m int,  # in表示这个参数必须只能是传入不能被返回出去
        in n int,  
        out res int  # out表示这个参数可以被返回出去,还有一个inout表示即可以传入也可以被返回出去
    )
    begin
        select tname from teacher where tid > m and tid < n;
        set res=0;
    end $$
    delimiter ;
    
    # 小知识点补充,当一张表的字段特别多记录也很多的情况下,终端下显示出来会出现显示错乱的问题
    select * from mysql.userG;
    

    如何用存储过程

    # 大前提:存储过程在哪个库下面创建的只能在对应的库下面才能使用!!!
    # 1、直接在mysql中调用
    set @res=10  # res的值是用来判断存储过程是否被执行成功的依据,所以需要先定义一个变量@res存储10
    call p1(2,4,10);  # 报错
    call p1(2,4,@res);  
    
    # 查看结果
    select @res;  # 执行成功,@res变量值发生了变化
    
    # 2、在python程序中调用
    pymysql链接mysql
    产生的游表cursor.callproc('p1',(2,4,10))  # 内部原理:@_p1_0=2,@_p1_1=4,@_p1_2=10;
    cursor.excute('select @_p1_2;')
    
    
    # 3、存储过程与事务使用举例(了解)
    delimiter //
    create PROCEDURE p5(
        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;
          update user set balance=900 where id =1;
          update user123 set balance=1010 where id = 2;
          update user set balance=1090 where id =3;
      COMMIT;
    
      -- SUCCESS
      set p_return_code = 0; #0代表执行成功
    
    
    END //
    delimiter ;
    

    函数

    mysql内置的函数只能在sql语句中使用

    # 例子
    CREATE TABLE blog (
        id INT PRIMARY KEY auto_increment,
        NAME CHAR (32),
        sub_time datetime
    );
    
    INSERT INTO blog (NAME, sub_time)
    VALUES
        ('第1篇','2015-03-01 11:31:21'),
        ('第2篇','2015-03-11 16:31:21'),
        ('第3篇','2016-07-01 10:21:31'),
        ('第4篇','2016-07-22 09:23:21'),
        ('第5篇','2016-07-23 10:11:11'),
        ('第6篇','2016-07-25 11:21:31'),
        ('第7篇','2017-03-01 15:33:21'),
        ('第8篇','2017-03-01 17:32:21'),
        ('第9篇','2017-03-01 18:31:21');
    
    select date_format(sub_time,'%Y-%m'),count(id) from blog group by date_format(sub_time,'%Y-%m');
    

    流程控制

    # if条件语句
    delimiter //
    CREATE PROCEDURE proc_if ()
    BEGIN
        declare i int default 0;
        if i = 1 THEN
            SELECT 1;
        ELSEIF i = 2 THEN
            SELECT 2;
        ELSE
            SELECT 7;
        END IF;
    
    END //
    delimiter ;
    
    # while循环
    delimiter //
    CREATE PROCEDURE proc_while ()
    BEGIN
        DECLARE num INT ;
        SET num = 0 ;
        WHILE num < 10 DO
            SELECT
                num ;
            SET num = num + 1 ;
        END WHILE ;
    END //
    delimiter ;
    
  • 相关阅读:
    latex
    anaconda
    git stash
    YOLO训练Pedestrain
    OpenCL C
    OpenCL
    OpenVX
    caffe源码阅读
    居住证积分查询地址
    jdk 1.8内存逐步增大的一个bug
  • 原文地址:https://www.cnblogs.com/godlover/p/12056851.html
Copyright © 2011-2022 走看看