基本的SQL语句(增删查改,建删改表,建删索引,视图)
事物的四个特性(ACID,四个隔离级别,串行化)
数据库并发:锁机制https://www.cnblogs.com/fanp/p/4633453.html
mysql的引擎
索引(B+树)
基本的sql语句:
增删查改:insert into tablename( ) values();
delet from tablename where
update table set where
select ** from tablename where group by having order by asc|desc
连接: select * from table_a (left) join table_b on table_a.*=table_b.* where
建删表:create table (name type primary key,*,*); foreign key name reference table_b(name); primary key (name)
drop table tablename casecade|restrict
alter table tablename add column columnname type
alter table tablename alter column columnname type
建删索引:
create unique|cluster index indexname on tablename(columnname)
drop index indexname
建删视图:
create view viewname()as 查询语句
drop view viewname casecade
select语句的执行顺序,from->where->group by->having->select->order by
字符串拼接:用“||”
创建表的时候的默认值用:default
插入数据库,如果已存在则忽略:insert or ignore into
批量插入数据到一个表中:insert into tablename select
强制使用索引:select * from tablename indexed by indexname where
创建触发器:create trigger name after[before] insert[update] on tablename begin insert into ... end
表的重命名:alter table name1 rename to name2
创建索引:alter table tablename add constraint primary key [foreign key]
交集:select A intersect select B
并集:select A union select B
差集:select A except select B
存储过程:SQL语句集存储在数据库中,一次编译之后再次执行不需要重复的编译
create procedure name (@参数名 参数类型) as begin end
exec
游标:declear name cursor for select
事物的四个特性:
https://www.cnblogs.com/fjdingsd/p/5273008.html
https://www.cnblogs.com/3013218061shang/p/5573476.html
ACID:原子性,一个事物的所有操作要么全做要么全不做(解决:事物一旦失败必须执行回滚)
一致性,事物执行前后都必须处于一致状态,例如转账前后双方账户的总额不变
隔离性,并发访问数据库时,事物之间运行不会互相干扰
永久性,一旦事物提交,它对数据库的修改就是永久的
事物的四个特性(隔离性和一致性)可能被并发破坏,主要问题:
丢失修改(两个事物同时对一个数据进行修改,其中一个事物的结果破坏了另一个事物的结果 类似i++问题),脏读,不可重复读,幻读
并发涉及到事物的四个隔离级别:
分别针对三个问题:
脏读(一个事物读取了另一个事物未提交的数据,先读了一个数据,这个数据是被另一个事物修改的,但是这个事物失败了发生了回滚,刚刚读到的数据是无效的)
不可重复读(先读了一个数据,另一个事物对这个数据进行了修改,再读一次的时候发现两次读到的不一样)
幻读(读取并修改了表中的一批数据,另一个事物在表中追加了记录,再去读发现有的数据没有被修改以为产生了幻觉)
针对这三个问题产生的四个隔离级别从高到低:
可串行化:解决了脏读不可重复读和幻读(并发调度的结果和一次串行执行(所谓串行执行是一个事物完成全部的操作之后再进行下一个事物)的结果相同,说明调度正确。)
可重复读:解决了不可重复读和脏读(mysql数据库默认的隔离级别)
已提交读:解决了脏读(大多数数据库默认的隔离级别)
未提交读:三个问题都没有解决
如何保障可串行化:
两段锁协议:分两个阶段(扩展阶段和收缩阶段),规定,进行读写操作之前首先对数据进行封锁,一旦释放锁之后就不能再获得其他封锁(两段锁和一次性加锁并不相同,两段锁还是可以分开加锁,因此会导致死锁)
解决修改丢失,脏读,重复读:
三级协议:第一级协议:事务对数据进行写操作必须先加互斥锁(因为在写的过程中不会有其他事物对其修改,解决写丢失问题,但是还可以有其他的事物来读,所以不能解决脏读)
第二级协议:在第一级协议的基础上,事物对数据进行读操作之前必须先加共享锁,读完之后立马释放锁(一个事物如果正在对数据进行修改那么另一个事物无法读,解决脏读)
第三级协议:在第一级协议的基础上,事物对数据进行读操作之前加共享锁,在事物提交之后才释放共享锁(在事物进行的过程中不会有其他事物对数据进行修改,解决不可重复读)
数据库并发控制(一致性和隔离性)锁:
锁的粒度:
行级锁
表级锁
锁的级别:
排它锁(写锁):可读取和修改对象,别的事物不能再加其他任何形式的锁(行级锁是一种排它锁)
共享锁(读锁):可读取对象,别的事物可以加读锁但是不能加写锁
锁的使用方式:
悲观锁:认为时刻会发生并发问题,事物访问数据库必须先加锁,利用上面数据库本身的锁机制实现,
乐观锁:认为不会有并发问题,事物访问数据库之前不需要加锁,只是要进行更新时才加锁,利用版本号机制实现,版本号记录数据被更新的次数,即每次更新的时候需要同时读取版本号和数据,在提交的时候需要对比当前版本号是否和刚刚读取的一致,一致才能更新成功(或者记录加时间戳,先读取后对比),适合大量的读操作
其他:意向锁:加了意向锁说明他的下层 节点正在被加锁,要对节点加锁必须先对上层节点加意向锁(表就是记录的上层节点)
死锁:
死锁避免:一次性加锁(事物开始之前需要对所要访问的数据全部加锁,否则不能执行)顺序封锁法
死锁检测和解除:超时法和等待图法(出现循环等待)
mysql引擎:
https://www.cnblogs.com/xiaohaillong/p/6079551.html
innodb:
支持事务ACID特性,支持行级锁,支持外键,不支持全文索引,不保存表的行数,适合大量的写操作的数据库(insert update),适合大容量数据库(会建立缓冲池)
底层索引是B+树,树中存放数据的地址,是聚集索引(索引顺序跟物理存储顺序一致)
myIsam:不支持事物特性,支持表级锁,支持全文索引,保存表的行数,适合大量的读操作的数据库(select),是默认引擎(Mysql在V5.1之前默认存储引擎是MyISAM;在此之后默认存储引擎是InnoDB)
底层索引是B+树,树中存放数据,因此是非聚集索引
mysql索引类型
普通索引
唯一索引:索引列上的值唯一(可以为空),如果是多个列那么多个列的组合值唯一
主键索引:特殊的唯一索引,不能为空,建表的时候创建
组合索引:多个列上的索引
B+树:
https://www.sohu.com/a/156886901_479559
m阶B+树,每个中间节点包含K个元素,有K个子树(m/2<k<=m)
所有叶子节点中包含全部的元素信息,且按从小到大排列,叶子节点之间连接形成链表
所有中间节点的元素同时存在于子节点中,且是子节点的最大值获最小值
聚集索引:叶结点中直接存放数据记录,非聚集索引:叶结点中存放指向数据记录的指针
B+树的查询性能:
数据只存放在最终的叶子节点,因此最终查询都要查询到叶子节点,性能稳定;同时中间节点不存放数据一次可以读入更多的中间节点,因此查询的效率更高;范围查询很方便只需要先找到范围的下界然后在叶子节点上顺序遍历即可
索引失效的情况:
如果条件中带or,即使其中有条件带索引也不会使用(为什么);使用组合索引但是不是从第一个索引开始的;like 用%打头的;如果全表查找比索引快就不用索引(表比较小,查询的数据占表的大部分);