三大嵌入式开源数据库对比,哪款适合你?
【引言】
最近收到一个调研需求,就是关于Apache Derby的替换研究。由于其最新的发布版本时间为2019年3月11日,已经有超过一年没有更新了。所以有必要对其进行可行性的替换研究。本文我们就来探索一下这个问题。
【Apache Derby】
Apache Derby,以前名称为IBM Cloudscape, 是Apache软件基金会开发的关系型数据库管理系统(RDBMS),它的特点是可以嵌入到Java程序中,用于在线事务处理。它的磁盘空间占用率非常小: 3.5M左右。
Apache Derby使用的是在Apache 2.0许可证。
有一段时间,Oracle公司以Java DB的名称发布了同样的二进制文件。 但是,2015年6月,Oracle宣布从JDK 9开始不再继续这样的发布。
【官方网站】
【License】
Apache License 2.0
【最新发布】
10.15.1.3 于 2019年3月11日
【Derby 技术特点】
Derby嵌入式数据库引擎
该技术的核心是Derby数据库引擎,是一个全功能的关系型嵌入式数据库引擎,支持JDBC和SQL的API访问。使用了IBM DB2 SQL语法。
Derby网络服务器
Derby网络服务器通过提供传统的客户端服务器功能,增加了Derby数据库引擎的覆盖范围。其网络服务器允许客户机使用标准的DRDA协议通过TCP/IP进行连接。该网络服务器允许Derby引擎支持网络化的JDBC、ODBC/CLI、Perl、Derby数据库引擎。
嵌入式网络服务器
嵌入式数据库可以被配置为混合服务器或者嵌入式RDBMS。 除了在同一JVM中的客户端外,还可以接受来自其他客户端的TCP/IP连接。
数据库实用工具
ij:是一个允许对任何JDBC数据库执行SQL脚本的工具。
dblook: 用于Derby数据库的设计定义进行提取的工具。
sysinfo: 实用工具,用于显示版本号和类路径。
【SQLite】
SQLite是一个基于C语言编写的关系型数据库管理系统,是一个程序库。与许多其他的数据库系统不同,SQLite 并不是一个客户端服务器数据库系统,它是被嵌入到终端程序中的。
SQLite兼容ACID (原子性、一致性、隔离性、耐久性),可以使用大部分的SQL标准,一般遵循PostgreSQL的语法。
但是,SQLite使用的是动态的、弱类型化的SQL语法,不能保证域的完整性,这就意味着,可以将一个字符串插入到定义为整数的列中。
SQLite会在适当的情况下尝试将数据在格式之间进行转换,在这种情况下,将字符串 "123 "转换为整数,但不保证这种转换,如果不能进行这种转换,则会将数据按原样存储。
SQLite作为嵌入式数据库软件, 可以说是部署得最广泛的数据库引擎,已经被一些浏览器、操作系统和嵌入式系统(如手机)等广泛使用。
【官方网站】
【License】
Public Domain
【最新发布】
3.31.1 于 2020年1月27日
【SQLite 设计思想】
与客户端-服务器数据库管理系统不同,SQLite引擎没有独立的进程与应用程序进行通信。
相反,SQLite库被链接进来成为应用程序程序的一个组成部分。链接可以是静态的,也可以是动态的。
应用程序可以通过简单的函数调用来使用SQLite的功能,这样可以减少数据库访问的延迟:
在单个进程内的函数调用比进程间通信更有效率。
SQLite将整个数据库(设计定义、表、索引和数据本身)作为一个单一的跨平台文件存储在主机上。它通过在写入过程中锁定整个数据库文件来实现这种简单的设计。
SQLite的读操作可以是多任务的,不过写操作只能按顺序进行。
由于无服务器的设计,SQLite应用比客户端-服务器数据库所需要的配置要少。
SQLite之所以被称为zero-conf,是因为它不需要服务管理(如启动脚本)或基于grant和密码的访问控制。
访问控制是通过赋予数据库文件系统本身的文件系统权限来处理的。客户端-服务器系统中的数据库使用的是文件系统权限,这种权限只给守护进程提供数据库文件的访问权限。
无服务器设计的另一个含义是,几个进程可能无法对数据库文件进行写入操作。
在基于服务器的数据库中,几个写入者都会连接到同一个守护进程,而守护进程能够在内部处理中使用事务锁。
SQLite则不得不依赖文件系统锁。它无法支持同时访问数据库的多个进程。
因此,SQLite并不是写密集型部署的首选。
然而,对于简单的查询,几乎没有什么并发性的查询,SQLite的性能是很高的,这得益于它的设计思想避免了将数据传递给其他进程的开销。
SQLite使用PostgreSQL作为参考平台。
一个主要的不同是,除了主键之外,SQLite不强制执行类型检查;值的类型是动态的,不受设计定义的严格约束。在存储时,如果数据类型转换是潜在的可逆的, 那么数据类型转换可能被触发)。
SQLite努力遵循Postel规则。
【SQLite功能】
【SQL支持】
SQLite实现了SQL的大部分SQL-92标准,但也有一些缺失。
例如,它部分地提供了触发器功能,不能写入到视图。
虽然它提供了复杂的查询,但由于它不能修改或删除列,所以它的ALTER TABLE功能有限。
【类型系统】
对于一个与SQL兼容的DBMS来说,SQLite使用了一个不寻常的类型系统。
它不像大多数SQL数据库系统那样给一个列分配类型,而是将类型分配给单个值。
从语言上来说,它是动态类型化的。
此外,它的弱类型化方式与Perl一样:人们可以将字符串插入到整数列中。
此时,如果列的首选类型是整数的话,SQLite会先尝试将字符串转换为整数。
这增加了列的灵活性,特别是当绑定到动态类型化的脚本语言中时。
然而,这种技术并不能移植到其他SQL产品中。一个常见的批评是,SQLite的类型系统缺乏其他产品中静态类型化列所提供的数据完整性机制。
SQLite网站描述了一种 "严格的亲和力"的模式,但这个功能模式还没有被添加进去。
目前,可以通过像CHECK(typeof(x)='integer')这样的约束来实现类型强制。
【主键表】
表通常包括一个隐藏的rowid索引列,它可以提供更快的访问速度。
如果数据库中包含一个Integer 主键(Primary Key)列,SQLite通常会通过将其作为rowid的别名来优化,使其内容作为一个严格键入的64位有符号整数来存储,并改变其行为,使其变为自动递增列。
未来的SQLite的版本可能会包含一个命令来自查一个列是否有类似于rowid的行为,以区分这些列与弱类型的、非自动递增的整数主键。
【Unicode】
Unicode功能在SQLite中是可选的。
【并发性】
多个计算机进程或线程可以并发访问同一个数据库。
可以并行满足多个读访问。
写访问只能在当前没有其他访问的情况下才能进行。
否则,写访问会失败并返回错误代码,或者可以自动重试,直到可配置的超时结束。
在处理临时表时,这种并发访问的情况会发生变化。在3.7版本中,当开启了写前记录(WAL)启用并发读和写时,这种限制就会放宽。
【全文搜索】
SQLite的3.7.4版本首先加入了FTS4(全文搜索)模块,该模块的特点是比老版本的FTS3模块增强了。
FTS4允许用户对文档进行全文搜索,类似于搜索引擎对网页的搜索方式。
【无rowid表】
3.8.2版本增加了对创建无rowid表的支持,这会带来空间和性能上的改进。
【表达式支持】
SQLite的3.8.3版本中增加了对通用表表达式的支持。
【Json支持】
2015年,随着json1的扩展和新的子类型接口,SQLite 3.9版本引入了JSON内容管理。
【SQLite开发与工具】
SQLite的代码由Fossil托管,Fossil是一个分布式版本控制系统,它本身就是建立在SQLite数据库基础上的。
在SQLite的发行版中提供了一个独立的命令行程序。它可以用来创建数据库,定义表,插入和更改行,运行查询和管理SQLite数据库文件。它本身还可以作为编写使用SQLite库的应用程序的参考。
SQLite在每次发布之前都会使用自动衰退测试。作为一个版本的验证的一部分,有超过200万个测试会被运行。从2009年8月10日发布的SQLite 3.6.17版本开始,SQLite版本的分支测试覆盖率达到100%。
这些测试和测试线束一部分是公共领域的,另一部分是不公开的。
【经典用例】
l 中间件
n ADO.NET适配器,最初由Robert Simpson开发,自2010年4月起与SQLite开发人员共同维护。
n ODBC驱动由Christian Werner开发并单独维护, Werner的ODBC驱动是OpenOffice.org推荐的访问SQLite的连接方式。
n 在Windows上,SQLite被称为COM(ActiveX)封装器,可在JScript和VBScript等脚本语言中访问。这为HTML应用程序(HTA)增加了SQLite数据库的功能。
l 网络浏览器
n 浏览器Google Chrome、Opera、Safari和Android浏览器都允许使用Web SQL数据库技术在浏览器内的SQLite数据库中存储信息,并在该数据库中检索信息,尽管这种技术正在迅速被淘汰(即将被IndexedDB取代)。
n Mozilla Firefox和Mozilla Thunderbird在内部管理的SQLite数据库中存储各种配置数据(书签、cookie、联系人等)。在Firefox 57版("Firefox Quantum")问世之前,有一个第三方的附加组件,利用支持该功能的代码提供了一个管理任意SQLite数据库的用户界面。
n 一些第三方插件可以利用JavaScript API来管理SQLite数据库。
l 网络应用框架
n Laravel
n Bugzilla
n Django的默认数据库管理系统
n Drupal
n WordPress
n Trac
n Ruby on Rails的默认数据库管理系统
n web2py
l 其他应用
n Adobe Systems在Adobe Photoshop Lightroom中使用SQLite作为文件数据库,这是Adobe AIR中的标准数据库,在Adobe Reader内部也是如此。
n Evernote使用SQLite来存储Windows中的本地数据库存储库。
n Skype
n 服务管理设施,用于Solaris和OpenSolaris操作系统内的服务管理。
n Flame(malware)
n BMW IDrive卫星导航系统
l 操作系统
l SQLite默认在
n 黑莓10操作系统
n Symbian OS
n 诺基亚的Maemo
n 谷歌的Android
n Linux 基金会的 MeeGo
n LG的webOS
n NetBSD
n FreeBSD,从2014年1月的10-RELEASE版本开始,被核心包管理系统使用。
n illumos
n 在Oracle Solaris 10中,服务管理设施数据库被用于启动序列化。
n 苹果公司从Mac OS X 10.4开始,在macOS的Core Data API中采用了它作为一个选项,在Mac OS X 10.4以后的原始实现中,苹果也采用了它作为管理视频和歌曲的选项,在iOS中也采用了它作为存储iPhone上的文本信息的选项。
n MorphOS自3.10版本起
n Tizen
n Windows 10
【H2】
H2是一个用Java编写的关系型数据库管理系统。它可以嵌入到Java应用程序中,也可以在客户端-服务器模式下运行。
它以开放源码软件Mozilla Public License 2.0或Eclipse Public License的形式提供。
【官方网站】
【License】
Eclipse Public License/Mozilla Public License 2.0
【最新发布】
1.4.1.20 于 2019年10月14日
【H2主要功能】
【API】
支持SQL(结构化查询语言)标准的一个子集。
主要的编程API是SQL和JDBC, 也支持使用PostgreSQL ODBC驱动,其作用类似于PostgreSQL服务器。
【表格介质】
它既可以在内存建表,也可以磁盘上的建表。
表可以是持久的,也可以是临时的。
【索引】
内存表索引类型是哈希表和树型,
磁盘表索引类型是b-树型。
【事务处理】
它所有的数据操作都是事务性的。 实现了表级锁定和多版本并发控制。同时支持2阶段提交协议,但没有实现分布式事务的标准API。
【安全特性】
数据库的安全特性有:
基于角色的访问权限,
密码使用SHA-256加密,
数据使用AES或Tiny Encryption Algorithm XTEA加密。
这些加密特性也可以作为数据库内部的功能来使用。
在客户端-服务器模式下,以及使用控制台应用程序时,支持SSL/TLS连接。
【全文搜索】
它包含两个全文搜索功能,一个是本地实现,一个是使用Lucene。
【高可用性】
它实现了一种简单的高可用性:
在客户端-服务器模式下使用时,数据库引擎支持热故障转移,这通常被称为集群,但需要在故障后必须手动启用集群模式才可以。
【强制参数】
数据库通过强制使用参数化语句,支持SQL注入侵入风险的保护。在H2中,这个功能被称为 "禁用字面符号(disabling literals)"。
【Google App Engine】
从1.1.111版本开始,H2内存内数据库可以在Google App Engine内部运行。
【H2在断电情况下面临的耐久性问题】
H2文档详细解释了底层硬件特别是电源系统的问题可能会影响耐久性。
根据H2文档的介绍,这些问题不仅与数据库引擎设计有关,还与存储缓存机制有关。由于存储设备为了提高速度而使用写缓存,在断电的情况下,设备缓存中的数据会丢失。这时,管理员要根据业务需求,评估速度和数据丢失风险之间的共同权衡,必须仔细考虑关键服务器的电源和UPS的设计。
在某些情况下,可以强制使用fsync来进行写缓存,这样可以减缓写入速度,或者客户可以接受在断电的情况下带来的一定数据丢失风险。
当然使用fsync的效果有限,因为很多硬盘的出厂默认是启用了写缓存,在这种情况下,无论是数据库的设计或设置,还是操作系统级别的命令,都无法完全杜绝突然断电时数据丢失或不一致的可能性。
通过操作系统和硬件设置来禁用所有的缓存,以便实时写入数据,会对性能产生很大的影响,因为当使用旋转磁盘时,每秒只有100次左右的写入操作。
H2文档详细描述了在断电情况下,事务处理的耐久性会受到影响。
考虑到在突然断电的情况下保存数据的硬件限制,同时开发人员通常又没有防止这类损失的有效手段,许多数据库引擎默认情况下不会为每个提交调用FileDescriptor.sync()或FileChannel.force()或fsync或类似的方法。
因为它们会显著降低系统性能, 又不会显著提高耐久性。
HSQLDB文档中参考了类似问题的变通方法。
微软知识库描述了这些问题,如电源故障、写缓存等对性能和耐久性的影响等等。
该知识库也讨论了性能和磁盘写缓存的脆弱性之间的权衡,以及管理员如何设置来平衡这些问题。
【H2工具】
H2有一个基于浏览器的控制台应用程序,以及一套启动和停止服务器、备份和恢复数据库的命令行(Shell)工具。
【三者对比表格】
名称 |
Derby |
H2 |
SQLite |
描述 |
全功能的RDBMS,占用空间小,可以嵌入到Java应用程序中,也可以作为数据库服务器使用。 |
全功能的RDBMS,占用空间小,可以嵌入到Java应用程序中,也可以作为数据库服务器使用。 |
广泛使用的进程内RDBMS |
实施语言 |
Java |
Java |
C |
服务器操作系统 |
所有带Java VM的操作系统 |
所有带Java VM的操作系统 |
无服务器 |
XML 支持 |
是 |
不 |
不 |
API和其他访问方法 |
JDBC |
JDBC |
ADO.NET |
支持的编程语言 |
Java |
Java |
Actionscript |
服务器端脚本 |
Java存储过程 |
Java存储过程和用户定义的函数 |
无 |
复制方法 |
主从复制 |
使用集群:不同计算机上的2台数据库服务器在数据库的相同副本上运行。 |
无 |
一致性概念 |
即时一致性 |
即时一致性 |
|
并发性 |
是 |
是,多版本并发控制(MVCC) |
是 |
用户概念 |
细粒度的访问权限,符合SQL标准 |
细粒度的访问权限,符合SQL标准 |
no |
最新发布 |
10.15.1.3 于 2019年3月11日 |
1.4.1.20 于 2019年10月14日 |
3.31.1 于 2020年1月27日 |
【小结】
本文对三个主流的嵌入式开源数据库系统进行了探索,对于Derby数据库的替换可以参考上述介绍和表格,同时结合自身的业务需求:
1. 哪些功能是可以用哪些数据库替换的?
2. 有没有特殊要求是其他数据库不能提供而必须使用Derby的?
如果存在第二种情况的话,团队可以结合自身能力,在Derby的基础上进行自研。
希望本文对业务开发有指导作用, 并对大家有所裨益。
欢迎讨论。
- 点赞
- 收藏
- 关注作者
评论(0)