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文件,存储的是索引。
区别
- InnoDB支持事务,MYIsam不支持
- 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;