上次整理了一篇SQL基础知识,我记得基本上是把增删改查这类知识总结了一下,基本的语句问题倒是少了,可能是连接查询和其他的方面有点弱,可以抽时间再练一练。
这次要解决的主要是数据库主从复制、MySQL索引和SQL优化、锁和事务这些平常的基础教程里讲的比较少的东西。
数据库主从复制
解决单点故障问题和提高整体服务性能。最粗略的说法是,其实大概就是异步备份吧。
索引
索引快,是因为数据库额外为索引字段存储建了结构,像是B+树,这样的查询效率要比遍历查找块,接近二分查找的速度。极端情况下(更新少、请求频繁、实时性低)可以建一个单项有序序列,用二分法最快。
索引分普通索引、唯一索引(保证元素在列中的唯一性)、主键(主键默认创建了索引)、单列索引、多列索引(满足最左前缀原则,即部分使用多列索引,优先用最左边的部分,若是用的部分在右边索引的效果就不是太好)。
SQL的优化
可以对某些较大的数据库进行拆库,或者拆表。
拆表使用的方法有两种,水平拆分和垂直拆分,水平拆分其实就是限制表的规模,再建一张副表。垂直拆分就是把字段拆出来,像是不常用的字段,可以单独拆出来,这样就可以减轻查找时候的负担了。
少用*查找,最好只指定自己需要的字段。关联查询用小表驱动大表。名字太长的字段名和表名用别名替换。字符串加引号。不要设置字段为NULL,用空字符串都能减轻SQL的负担。
参考explain的过程说明来优化SQL的执行过程。
锁
从个人角度理解,锁就是对资源访问的限制吧,若是没有限制,资源访问就会出现各种问题。
锁分悲观锁和乐观锁。
悲观锁和乐观锁是一种概念。不是指实际的实现。像是悲观锁,针对的大多针对的时写多读少的情景,他就假设每次一个进程修改数据时都会被另一个进程访问到,为了防止这种情况的发生,每次修改数据前,进程都会对内存加锁,禁止掉其他进程读写权限。乐观锁针对的一般是写少读多的情况,所以假设数据一般不会发生被修改,所以只有在提交的时候才会对数据进行查验。可以设置一个version,每次修改都会对version加1,这样通过核对version的值,很容易就知道了数据有没有被修改了。
悲观锁还分共享锁和互斥锁。共享锁是只对读这个权限进行共享,但是写还是不行的。互斥锁简言之就是不管读写每次都会先把进程锁了。当然并发度就会差不少。
针对数据库的锁的分类,大概分表级锁、页级锁和行级锁。表级锁开销小,速度快、粒度大,但是很明显并发度不够,经常会发生冲突。行级锁是针对表中的一行进行的锁,开销大,速度慢,但是冲突概率低,并发度高。页级锁的性能基本上介于表级锁和行级锁之间。现在的MySQL,使用的InnoDB默认使用的就是行级锁。主要是并发的效果好一些。
死锁处理目前有这几个方法,一是超时结束任务,二是死锁检测,发生死锁后回滚事务。
事务
事务其实就是一组连续的数据库操作。这一组操作必须要么全执行完,要么全部不执行,不存在执行到一半了突然出了问题不执行的情况。
事务的四个特点、原子性(一个事务就是一个整体,要么成功要么全不执行)、隔离性(多事事务之间操作互相独立,不能发生干涉)、一致性(执行事务只是从一个一致状态到另一个一致状态)、持久性(事务一旦提交,造成的影响是持久存在的,数据库故障也不会丢失提交事务的操作)。
事务隔离级别基本存在四种情况,读未提交,读提交,可重复读、串行化。
先介绍三个概念。脏读、不可重复读和幻读。
脏读指一个事务修改了事务但还没提交的时候另一个事务却已经能从事务上读到这个还没提交的数据了。
不可重复读,一个事务读取同一条记录两次,但是得到的内容不一样。
幻读是一个事务读两次,但是记录的条目数量不一样。无中生有或者不翼而飞了属于是。
上面事务隔离程度依照从左往右依次变高。
读未提交不能阻止上面的问题,最不安全。读提交制止了脏读操作,但是共享操作的存在违反了事务的隔离性,每次修改的新值都能读到。可重复读是制止了脏读和不可重复读,每次只会显示第一次读取的值。串行化问题是写不能读,读不能写,不能并发。
总结
理解概念,记在脑子里。