• 1101 事务存储引擎触发器函数


    1. 事务

    mysql主要用于处理操作量大,复杂度高的数据,比如在人员管理系统 你删除一个人员,你既需要删除人员的基本资料,也要删除和该人员相关的信息,如信箱,文章等等,这样,这些数据库操作语句就构成一个事务!

    • 在mysql中只有使用了InnoDB数据库引擎的数据库或表才支持事务
    • 事务处理可以维护数据库的完整性,保证成批的sql语句要么全部执行,要么全部不执行
    • 事务用来管理insert,update,delete语句

    为什么要使用

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

    eg: 转账 == 转入转出均成功,才能认为操作成功

    使用

    开启事务:	start transaction
    sql语句:	
    提交:		 commit	
    
    回滚:		 rollback	// 影响所有,回滚到初始
    
    start transaction;
    --开启事物,在这条语句之后的sql将处在同一事务,并不会立即修改数据库
        
    commit;
    --提交事务,让这个事物中的sql立即执行数据的操作,
    
    rollback;
    --回滚事务,取消这个事物,这个事物不会对数据库中的数据产生任何影响 #(包括没有语法错误的数据变更语句) 
    

    例子

    1.// 创建文件夹
    create database day111;
    2.// 更改
    use day111;
    3.//创建表
    create table aaa(
    	id int auto_increment primary key,
        name varchar(32) not null default '',
        salary int not null default 0
    )charset utf8;
    	// Query OK, 0 rows affected (0.02 sec)
    4.//添加数据
    insert into aaa (name,salary) values ('lucy',100);
    insert into aaa (name,salary) values ('jack',100);
    5.//查询数据
        select * from aaa;
    /*	+----+------+--------+
        | id | name | salary |
        +----+------+--------+
        |  1 | lucy |    100 |
        |  2 | jack |    100 |
        +----+------+--------+
        2 rows in set (0.00 sec)	*/
    

    解决方法

    1.//开启事务:
        start transaction;
    2.//开始转账操作
        update aaa set salary=50 where name='lucy';
    3.//查询余额
        select * from aaa;
    /*	+----+------+--------+
        | id | name | salary |
        +----+------+--------+
        |  1 | lucy |     50 |
        |  2 | jack |    100 |
        +----+------+--------+
        2 rows in set (0.00 sec)	*/
    
    4. // 在另一客户端中查看余额
    mysql> select * from aaa;
    /*  +----+------+--------+
        | id | name | salary |
        +----+------+--------+
        |  1 | lucy |    100 |
        |  2 | jack |    100 |
        +----+------+--------+
        2 rows in set (0.00 sec)	*/ 事务间是相互独立的
    5. // 修改jack数据(模拟收账)
        update aaa set salary=150 where name='jack';
    
    6. //提交事务
        commit;
    
    7.两个客户端查询结果 结果一样
    /*  mysql> select * from aaa;
        +----+------+--------+
        | id | name | salary |
        +----+------+--------+
        |  1 | lucy |     50 |
        |  2 | jack |    150 |
        +----+------+--------+
        2 rows in set (0.00 sec)
    

    回滚

    8.//回滚操作在开启事务之后,commit之前.回到之前
        start transaction;
    	update aaa set salary=50 where name='lucy';
    	select * from aaa;
        rollback;
    	select * from aaa;
    
    //回到了更改之前的数据
        
    

    特性

    原子性

    事务是一组不可分割的单位,要么同时成功,要么同时不成功
    

    一致性

    事务前后的数据完整性应该保持一致
    

    隔离性

    多个用户并发访问数据时,一个用户的事务不能被其他用户的事务所干扰,多个并发事务间数据要相互隔离
    

    持久性

    一个事务一旦被提交,它对数据的改变就是永久的,即使数据库故障也不会对其有影响.
    

    2.存储引擎

    引擎是建表的规定,提供给表使用,而不是数据库

    create table 表名(
    字段名1 类型[(宽度) 约束条件],
    字段名2 类型[(宽度) 约束条件],
    字段名3 类型[(宽度) 约束条件]
    )engine=innodb charset=utf8; #默认引擎为innodb,设置了配置文件后的默认编码为utf8。
    

    InnoDB

    • mysql 5.5以上engine默认添加innodb

    • InnoDB是一个事务型的存储引擎,有行级锁定和外键约束。

    MYIsam

    MyIASM是MySQL默认的引擎,但是它没有提供对数据库事务的支持,也不支持行级锁和外键,因此当INSERT(插入)或UPDATE(更新)数据时即写操作需要锁定整个表,效率便会低一些。
    

    引擎在创建表的时候,会创建三个文件,一个是.frm文件用于存储表的定义,一个是.MYD文件用于存储表的数据,另一个是.MYI文件,存储的是索引。

    区别

    1. InnoDB支持事务,MYIsam不支持
    2. InnoDB支持行锁,MYIsam支持表锁.
    InnoDB对数据行进行加锁,处理度较细小
    

    3.视图

    定义

    存储的查询语句,当调用的时候,产生结果集,视图充当的是虚拟表的角色.

    项目, 有100个SQl, 其中80个SQL都是:select * from user where name='xxx'; 
    
    • 如果要对一张表或者多张表进行查询,可以通过写复杂的SQL语句来实现
    • 如果要这些SQL语句存储为视图,那么查询的时候,就直接查询这个视图就可以了.
    其相当于从原来的数据表中获取部分数据,然后新建一个只可创建、查询和删除的新表来存放这些数据(一般情况下),可以理解成把想要的数据部分截图下来保存,供以后查询用,此时视图只是为了满足某些数据查询而建立的对象。
    

    例子

    1. // 增加视图
    create view v1 as select * from aaa ;
    // create view v2 as select * from aaa where name='lucy';
    2. // 查看视图
        select * from v2;
    /*  +----+------+--------+
        | id | name | salary |
        +----+------+--------+
        |  1 | lucy |     50 |
        +----+------+--------+
        1 row in set (0.00 sec)			*/
    3. //
    

    增加视图

    create view 视图名(列1,列2...) as select语句 ;
    

    查看视图

    select * from 视图名;
    

    在视图创建完成后,就可以把其当做一个只读的表来用,此时就可以正常的进行查询了,举例:

    mysql> create view aaa (name, psd) as select username, password from peoples;
    #创建视图aaa,里面记录了peoples表的用户名和密码
    mysql> select * from aaa;
    #发现可以正常查询
    

    查看当前库下的所有视图

    show full tables where table_type like 'VIEW';
    

    删除视图

    drop view 视图名;
    

    4.触发器

    在表发生数据更新时,会自动触发的功能称之为触发器

    当一个表在发生数据更新时,需要去完成一些操作,可以为具体数据更新的方式添加触发器。

    当我下一个订单的时候订单表中需要增加一个记录,同时库存表中需要减一,这两个操作是同时发生的,并且前一个操作触发后一个操作
    

    语法

    delimiter //  #此行的作用是转换mysql执行语句的结尾标识
    create trigger 触发器名 before|after insert|update|delete on 表名 for each row
    begin 
        需要触发执行的sql代码们;
    end //
    delimiter ;
    
    注:delimiter是用来修改sql的语句结束标识符
    使语句中的 ; 不再结束
    

    增加触发器

    // 创建t1表
    create table t1(
    	id int auto_increment primary key,
        name varchar(32) not null 
    )charset utf8;
    	// 添加数据
    	insert into t1 (name) values ('uzi'),('xiaogou');
    
    // 创建t2表
    create table t2(
    	id int auto_increment primary key,
        name varchar(32) not null 
    )charset utf8;
    	// 添加数据
    	insert into t2 (name) values ('55k'),('white');
    

    添加触发器

    delimiter //
    create trigger t1_t2 before insert on t1 for each row
    begin
        insert into t2 (name) values ('aa');
    end //
    delimiter ;
    /*
    给t2添加 t1触发器, 当给t1添加值时,t2自动增加数据'aa'
        而给t2加值,t1不会出现数据.
    // 当向t1表中添加值的的同时,向t2表添加一条数据
    */
    
    
    
    
    /*
    mysql> insert into t1 (name) values ('nihao');
    Query OK, 1 row affected (0.01 sec)
    
    mysql> select * from t1;
    +----+---------+
    | id | name    |
    +----+---------+
    |  1 | uzi     |
    |  2 | xiaogou |
    |  3 | nihao   |
    +----+---------+
    3 rows in set (0.00 sec)
    
    mysql> select * from t2;
    +----+-------+
    | id | name  |
    +----+-------+
    |  1 | 55k   |
    |  2 | white |
    |  3 | aa    |
    +----+-------+
    3 rows in set (0.00 sec)
    
    mysql> insert into t2 (name) values ('buhao');
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from t2;
    +----+-------+
    | id | name  |
    +----+-------+
    |  1 | 55k   |
    |  2 | white |
    |  3 | aa    |
    |  4 | buhao |
    +----+-------+
    4 rows in set (0.00 sec)
    
    mysql> select * from t1;
    +----+---------+
    | id | name    |
    +----+---------+
    |  1 | uzi     |
    |  2 | xiaogou |
    |  3 | nihao   |
    +----+---------+
    3 rows in set (0.00 sec)
    

    查看触发器

    show triggers G;		# G 是将输出内容格式化
    
    '''
    *************************** 1. row ***************************
                 Trigger: t1_t2
                   Event: INSERT
                   Table: t1
               Statement: begin
        insert into t2 (name) values ('aa');
    end
                  Timing: BEFORE
                 Created: 2019-11-01 19:06:35.37
                sql_mode: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
                 Definer: root@localhost
    character_set_client: gbk
    collation_connection: gbk_chinese_ci
      Database Collation: latin1_swedish_ci
    1 row in set (0.01 sec)
    

    删除触发器

    drop trigger 触发器名;
    
    //	Query OK, 0 rows affected (0.01 sec)
    

    5.存储过程

    MySQL 5.0 版本开始支持存储过程。

    定义

    像一个sql函数

    存储过程(Stored Procedure)是一种在数据库中存储复杂程序,以便外部程序调用的一种数据库对象。

    用于完成指定功能的sql语句块,类似于python中的函数
    

    优点

    将能指定功能的sql语句块建立成存储过程,不仅将sql语句逻辑化了,更是功能化了,那我们要完成相同的事,只需要重复使用建立的存储过程,就不需要再重复书写sql语句了。
    
    • 存储过程可封装,隐藏复杂商业逻辑
    • 存储过程可以回传值,也可接受参数
    • 存储过程无法使用 SELECT 指令来运行,因为它是子程序,与查看表,数据表或用户定义函数不同。
    • 存储过程可以用在数据检验,强制实行商业逻辑等。

    缺点

    • 存储过程,往往定制化于特定的数据库上,因为支持的编程语言不同。当切换到其他厂商的数据库系统时,需要重写原有的存储过程。
    • 存储过程的性能调校与撰写,受限于各种数据库系统。

    总结

    存储过程可以让sql语句具有 复用性, 从而提高开发效率

    语法

    delimiter //
    
    create procedure 存储名 ()
    BEGIN
    sql语句; # 类似 select * from user where id=2;
    END //
    
    delimiter ;
    
    注:
    1.输入输出类型:in | out | inout
    2.call 存储过程名(实参们)来调用存储过程
    call 存储过程名(实参们)  sql语句中没有任何打印语句时执行后不会得到任何结果,查看结果需要执行查询语句(select 实参中的输出实参)
    

    创建

    delimiter //
    create procedure pp11()
    begin
    select * from t1 where id =1;
    end //
    
    delimiter ;
    

    使用

    调用 call 存储名();

    call pp11();
    /*
    mysql> call pp11();
    +----+------+
    | id | name |
    +----+------+
    |  1 | uzi  |
    +----+------+
    1 row in set (0.00 sec)
    

    删除

    drop procedure 存储名;
    drop procedure pp11;
    //	Query OK, 0 rows affected (0.01 sec)
    

    6.函数

    CHAR_LENGTH(str)
        返回值为字符串str 的长度,长度的单位为字符。一个多字节字符算作一个单字符。
        对于一个包含五个二字节字符集, LENGTH()返回值为 10, 而CHAR_LENGTH()的返回值为5。
    
    CONCAT(str1,str2,...)
        字符串拼接
        如有任何一个参数为NULL ,则返回值为 NULL。
    
    FORMAT(X,D)
        将数字X 的格式写为'#,###,###.##',以四舍五入的方式保留小数点后 D 位, 并将结果以字符串的形式返回。若  D 为 0, 则返回结果不带有小数点,或不含小数部分。
        例如:
        SELECT FORMAT(12332.1,4); 结果为: '12,332.1000'
        
        
    INSTR(str,substr)
    	返回字符串 str 中子字符串的第一个出现位置。
        
    LEFT(str,len)
    	返回字符串str 从开始的len位置的子序列字符。
        
    LOWER(str)
    	变小写
        	
    UPPER(str)
    	变大写
        
    LTRIM(str)
    	返回字符串 str ,其引导空格字符被删除。
        
    RTRIM(str)
    	返回字符串 str ,结尾空格字符被删去。
    
    SUBSTRING(str,pos,len)
    	获取字符串子序列
        
    LOCATE(substr,str,pos)
    	获取子序列索引位置
        
    REPEAT(str,count)
    	返回一个由重复的字符串str 组成的字符串,字符串str的数目等于count 。
        若 count <= 0,则返回一个空字符串。
        若str 或 count 为 NULL,则返回 NULL 。
        
    REPLACE(str,from_str,to_str)
    	返回字符串str 以及所有被字符串to_str替代的字符串from_str 。
        
    REVERSE(str)
    	返回字符串 str ,顺序和字符顺序相反。
        
    RIGHT(str,len)
    	从字符串str 开始,返回从后边开始len个字符组成的子序列
    
    更多函数:
    http://doc.mysql.cn/mysql5/refman-5.1-zh.html-chapter/functions.html#encryption-functions
    		
    

    7.数据库备份

    将重要的数据保存下来
    

    备份的文件在mysql中是mysqldump.exe

    语法

    #语法:
    # mysqldump -h 服务器 -u用户名 -p密码 数据库名 表名,  表名,.... > aaa.sql
    

    例子

    在cmd中输入

    #单库备份
    mysqldump -uroot -p123 db1 > db1.sql
    mysqldump -uroot -p123 db1 table1 table2 > db1-table1-table2.sql
    
    #多库备份
    mysqldump -uroot -p123 --databases db1 db2 mysql db3 > db1_db2_mysql_db3.sql
    
    #备份所有库
    mysqldump -uroot -p123 --all-databases > all.sql
    
    # 重新导入:
    mysql> source D:/test3.sql;
    
  • 相关阅读:
    进程池的使用
    同步提交,异步提交
    协程
    单线程下实现并发的套接字
    批量上传
    TP中的session和cookie
    ajaxReturn
    ajax的两种方式
    Yii里表单的操作方法(展示渲染待续......)
    Yii里文件上传的操作方法(图片修改,在详情上展示,批量上传待续...)
  • 原文地址:https://www.cnblogs.com/fwzzz/p/11779541.html
Copyright © 2020-2023  润新知