后来者可以充分利用前人的成果,在开发界,我们也会这样做。我们可以发现很多.NET的开源项目都是从优秀的Java项目移植过来的:我用得比较多像NHibernate、DotLucene(暂停开发...)、iTextSharp、Quartz.NET等。移植总比从头写轻松多了,不是吗?
数据存储是软件中不可或缺的组成部分。我们所熟知和使用的,以前有Access,现在有MS SQL Server、Oracle、DB2这些商业数据库,开源的有PHP用得最多的MySQL,有趣的是PHP内置了SQLite。比较少用的如Firebird、PostgreSQL、Berkeley DB(Berkeley DB for .NET)等。
几年前我写了一些开源项目的随笔,数据库是其中一种,不过当时还没有出现成熟的.NET开源数据库,写得最多的倒是在嵌入式应用最广泛c写的SQLite。我对嵌入式/轻量级的数据库有情结,对SQLite尤甚。SQLite的应用非常广泛,如官方所说的诺基亚开源手机操作系统塞班(Symbian)、Mozilla、Safari、Chrome和非常多的桌面应用等。后来出现了ADO.NET Provider for SQLite(for .Net 1.x的,现在停止开发),最后出现了现在.NET程序使用最多的来自phxsoftware的System.Data.SQLite,最出名的应用者估计就是飞信了。除了稍微显得有点重口味的System.Data.SQLite,我们还有非常轻口味的sqlite-net。sqlite-net还是封装了SQLite.dll,不过它只了16K的代码,而且是OO方式存取数据,可以认为是一个简单的ORM。不过,这些都不是开源的.NET数据库,充其量其实包装(wrapper),而且是最原始的那种InterOp的做法,连Managed C++都不是。.NET都发展了9年多了,是时候有一个像样的数据库了。即便不是原创的,从Java移植一个成熟的也是不错的。
差不多那个时候,出现了一个人,Mark Tutt,写了第一个.NET数据库(据我所知):SharpHSQL,这是从Java界应用非常广泛的HSQLDB移植过来的,而HSQLDB又是从HSQL衍生过来的,不过这是另外一个话题了。Mark Tutt移植完了就不继续维护了,这倒不是大问题,问题是他移植的版本根本保存不了数据到文件(所谓的持久化),在内存中跑完,程序关闭就没了,根本就没法用(你只想用纯内存版另当别论)。
HSQL,这就是SharpHSQL的前世,但今生呢?Mark Tutt之后,andresv接过了SharpHSQL,并让它成功地让数据保存到文件。感谢上帝,终于有一个纯.NET的数据库了。另外说一下,andresv还是另外一个不大出名的ORM-Retina.NET OR/M的作者。
可以预想到的是,andresv继承了Mark Tutt的“光荣传统”,在项目移植完了就不再维护了,以至于HSQLDB发展得红红火火的,SharpHSQL还像个玩具那样弱不禁风。
在HSQL的薪火貌似终止的时候,出现了一个庞然大物让我眼前一亮:Minosse Relational DataBase System,一个大型的纯C#开源数据库系统。嗯,不是单纯的引擎,是系统。可惜,开源界最臭名昭著的噩梦又发生在Minosse身上,在经过短暂的狂喜之后,便失去了继续开发的动力。
开源界的.NET数据库再次陷入了静寂。
直到今年,再次风起云涌,一下子冒出了3个重量级的项目:csharp-sqlite、EffiProz、DeveelDB。
首先说说csharp-sqlite,相信部分同学已经对这个项目有一些了解:这是SQLite最新版本的C#移植版,虽然其作者Noah Hart认为这不能算是移植,而是用C#模拟C。这个移植版是100%二进制兼容SQLite数据库格式的,所以你可以用它来读写SQLite创建的数据库。该作者曾说,这只是一个为了学习C#的练手项目,而且一练就2年多,估计都练到九重天了吧。总的来看,这个作者相当重口味。
同学们肯定想知道这个这个项目的性能:
Aug 21, 2009 Updated to 3.6.17
小型数据库
# 记录数 | 插入 | 查询 2X | 循环 2X | 删除 | |
SQLite | 100,000 | 2.2s | 3.5s | 0.3s | 2.0s |
C#-SQLite | 100,000 | 5.7s | 4.1s | 0.3s | 4.3s |
C#/SQLite | 2.6x | 1.2x | 1.0x | 2.2x |
大型数据库
# 记录数 | 插入 | 查询 2X | 循环 2X | 删除 | |
SQLite | 1,000,000 | 42.8s | 43.3s | 3.0s | 35.5s |
C#-SQLite | 1,000,000 | 116.0s | 60.0s | 2.9s | 89.2s |
C#/SQLite | 2.7x | 1.4x | 1.0x | 2.5x |
简单的来看,检索/循环的速度跟SQLite差异不大,插入和删除就只有SQLite的50%不到。
除此之外,最关心的还是怎样获取代码。请访问这里获取代码,csharp-sqlite比较特别,没有采用常见的CVS、SVN这两种项目代码控制服务,而用了比较冷门的HG,不过跟TortoiseCVS、TortoiseSVN一样,我们还有TortoiseHg,不过同样地让人不爽的是:TortoiseHg一样会强制关闭Explorer.exe来让资源管理器插件生效,现在的安装程序都把自己当大爷,颇为毫不客气。当然,你也可以直接点击这里下载,内含最新代码和已编译DLL。
在使用TortoiseHg获取代码之后,就会遇到编译问题,如果你新建一个项目,把*.cs放进去,然后编译,问题就会出来了,因为csharp-sqlite一样学了c那套复杂的编译条件。
不过,需要注意的是,csharp-sqlite只是Noah Hart的个人行为,跟SQLite的官方没有任何关系,所以当初为了这个项目的名称,还跟SQLite之父D. Richard Hipp鱼雁传情好几回,最后在承诺撇清与SQLite的官方关系之后(就是不想做额外的售后服务),才得了这个名字。可见D. Richard Hipp还相当懒惰的。
csharp-sqlite的实际使用并不是传统的ADO.NET那样,因为它没有提供这个接口,你只能直接调用跟所谓的Native接口。当然,作者还是做了一些封装,你可以用类似Command接口的SQLiteDatabase,进行ExecuteQuery(返回DataTable)、ExecuteNonQuery。
另外,csharp-sqlite的稳定性还是让人担心的,虽然作者宣称已经通过了SQLite官方的99.99%的测试,但他却是这样回答是否可以在正式产品中使用的:“我也想知道,如果你用了,请告诉我情况。”
有趣的是,Tim Anderson弄了个在Silverlight跑的Quick and dirty版本,不过这仅仅是一个概念验证罢了,因为屏蔽了原来csharp-sqlite中为了实现文件锁而调用的Win32 API,只能单线程跑。值得一说的是,这厮抢注了这个域名相当不错。
最后,我对于作者连基本的代码和编译好的压缩包都不提供这种行为表达相当的不爽和最强烈的反对。
ToDo in .NET开源数据库的前世和今生(下):
1.EffiProz
2.DeveelDB
3.DB40
4.Perst4net
5.其它开源数据库
6.比较
7.n个为什么