海量存储系列之三

首先是回答上次的问题。

假设有这么一组数据,性别有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”这个大怪兽再次吃掉。。我先发这些。

在下一个章节,我们继续在事务这个领域徜徉,给大家介绍一下,在单机上面,事务是如何进行的。

本文来源于"阿里中间件团队播客",原文发表时间" 2011-12-10 "

时间: 2025-01-14 23:47:39

海量存储系列之三的相关文章

海量存储系列之八

首先来回答一个问题:为什么在磁盘中要使用b+树来进行文件存储呢? 原因还是因为树的高度低得缘故,磁盘本身是一个顺序读写快,随机读写慢的系统,那么如果想高效的从磁盘中找到数据,势必需要满足一个最重要的条件:减少寻道次数. 我们以平衡树为例进行对比,就会发现问题所在了: 先上个图 这是个平衡树,可以看到基本上一个元素下只有两个子叶节点 抽象的来看,树想要达成有效查找,势必需要维持如下一种结构: 树的子叶节点中,左子树一定小于等于当前节点,而当前节点的右子树则一定大于当前节点.只有这样,才能够维持全局

海量存储系列之十一

上一期我们主要在介绍hash相关的切分方式,那么这次我们来看一下有序结构的切分 有序结构的拆分,目前主要就是使用树或类似树的结构进行拆分,这里主要就是指HBase和MongoDB. 使用树结构切分,带来的好处就如hbase和mongoDB的宣传标语一样,可以无缝的实现自由扩展.但反过来,带来的问题其实也不少,下面我们一起来看一看吧. 首先复习B树知识http://qing.weibo.com/1765738567/693f0847330008ii.html 在B树中,最关键的处理逻辑是如果单个节

海量存储系列之九

终于来到了COLA树系,这套东西目前来看呢,确实不如LSM火,不过作为可选方案,也是个值得了解的尝试,不过这块因为只有一组MIT的人搞了个东西出来,所以其实真正的方案也语焉不详的.从性能来说,tokuDB的写入性能很高,但更新似乎不是很给力,查询较好,占用较少的内存. http://www.mysqlperformanceblog.com/2009/04/28/detailed-review-of-tokutek-storage-engine/ 这里有一些性能上的指标和分析性文字.确实看起来很心

海量存储系列之十二

本章,我们主要来讨论数据的管理和扩容中最重要的一个部分,数据迁移. 数据迁移是数据运维中最为重要的一个部分,在前面的文章中已经提到过,作为有状态的数据节点,在互联网行业的主要追求就是,无限的水平扩展能力,这种水平扩展,主要用于解决两类问题,一类是磁盘空间不足的问题,一类是性能不足的问题. 为了达到这种能力,一般来说主要也就是这样一个思路,尽可能的让数据不动,只通过规则变动的方式来完成扩容,如果这种方式无法满足要求,那么再通过移动数据的方式,来满足其他的一些需求. 下面来进行下分析. 只通过变动规

海量存储系列之十三

在上一章中,我们主要介绍了规则引擎中最重要的一个部分,自动扩容,在今天的章节,我们主要还是介绍一下我们在淘宝TDDL中的工程实践吧. 首先从原理开始吧. 规则引擎是什么呢? 对应在上述例子里面,其实就是DBNum = pk % 3 这个规则. 他的变化可能很多,比如对于一致性hash则变为一个if - else 的表达式(见前面) 也可能有其他的变化. 所以,我们要回归本源,问一个问题,什么是规则引擎? 抽象来看,规则引擎在做的事情是,根据一组输入条件(例如主键id,或者用户id+时间,或者一个

海量存储系列之七

在上一个章节,我们阐述了分布式场景下,事务的问题和一些可能的处理方式后,我们来到了下一章节 Key-value存储 这一章,我们将进入k-v场景,其实,在大部分场景下,如果某个产品宣称自己的写读tps超过其他存储n倍,一般来说都是从k-v这个角度入手进行优化的,主要入手的点是树的数据结构优化和锁的细化,一般都能在一些特定的场景获得5-10倍的性能提升.由此可见key-value存储对于整个数据存储模型是多么的重要. 好吧,那么我们来进入这个章节,用最简单和浅显的话语,阐述这些看起来很高深的理论吧

海量存储系列之四

单机事务: 其实在上面介绍ACID的时候 我们已经提到了一种最简单的实现方式,就是锁的实现方式. 从原理来看,事务是个变态而复杂的事情.其实如果是序列化的话呢,那么实现起来一定是非常简单的. 但问题就在于,这样性能实在比较低,于是,就有了非常多的方案,为了能哪怕减少一个地方的锁,或者降低一个地方的锁的级别,就付出大量的时间和代码加以实现. 那么,让我们以崇敬的心情,去拜读一下他们的劳动成果吧~ 在上一篇中,我们谈了事务管理的四个核心要素,其中有两个要素是和性能紧密相关的,其实也就是需要涉及到锁的

海量存储系列之一

一个数据库,我们可以抽象的认为由下面的一个逻辑结构组成,刨除意义不大的视图,存储过程,外键限制等之后,我们就剩下了下面的这张图: 从API来说,也就是SQL,结构化查询语言,这个东东我们后面再去细说,先来看看这个关系代数模型. 之所以要从这里开始,主要的原因是因为,这是最受到关注的一个部分,自大从一开始做分布式数据层开始,被人问得最多的问题就是:1. 切分以后如何做join.2.如何进行分布式事务.. 可惜,现在我也没有一个方法能做到100%让您满意..因为,没有银弹,只有取舍. 取舍的原则,也

海量存储系列之六

上次我们讲到,单机事务个我们面临的问题,下面我们来说一些我所知的解决的方法. 在我开始做淘宝数据层的时候,被问得最多的无非也就是:如何做事务,如何做join.至今仍然如此,我一般都会简单而明确的跟对方说:没有高效的实现方法. 虽然没有高效的实现,但实现还是有的.作为引子,我们先来介绍一下这种实现的方式. 我们仍然以上一次讲到的bob和smith为例子来说明好了. 开始的时候.Bob要给smith100块,那么实际上事务中要做的事情是 事务开始时查询bob有多少钱.如果有足够多的钱让bob的账户