事务Transaction
事务概述
1.事务
一个事务是一个完整的业务逻辑单元,不可再分。
比如:银行账户转账,从A账户向B账户转账10000,需要执行两条update语句:
update t_act set balance = balance - 10000 where actno = 'act-001';
update t_act set balance = balance + 10000 where actno = 'act-002';
以上两条DML语句必须同时成功,或者同时失败,不允许出现一条成功,一条失败。
要想保证以上的两条DML语句同时成功或者同时失败,那么就需要使用数据库的“事务机制”。
2.事务相关语句
和事务相关的语句只有:DML语句。(insert delete update)
因为它们这三个语句都是和数据库表当中的“数据”相关的。事务的存在是为了保证数据的完整性,安全性。
3.解释说明
假设所有的业务都能使用1条DML语句搞定,就不需要事务机制了。
但实际情况不是这样的,通常一个“事儿(事务【业务】)”需要多条DML语句共同联合完成。
事务原理
假设一个事务,需要先执行一条insert语句,再执行一条update语句,最后执行一条delete语句,整个事务才算完成。
若提交事务commit,三条DML语句会对磁盘文件做出修改,同时数据库中三条历史操作会被清除;
若回滚事务rollback,三条DML语句不会对文件执行操作,并且数据库中的历史操作会被清除。
事务特性
事务包括四大特性:ACID
A: 原子性:事务是最小的工作单元,不可再分。
C: 一致性:事务必须保证多条DML语句同时成功或者同时失败。
I:隔离性:事务A与事务B之间具有隔离。
D:持久性:持久性说的是最终数据必须持久化到硬盘文件中,事务才算成功的结束。
事务之间的隔离性
事务隔离性存在隔离级别,理论上隔离级别包括4个:
第一级别:读未提交(read uncommitted)
对方事务还没有提交,我们当前事务可以读取到对方未提交的数据。读未提交存在脏读(Dirty Read)
现象:表示读到了脏的数据,数据不稳定。
第二级别:读已提交(read committed)
对方事务提交之后的数据我方可以读取到。
这种隔离级别解决了: 脏读现象没有了。
读已提交存在的问题是:不可重复读。(多次读到不同的数据,读到最新的改变过的数据。)
第三级别:可重复读(repeatable read)
这种隔离级别解决了:不可重复读问题。事务未结束前读到的数据是一致的,接收不到对方更新的数据。
这种隔离级别存在的问题是:读取到的数据是幻象。
第四级别:序列化读/串行化读(serializable)
解决了所有问题。
效率低。需要事务排队。
oracle数据库默认的隔离级别是:读已提交。
mysql数据库默认的隔离级别是:可重复读。
演示事务
mysql事务默认情况下是自动提交的。只要执行任意一条DML语句则提交一次。
可以使用 start transaction;关闭自动提交。
演示:mysql中的事务是支持自动提交的,只要执行一条DML,则提交一次。
mysql> drop table if exists t_user;
mysql> create table t_user(
-> id int primary key auto_increment,
-> username varchar(255)
-> );
mysql> insert into t_user(id,username) values(1,'zs');
mysql> rollback;
#此时执行rollback并不能将插入的数据撤回掉。
演示:使用start transaction;关闭自动提交机制。
mysql> start transaction;
mysql> insert into t_user(username) values('lisi');
mysql> insert into t_user(username) values('Rose');
mysql> rollback;
mysql> select * from t_user;
#此时表中是没有'lisi','Rose'这两条记录的。事务回滚到最初了。
mysql> start transaction;
mysql> insert into t_user(username) values('Jack');
mysql> insert into t_user(username) values('Alice');
mysql> commit;
mysql> select * from t_user;
#提交了事务,表有'Jack','Alice'两条记录。rollback也回不去了。
1.读未提交
mysql> set global transaction isolation level read uncommitted;
2.读已提交
sql> set global transaction isolation level read committed;
3.可重复读
sql> set global transaction isolation level repeatable read;
查看事务的全局隔离级别:
mysql> select @@global.tx transaction
索引
1.索引的概念、作用
索引就相当于一本书的目录,通过目录可以快速的找到对应的资源。
在数据库方面,查询一张表的时候有两种检索方式:
第一种方式:全表扫描
第二种方式:根据索引检索(效率很高)
索引提高检索效率最根本的原理是缩小了扫描的范围。
添加索引是给某一个字段,或者说某些字段添加索引。
索引虽然可以提高检索效率,但是不能随意的添加索引,因为索引也是数据库当中的对象,也需要数据库不断的维护。是有维护成本的。比如,表中的数据经常被修改这样就不适合添加索引,因为数据一旦修改,索引需要重新排序,进行维护。
2.索引的创建和删除
创建索引对象:
create index 索引名称 on 表名(字段名);
删除索引对象:
drop index 索引名称 on 表名;
3.添加索引的条件
- 数据量庞大。(根据客户的需求,根据线上的环境)
- 该字段很少的DML操作。(因为字段进行修改操作,索引也需要维护)
- 该字段经常出现在where子句中。(经常根据哪个字段查询)
注意:主键和具有unique约束的字段自动会添加索引。
根据主键查询效率较高。尽量根据主键检索。
4.查看sql语句的执行计划
mysql> explain select ename,sal from emp where sal = 5000;
mysql> create index emp_sal_index on emp(sal);
mysql> explain select ename,sal from emp where sal=5000;
5.索引实现原理
索引底层采用的数据结构是:B + Tree
通过B Tree缩小扫描范围,底层索引进行了排序,分区,索引会携带数据在表中的“物理地址”,最终通过索引检索到数据之后,获取到关联的物理地址,通过物理地址定位表中的数据,效率是最高的。
mysql> select ename from emp where ename = 'SMITH';
#通过索引转换为:
mysql> select ename from emp where 物理地址 = 0x3;
6.索引的分类
单一索引:给单个字段添加索引
复合索引: 给多个字段联合起来添加1个索引
主键索引:主键上会自动添加索引
唯一索引:有unique约束的字段上会自动添加索引
…
7.索引失效
mysql> select ename from emp where ename like '%A%';
模糊查询的时候,第一个通配符使用的是%,这个时候索引是失效的。索引第一个字母无法定位。
视图
站在不同的角度去看待数据。(同一张表的数据,通过不同的角度去看待)。
1.视图创建/删除
#创建视图:
create view myview as select empno,ename from emp;
#删除视图:
drop view myview;
2.对视图进行增删改查,会影响到原表数据。(通过视图影响原表数据的,不是直接操作的原表)。可以对视图进行CRUD操作。
3.操作
mysql> create table emp_bark as select * from emp;
#这样操作原表会发生改变
mysql> update myview1 set ename='Rose',sal=2000 where empno=7369;
mysql> delete from myview1 where empno=7369;
4.视图的作用
视图可以隐藏表的实现细节。保密级别较高的系统,数据库只对外提供相关的视图,程序员只对视图对象进行CRUD。
DBA命令
1.将数据库当中的数据导出
在windows的dos命令窗口中执行:(导出整个库)
mysqldump 库名>文件路径 -uroot -p333
mysqldump bjpowernode>D:\bjpowernode.sql -uroot -p333
在windows的dos命令窗口中执行:(导出指定数据库当中的指定表)
mysqldump 库名 表名>路径 -uroot –p123
mysqldump bjpowernode emp>D:\bjpowernode.sql -uroot –p123
2.导入数据
mysql> create database bjpowernode;
mysql> use bjpowernode;
mysql> source D:\bjpowernode.sql
数据库设计三范式
1.设计范式
设计表的依据。按照这个三范式设计的表不会出现数据冗余。
2.第一范式
任何一张表都应该有主键,并且每一个字段原子性不可再分。
3.第二范式
建立在第一范式的基础之上,所有非主键字段完全依赖主键,不能产生部分依赖。
多对多:三张表,关系表两外键
4.第三范式
建立在第二范式的基础之上,所有非主键字段直接依赖主键,不能产生传递依赖。
一对多:两张表,多的表加外键。
PS:在实际的开发中,以满足客户的需求为主,有的时候会拿冗余换执行速度。
5.一对一的设计
(1)主键共享
(2)外键唯一