zoukankan      html  css  js  c++  java
  • 数据库高级

    高级部分

    一、视图

    什么是视图,

    本质上是一个虚拟的表,即看得见但是不实际存在 
    视图是有一张表或多张表的查询结果构成的一张虚拟表
    

    为甚么要用视图

    场景1:

    隔离数据
    我们希望某些查询语句只能查看到某个表中的一部分记录 
    

    场景2:

    简化sql语句的编写
    

    使用方法:

    语法:
    create [or replace] view view_name as 查询语句;
    or replace 如果视图已经存在了 就替换里面的查询语句;
    
    # 修改视图
    alter view view_name  as 新的语句;
    
    # 删除视图
    drop view  view_name;
    
    # 查看
    desc view_name;
    show create view view_name;
    
    
    # 限制可以查看的记录 
    create table salarys(id int,name char(10),money float);
    insert into salarys values(1,"张三丰",50000),(2,"张无忌",40000);
    # 创建视图  限制只能查看张无忌的工资
    create view zwj_view as select *from salarys where name = "张无忌";
    
    # 简化sql编写
    create table student(
      s_id int(3),
      name varchar(20), 
      math float,
      chinese float 
    );
    insert into student values(1,'tom',80,70),(2,'jack',80,80),(3,'rose',60,75);
    
    create table stu_info(
      s_id int(3),
      class varchar(50),
      addr varchar(100)
    );
    insert into stu_info values(1,'二班','安徽'),(2,'二班','湖南'),(3,'三班','黑龙江');
    # 查询班级和学员的对应关系做成一个视图  方便后续的查询 
    create view class_info as select student.s_id,name,class from student join stu_info on student.s_id = stu_info.s_id;
    
    select *from class_info;
    

    注意: 修改视图 也会引起原表的变化,我们不要这么做,视图仅用于查询

    二、触发器:

    触发器是一段与表有关的mysql程序
    当这个表在某个时间点发生了某种事件时 将会自动执行相应的触发器程序
    
    其中两个关键因素:
    时间点
    	事件发生前  before | 事件发生后  after 
    事件	
    	update  delete   insert 
    再触发器自动的包含两个对象
    	old        update,delete中可用 
    
    	new        update,insert 中可用
    用来干什么: 
    	可以用于:当表的数据被修改时,自动记录一些数据,执行一些sql语句 
    
    语法:
    create trigger t_name  t_time t_event on  table_name 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
    );
    
    #需求: 当插入cmd表 的时候 如果执行状态时失败的 那么将信息插入到errlog中
    
    # 将结束符设置为|
    delimiter |
    create trigger cmd_insert after insert on cmd for each row
    begin
    if new.success = "no" then
    	insert into errlog values(null,new.cmd,new.sub_time);
    end if;
    end|
    # 在还原之前的结束符 
    delimiter ;
    
    
    # 创建一个触发器 叫cmd_insert  
    # 触发器会在 插入数据到cmd表后执行 
    # 当插入的记录的success为no时 自动插入记录到errlog中 
    
    
    # 错误原因 遇到分号自动提交了  , 需要重定义  行结束符  
    delimiter |
    
    # 删除触发器
    drop trigger cmd_insert;
    
    #查看 所有触发器
    show triggers;
    
    # 查看某个触发器的语句 
    show create trigger t_name;
    

    三、事务:

    什么是事务 ------>是逻辑上的一组操作,要么都成功,要么都失败

    事务存在的必要性------||||||||||

    很多时候一个数据操作,不是一个sql语句就完成的,可能有很多个sql语句,如果部分sql执行成功而部分sql执行失败将导致数据错乱!

    事务的四个特性:

    1.原子性:指的是这个事务中的sql语句是一个整体,不能拆分,要么都执行,要么全都失败 
    
    2.一致性: 事务执行结束后,表的关联关系一定是正确的,不会发送数据错乱  
    
    3.隔离性:事务之间相互隔离,数据不会互相影响,即使操作了同一个表 , 本质就是加锁,根据锁的粒度不同分为几个隔离级别 
    
    4.持久性:事务执行成功后数据将永久保存,无法恢复  
    

    事务的应用场景:

    转账操作  1.从原有账户减去转账金额,
    		2.给目标账户加上转账金额 做增加操作 
    
    money(name,money)
    
    update money set money = money - 100 where name = "李寻欢";
    
    update money set money = money + 100 where name = "步惊云";
    

    注意: 在官方提供的cmd的mysql客户端下 事务是默认就开启,会将一条sql语句作为一个事务 会自动提交

    使用事务:

    #开启事务 ,在这条语句之后的sql将处在同一事务,并不会立即修改数据库
    start transaction 
    rollback  #回滚操作   取消这个事务,并且不会对数据库中的数据产生任何影响
    #事务的回滚的前提是能捕捉异常,否则无法决定何时回滚,另外在mysql中需要使用存储过程才能捕获异常
    
    commit  #提交事务 事务中的sql立即执行数据的操作
    
    基本语法:
    create table `account` (
      `name` char(10),
      `money` float  
    );
    
    start transaction;
    update account set money = money - 100 where name = "一只穿云箭";
    update account set money = money + 100 where name = "千军万马";
    commit;
    
    
    # 何时应该回滚  当一个事务执行过程中出现了异常时
    # 何时提交   当事务中所有语句都执行成功时
    # 保存点 可以在rollback指定回滚到某一个savepoint ,也就是回滚一部分  
    
    start transaction;
    update account set money = money - 100 where name = "一只穿云箭";
    savepoint a;
    update account set money = money - 100 where name = "一只穿云箭";
    savepoint b;
    update account set money = money - 100 where name = "一只穿云箭";
    savepoint c;
    
    select * from account;
    
    # 回滚至某个保存点 
    rollback to 保存点名称
    
    read committed
    
    

    隔离级别:
    read uncommittted ---------不做任何隔离,有可能脏读 和幻读
    read commited-------------可以防止脏读,但是不能防止不可重复读和幻读
    repeatable read -------可以防止脏读、不可重复读,不能防止幻读
    serializable -----串行 没有任何问题 效率低而已

    修改隔离级别:

    修改全局的  
     set global transaction isolation level read committed;
     或者:
     set @@tx_isolation = "asasasasas-read";
     修改局部
     set session transaction isolation level read committed;
     
    
     @@系统内置变量
     @表示用户自定义的变量
    

    四、存储过程:

    什么是存储过程 ,

    是任意的sql语句的组合,被放到某一个存储过程中,类似于一个函数,有一个函数,有参数,还是函数体
    

    用来干什么:

     其中可以包含任何的sql语句,逻辑处理,事务处理,所有的我们学过的sql语句都可以放到里面 
    

    三种数据处理方式

    1.应用程序只关注业务逻辑,所有与数据相关的逻辑封装到mysql中 
    
    优点:应用程序要处理的事情变少了, 可以减少网络传输
    
    缺点:增加了人力成本,沟通成本,降低整体开发效率 
    
    2.应用程序既要处理业务逻辑,还要自己编写sql语句  
    
    优点:降低了沟通成本,人力成本 
    
    缺点:网络传输增加,sql语句的编写非常繁琐,易出错 
    
    3.通过ORM框架  对象关系映射  自动生成sql语句并执行 
    
    优点:不需要要在编写sql语句,明显提升和开发速度  
    
    缺点: 不够灵活,应用程序开发者和数据库完全隔离了,可能导致仅关注上层开发,而不清楚底层原理
    

    使用存储过程

    语法:
    create procedure pro_name(p_Type p_name data_type)
    begin
    sql语句......流程控制
    end
    
    p_type 参数的类型  in输入  out输出   inout即可输出也可输入
    p_name 参数的名字 
    p_data_type 参数的数据类型 如  int float
    
    #注意:out参数必须是一个变量 不能是值
    
    #案例:
    delimiter |
    create procedure add1(in a float,in b float,out c float)
    begin 
    set c = a + b;
    end|
    delimiter;
    
    #调用
    set  @res = 0;
    call add1(100,10,@res)
    # 删除
    drop procedure 名称;
    # 查看
    show create procedure 名称;
    # 查看全部  db02库下的所有过程
    select name from mysql.proc where db = 'day41' and type = 'PROCEDURE';
    
    delimiter |
    create procedure transfer2(in aid int,in bid int,in m float,out res int)
    begin 
    	declare exit handler for sqlexception
    	begin
    		# 异常处理代码
    		set res = 99;
    		rollback;
    	end;
    	
    	start transaction;
    	update account set money = money - m where id = aid;
    	update account set money = moneys + m where id = bid;
    	commit;
    	set res = 1;
    end|
    delimiter ;
    

    5.函数

    自定义函数

    create function func_name(参数 类型)
    函数体
    returns 返回值的类
    return 返回值 
    
    
    delimiter | 
    create function add2(a int,b int)
    returns int
    return a + b|
    delimiter ;
    
    
    #查看创建语句 
    show create function name;
    
    #查看所有函数的状态
    show function status;
    
    #查看某个库下所有函数
    select name from mysql.proc where db = "库名称" and type = "FUNCTION";
    
    # 删除
    drop function name;
    

    6.备份与恢复

    # 备份
    mysqldump.exe   
    mysqldump -u用户名 -p密码 数据库 表名1 表名2 .... > 文件路径....
    # 注意 第一个表示数据库  后面全都是表名
    mysqldump -uroot -p day41 student  > 
    
    
    #备份多个数据库
    mysqldump -uroot -p111 --databases day41 day40  > x3x.sql
    #指定 --databases 后导出的文件包含 创建库的语句   而上面的方式不包含
    
    #备份所有数据  
    mysqldump -uroot -p111 --all-databases > all.sql
    
    
    #自动备份
    linux crontab 指令可以定时执行某一个指令
    
    
    
    # 恢复数据:
    没有登录mysql 
    mysql < 文件的路径
    
    
    已经登录了MySQL 
    source  文件路径
    
    
    注意: 如果导出的sql中没有包含选择数据库的语句 需要手动加上 
    

    7.流程控制

    delimiter | 
    create procedure showjishu()
    begin
    declare i int default 0;
    aloop: loop
    set i = i + 1;
    if i >= 101 then leave aloop; end if;
    if i % 2 = 0 then iterate aloop; end if;
    select i;
    end loop aloop;
    end|
    delimiter ;
    

    正则匹配

    语法:
    select  *from  table where 字段名  regexp "表达式!";
    
    create table info(name char(20));
    insert into  info values("jack sbaro"),("jack rose"),("jerry sbaro"),("sbaro jerry"),("jerry");
    
    # 注意: 不能使用类似 w 这样的符号   需要找其他符号来代替  
    
    
  • 相关阅读:
    细嚼慢咽C++primer(3)——引用形参,内联函数,重载函数,指向函数的指针
    面试突击(1)——数据结构基础,排序
    【Linux操作系统分析】进程的创建与可执行程序的加载
    List排序
    Dictionary 排序
    数据库连接串MSSQL、Oracle、Access
    String.IsNullOrEmpty()和String.IsNullOrWhiteSpace()
    jquery学习一 选择器
    sql查询问题
    int、string转enum;enum转int、string【C#】
  • 原文地址:https://www.cnblogs.com/zhuyuanying123--/p/11197413.html
Copyright © 2011-2022 走看看