总目录:https://www.jianshu.com/p/e406a9bc93a9
数据库 - 子目录:https://www.jianshu.com/p/4499e57a5604
Yuan先生的数据库进阶:https://www.cnblogs.com/yuanchenqi/articles/6437362.html
事务
什么是事务
事务指逻辑上的一组操作,组成这组操作的各个单元,要不全部成功,要不全部不成功。
事务特性
<1> 原子性(Atomicity):原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。
<2> 一致性(Consistency):事务前后数据的完整性必须保持一致。在事务执行之前数据库是符合数据完整性约束的,无论事务是否执行成功,事务结束后的数据库中的数据也应该是符合完整性约束的。在某一时间点,如果数据库中的所有记录都能保证满足当前数据库中的所有约束,则可以说当前的数据库是符合数据完整性约束的。
比如删部门表前应该删掉关联员工(已经建立外键),如果数据库服务器发生错误,有一个员工没删掉,那么此时员工的部门表已经删除,那么就不符合完整性约束了,所以这样的数据库也就性能太差啦!
<3>隔离性(Isolation):事务的隔离性是指多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离。
将数据库设计为串行化程的数据库,让一张表在同一时间内只能有一个线程来操作。如果将数据库设计为这样,那数据库的效率太低了。所以数据库的设计这没有直接将数据库设计为串行化,而是为数据库提供多个隔离级别选项,使数据库的使用者可以根据使用情况自己定义到底需要什么样的隔离级别。
不考虑隔离性可能出现的问题:
脏读
一个事务读取到了另一个事务未提交的数据,这是特别危险的,要尽力防止。
不可重复读
在一个事务内读取表中的某一行数据,多次读取结果不同。(一个事务读取到了另一个事务已经提交的数据--增加记录、删除记录、修改记录),在某写情况下并不是问题,在另一些情况下就是问题。
虚读
是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。(一个事务读取到了另一个事务已经提交的数据---增加记录、删除记录),在某些情况下并不是问题,在另一些情况下就是问题。
四个隔离级别:
Serializable:可避免脏读、不可重复读、虚读情况的发生。(串行化)
Repeatable read:可避免脏读、不可重复读情况的发生。(可重复读)不可以避免虚读
Read committed:可避免脏读情况发生(读已提交)
Read uncommitted:最低级别,以上情况均无法保证。(读未提交)
安全性考虑:Serializable>Repeatable read>Read committed>Read uncommitted
数据库效率:Read uncommitted>Read committed>Repeatable read>Serializable
一般情况下,我们会使用Repeatable read、Read committed mysql数据库默认的数据库隔离级别Repeatable read
mysql中设置数据库的隔离级别语句:
set [global/session] transaction isolation level xxxx;
如果使用global则修改的是数据库的默认隔离级别,所有新开的窗口的隔离级别继承自这个默认隔离级别
如果使用session修改,则修改的是当前客户端的隔离级别,和数据库默认隔离级别无关。
<4>持久性(Durability):持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。
事务命令
#开启事务
start transaction;
#回滚
rollback
#提交事务
commit;
#设置回滚点
savepoint rol_name;
#回滚至rol_name回滚点
rollbackto rol_name;
例子1:
例子2
索引
创建/添加/删除索引
在创建表时添加索引
CREATE TABLE 表名( 属性名 数据类型[完整性约束条件],
属性名 数据类型[完整性约束条件],
......
属性名 数据类型
[ UNIQUE | FULLTEXT | SPATIAL ] INDEX | KEY
[ 别名] ( 属性名1 [(长度)] [ ASC | DESC] )
);
创建索引
CREATE <索引名> ON <表名> (<列名> [<长度>] [ ASC | DESC])
or
ALTER TABLE 表名 ADD
[UNIQUE | FULLTEXT | SPATIAL ] INDEX 索引名 (字段名[(长度)] [ASC |DESC]) ;
删除索引
DROP INDEX 索引名 on 表名
创建普通索引示例:
创建唯一索引示例:
创建全文索引示例:
创建多列索引示例:
添加索引
删除索引
索引性能测试
--创建表
create table Indexdb.t1(id int,name varchar(20));
--存储过程
delimiter $$
create procedure autoinsert()
BEGIN
declare i int default 1;
while(i<500000)do
insert into Indexdb.t1 values(i,'yuan');
set i=i+1;
end while;
END$$
delimiter ;
--调用函数
call autoinsert();
-- 花费时间比较:
-- 创建索引前
select * from Indexdb.t1 where id=300000;--0.32s
-- 添加索引
create index index_id on Indexdb.t1(id);
-- 创建索引后
select * from Indexdb.t1 where id=300000;--0.00s