前段时间加入TopLanguage的Group,发现这里圈子的还有不少朋友认得我。不少朋 友从本科就开始关注,虽然我们并不相识。原以为我的blog会是孤岛,看来自己还是应该花不少时间去更新一下自己的blog了。写blog更多也是对自己 生活,学习和工作的总结。记得最早接触blog的还在是04年初,还记得那个时候因为获得了Microsoft的MVP,认识了微软的Grace,在和她 的交流中才知道原来这个世界上有个叫做blog的东西。
这段时间一直都很忙,因为除了毕业论文外,还在准备参加一个数据库开发的比赛。不过我们可不是用数据库,而是真正地开发数据库系统DBMS。硕士阶段做的 东西主要是Data Mining,KDD方面的比较多。而数据库DBMS应该更多倾向于是System方向。港科大的同学也提议我应该可以去尝试做做System方面,因为 我在做系统实现方面还是有一定的经验和技术。07年在微软的时候,做的东西也是偏向于System,这块领域的确是很实在,做出来的东西都是直接影响工业 界和社会的。后来发现,诸如MIT,Berkerley等牛校在数据库方面都是做System较多。Data Mining,KDD则更多是偏向于机器学习,需要更多的数学理论,而非编程技巧。我本人在此之前发表的3篇学术论文也都是Data Mining方面(我的主页http://cs.scu.edu.cn/~tangliang上 可以直接下载到pdf)。虽说自己的研究方向是数据库与数据挖掘,其实学了3年下来,感觉无论是数据库还是数据挖掘都学得不太好。数据挖掘是一个很大的领 域,硕士3年学不好情有可原。而数据库系统,从本科就在学习,到了硕士阶段又学了一次,可是自己也不敢说真的理解清楚数据库系统。为了参加数据库的开发比 赛,又重新拿起那本经典的教材《Database System Concepts》反复研究,逐步体会到了数据库系统很多以前没有体会到的精髓。
以前的数据库学习,把过多的精力放在了关系代数,关系表设计,范式,SQL等等。而真正属于数据库系统的就只有B+Tree。我相信,现在很多人都写不出来真正的B+Tree。B+Tree的Insert和Search都比较简单,而最复杂的还是Deletion。在SIGMOD1995上甚至还有一篇专门讲解B+Tree的Deletion的论文,《Implementing Deletion in B+ Tree》,这篇文章可以在Stanford的著名女大牛教授Jennifer Wisdom的网站可以下载http://infolab.stanford.edu/~widom/cs346/jannink.pdf。
除开B+Tree外,数据库系统另外一个复杂而重要的部分就是concurrency control。之前参加比赛之前,港科大的同学就劝我去看看Postgres SQL源代码。其中最复杂的部分不是Indexing,而是Concurrency Control混合的代码。记得当年Berkeley的Micheal Stonebraker开启了这个Postgres的 项目,后来霸占了数据库最顶尖的SIGMOD八十年代无数篇papers,于是PostgresSQL也获得一个学院派的数据库称号。而我个人是在看不过 来PostgresSQL的源代码了,自从在cygwin上编译成功之后,看了一些heap file之后,就再也没有碰过了。这次参加的数据库开发比赛的发起人也是这位传说中的神人Micheal Stonebraker,不过他现在已经到了MIT。这里的concurrency control应该分成两部分来看,一部分是indexing,cache, heap file的同步访问,另外一部分就是保持ACID(Atomic,Consistent,Isolation, Duarable)的事务(Transaction)控制。说到Transaction事务的提起,就不得不提到曾经为此拿到图灵奖的 微软的另一位神人,Jim Grey。可能很多人提到这位神人,都会想起他前年在太平洋上失踪的事件。我想,或许他真的是某个外星球派到地球上的神人,帮助人类完成数据库上 Transaction的设计,大功告成后回到自己的星球去了。官方的可信的说法是,他在太平洋上遇到了海盗。海盗可不管他是不是什么数据库神人,还是微 软的首席科学家什么的。在第一部分的数据部分的同步访问,主要涉及到对复杂的数据结构加锁,多线程的技巧等等。它是提高并发性的关键。在网上有很多关于索 引加锁的PPT教程,需要注意的就是加锁的顺序。因为保持加锁顺序是防止死锁的根本保障。比如说,我在实现我们的数据 库系统的时候,对索引树加锁的顺序始终保持从根结点到叶子结点。这里还会涉及到“乐观锁”和“悲观锁”的加锁策略。这些在数据库的教材上都有详细讲解。在 控制事物的ACID方面,数据库的书上主要讲解了两阶段锁(Two-Phase Locking)的策略。这也是现在大部分数据库,SQL SERVER,ORACLE等默认的事物控制原则。一般的教材都有比较严格的讲解。两阶段的协议本身是很简单的,不过要证明两阶段能够实现真正的ACID 却要花掉教材上很多篇幅的讲解。个人感觉两阶段锁在很多时候都过于严格。去年2008年的SIGMOD best paper: Serializable Isolation for Snapshot Databases(http://www.sigmod.org/sigmodinfo/awards/#bestpaper)都还在研究多版本控制,snapshot的事物控制方式。其实说到多版本控制的事务实现,最直观的体会就是大家常用的源代码版本控制软件CVS,SVN。它能够保证大家任何时候都能读和写其中源代码,只是最后commit的时候提示你冲突。对于数据库系统来说,如果commit冲突了,无非也就abort其中一个transaction,再执行一遍。而CVS,SVN则要求用户自己去解决这个冲突。
除开索引和事务控制外,数据库系统其他部分的东西就是Cache和Heap file,而这两部分相对简单一些。因为在其他很多存储系统上,Cache都经常用到,诸如什么最近最少的替换原则,在操作系统的课程上都讲了很多。其 实,国外某些大学甚至把操作系统和数据库系统两门课程放到一起来讲解。而Heap file似乎很少在国内的数据库教材上看到。Heap file本身也没多大的技术含量,只是我们不能忘了,真的数据都是存在heap file内的。以前还有人提出sort file。不过sort file虽然search时候更快,但是插入删除的时候需要移动的数据实在太多。不要忘了Heap File和Sort File都是在外存的介质上,移动数据的效率是十分低的。所以现在所有的数据库系统SQL SERVER,ORACLE,MYSQL等都用Heap file。
国内的数据库系统课程设计,几乎都只是讲讲书本上的东西。而国外诸如MIT这些牛校,将每门课程的时候都要求学生动手去做一个实际的系统出来。MIT在他们的OpenCourse网站上的Database System课程里面,就要求学生动手实现一个叫做TinyDB的小数据库系统。