上一篇http://rdc.taobao.com/team/jm/archives/1349
首先是回答上次的问题。
假设有这么一组数据,性别有4种,user_id是一对多的关系,如果我想查询
select * from tabwhere user_id in (?,?,?,?) and 性别=’不明’
如何进行索引构建能够获得比较好的效果呢?
我个人认为,应该建立的是以user_id作为前导列,性别作为辅助列的索引,在大量单值查询时会有优势。
理由如下
1. 假定总数据量为N,user_id的区分度为N/10000 而性别的区分度为N/4
那么如果以user_id作为前导列,性别作为后列,那么查询的复杂度为O(logN+log(N/10000))。也就是说,第一次二分查找之后,下一次是在第一次的二分查找的基础上再去查找。而如果以性别作为前导,user_id作为后列,那么复杂度为
O(logN+log(N/4));
效率略差。
然后进入本次正题。上次介绍了关系模型,那么这次我们来介绍一下事务。
在一切之前,我想先给自己解嘲一下。。事务我自己也没有办法完全融汇贯通,因为每一个小的选择,都会导致效果的完全不同,所以有错请在后面一起探讨。
那么我们在这里,主要以单机事务作为入手点,然后阐述一下多机事务相关的知识点。我在这里只是想做一个引导,让大家能够对整个的知识体系有一个基本的认识,对于细节问题,会给出一些资料,而不会直接去进行讲解,因为篇幅所限.
一般来说,我们一提起事务,就会想到数据库,确实,事务是数据库的最重要的一个属性。但这似乎不是事务的本源,那么,让我们从更深层次去对事务进行一次思考吧:
事务,本质来说就是一组由一个人(或机器)发起的连续的逻辑操作,共同的完成一件事情,在完成整个事情之前,其所有的改动,都不应该对其他人可见和影响。而在事务结束之后,其一切的改动,都必须“全部”“立刻”对其他的人(或机器)可见。
然后,人们为了描述这一运作,使用了四个词汇,这也是很多面试的同学们折戟沉沙之处。J 不过这个以前我也不会,后来发现,理解了以后,确实有点用,所以这里也费一些笔墨吧。
原子性(Atomicity):也就是说,一组操作,要不就都成功,要不就都失败。不存在中间状态。
一致性(Consistency):一致性,也就是说,这个事务在提交或回滚的时候,对其他人(或机器)来说,数据的状态是同一的,不会出现中间的状态。最理想的状态下,就是说,数据提交后,所有的更改立刻同时生效,可惜,在计算机领域,这个做不到。。因为cpu运算,磁盘写入,内存写入,都是要时间的,内部一定是个顺序化的过程,所以不可能做到绝对的立刻同时生效。
所以一致性一般来说指代的是逻辑上的同时生效,比如,我要改A,B两行数据,那么,最简单的一致性保证就是,对A,B加锁,改A,B,然后对A,B解锁。
这样下一个人读到的一定是A,B的最新值啦。
(但这块有很多种解释,一般来说这是个最不明确的词汇)。
隔离性(Isolation):隔离,这是面试最容易挂的一个问题,其实我认为不怪我们,而是因为本身这个隔离性,是依托锁来进行设计的。
我们所知道的锁,主要有以下几种,1.读写锁,2. 排他锁
那么这四种级别其实就和这两种锁的实现有关,之所以要定义四个级别,其实原因也是因为,锁的范围越大,并行效率越低。而范围越小,那么并行的效率就越高。
读未提交: 其实就是什么锁也没有,所以数据的中间状态,是可能被其他人读到的。
读已提交:就是读写锁实现,读锁在查询之后会被释放掉,所以这样其他人可能会更改那些被释放了读锁的数据,这样当前事务再去读取的时候,就可能读取到被别人修改过的数据了,所以一个人在事务中读取到的某个数据,可能下次读取就变成别的数据啦。这就是不可重复读的意思。。
可重复读:也是个读写锁实现,读锁会阻塞其他人(或机器)的写,于是,只要是事务中读取到得数据,都被加了锁,其他人没办法改他们,于是就实现了可重复读咯。
最后是序列化,就是所有都顺序,一个大锁全部锁住J
持久性(Durability):持久性就是,事务执行后,就丢不了了,就算是整个中国被淹了,机器都没了,数据也不应该丢掉(不过基本做不到这个,也就是一个机器挂了不会丢数据而已。。)所有机房没了那数据也就没了。。
对于这块,给大家一些参考资料:
http://zh.wikipedia.org/wiki/%E4%BA%8B%E5%8B%99%E9%9A%94%E9%9B%A2
http://www.cnblogs.com/wangiqngpei557/archive/2011/11/19/2255132.html
这些讲的不错,浅显易懂是我的最爱.
好啦,为了保证我写的东西不会被”qing”这个大怪兽再次吃掉。。我先发这些。
在下一个章节,我们继续在事务这个领域徜徉,给大家介绍一下,在单机上面,事务是如何进行的。