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 ;
    
  • 相关阅读:
    zoj 2316 Matrix Multiplication 解题报告
    BestCoder7 1001 Little Pony and Permutation(hdu 4985) 解题报告
    codeforces 463C. Gargari and Bishops 解题报告
    codeforces 463B Caisa and Pylons 解题报告
    codeforces 463A Caisa and Sugar 解题报告
    CSS3新的字体尺寸单位rem
    CSS中文字体对照表
    引用外部CSS的link和import方式的分析与比较
    CSS样式表引用方式
    10个CSS简写/优化技巧
  • 原文地址:https://www.cnblogs.com/godlover/p/12056851.html
Copyright © 2011-2022 走看看