嵌入式数据库(Embedded Database)和数据库服务器(Database Server)

像Oracle、Sybase、MySQL和SQL Server这些大家熟知的数据库都属于数据库服务器(当然不排除某些也提供嵌入式版本),而像SQLite、Berkeley DB等属于嵌入式数据库。 嵌入式数据库跟数据库服务器最大的区别在于它们运行的地址空间不同。通常,数据库服务器独立地运行一个守护进程(daemon),而嵌入式数据库与应用程序运行在同一个进程。

数据库服务器的架构

数据库客户端通常通过数据库驱动程序如JDBC、ODBC等访问数据库服务器,数据库服务器再操作数据库文件。 数据库服务是一种客户端服务器模式,客户端和服务器是完全两个独立的进程。它们可以分别位于在不同的计算机甚至网络中。客户端和服务器通过TCP/IP进行通讯。这种模式将数据与应用程序分离,便于对数据访问的控制和管理。

嵌入式数据库架构

嵌入式数据库不需要数据库驱动程序,直接将数据库的库文件链接到应用程序中。应用程序通过API访问数据库,而不是TCP/IP。因此,嵌入式数据库的部署是与应用程序在一起的。比如常见的版本控制器SubVersion,它所用的嵌入式数据库就是跟应用程序放在一起的。

区别

数据库服务器和嵌入式对比如下: (1)数据库服务器通常允许非开发人员(DBA,数据库库管理员)对数据库进行操作,而在嵌入式数据中通常只允许应用程序对其进行访问和控制。 (2)数据库服务器将数据与程序分离,便于对数据库访问的控制。而嵌入式数据库则将数据的访问控制完全交给应用程序,由应用程序来进行控制。 (3)数据库服务器需要独立的安装、部署和管理,而嵌入式数据通常和应用程序一起发布,不需要单独地部署一个数据库服务器,具有程序携带性的特点。

嵌入式数据库

  1. 嵌入在进程中执行,不需要单独引擎。
  2. 可定制、体积小,满足嵌入式系统需求。

市场上常见的嵌入式数据库

Berkeley DB(开源,商用收费)

Berkeley DB可以保存任意类型的键/值对(Key/Value Pair),而且可以为一个键保存多个数据。Berkeley DB支持让数千的并发线程同时操作数据库,支持最大256TB的数据,广泛用于各种操作系统,其中包括大多数类Unix操作系统、Windows操作系统以及实时操作系统

技术特点

  1. Berkeley DB是一个开放源代码的内嵌式数据库管理系统,能够为应用程序提供高性能的数据管理服务。应用它程序员只需要调用一些简单的API就可以完成对数据的访问和管理。(不使用SQL语言)
  2. Berkeley DB为许多编程语言提供了实用的API接口,包括C、C++、Java、Perl、Tcl、Python和PHP等。所有同数据库相关的操作都由Berkeley DB函数库负责统一完成。
  3. Berkeley DB轻便灵活(Portable),可以运行于几乎所有的UNIX和Linux系统及其变种系统、Windows操作系统以及多种嵌入式实时操作系统之下。Berkeley DB被链接到应用程序中,终端用户一般根本感觉不到有一个数据库系统存在。
  4. Berkeley DB是可伸缩(Scalable)的,这一点表现在很多方面。Database library本身是很精简的(少于300KB的文本空间),但它能够管理规模高达256TB的数据库。它支持高并发度,成千上万个用户可同时操纵同一个数据库。Berkeley DB能以足够小的空间占用量运行于有严格约束的嵌入式系统。
    Berkeley DB在嵌入式应用中比关系数据库和面向对象数据库要好,有以下两点原因: (1)因为数据库程序库同应用程序在相同的地址空间中运行,所以数据库操作不需要进程间的通讯。在一台机器的不同进程间或在网络中不同机器间进行进程通讯所花费的开销,要远远大于函数调用的开销; (2)因为Berkeley DB对所有操作都使用一组API接口,因此不需要对某种查询语言进行解析,也不用生成执行计划,大大提高了运行效率。

SQLite(开源,商用免费) 轻量级别数据库SQLite的主要特点:

  1. 支持事件,不需要配置,不需要安装,也不需要管理员;
  2. 一个完整的数据库保存在磁盘上面一个文件,同一个数据库文件可以在不同机器上面使用,最大支持数据库到2T,字符和BLOB的支持仅限制于可用内存;
  3. 整个系统少于3万行代码,少于250KB的内存占用(gcc),大部分应用比目前常见的客户端/服务端的数据库快,没有其它依赖
  4. 源代码开放,代码95%有较好的注释,简单易用的API。官方带有TCL的编译版本。
  5. 功能完善:支持ACID(Atomicity 、Consistency、Isolation、Durability)事务, Atomicity(原子性)、Consistency(一致性)、Isolation(隔离性)和Durability(持久性)是一个支持事务(Transaction)的数据库系统必需要具有的四种特性,否则在事务过程(Transaction processing)中无法保证数据的正确性,交易过程很有可能达不到交易方的要求。SQLite支持大多数的SQL92,即支持触发器、多表和索引、事务、视图,还支持嵌套的SQL。SQLite数据库存储在单一的磁盘文件中,可以使不同字节序的机器进行自由共享,支持数据库的大小可以达到2TB。

Empress(商业数据库)

开发阶段特点:

  1. 可嵌入程序,该特性使应用程序和数据库工作于统一地址空间,增强了系统的稳定性,提高了系统的效率。
  2. 确定的响应时间,Empress 可以使数据的响应时间相对一致,使用者可以设定一个超时限制,如果在规定时间内没有完成插入,修改等操作,系统会报错。
  3. 快速的操作Empress 提供了内核级的CAPI,称为MR, 用MR编写的应用程序在执行时不需要解析。另外在MR中加速的机制还包括优秀的加锁控制,内存管理和基于记录数量的选择功能。
  4. 灵活的开发方式,Empress 提供多种开发接口,加快开发进程而无需开发者重新学习开发语言和熟悉开发环境。
  5. 友好的存储方式,Empress 数据库可以放在操作系统支持的任何存储设备中,Empress的表单甚至可以分割放在不同的存储设备中,比如在内存,硬盘和CD-ROM中。
  6. 微型内核结构 Empress 高度单元化, 可根据需要选择需要的单元,从而缩小产品中Empress 数据库所占用的资源。
  7. 宽广的平台支持,Empress 支持多种硬件平台和软件平台, 也可移植到客户要求的硬件平台或操作系统

技术优势:

  1. 微型内核结构,占用少量内存空间,特别适合紧凑性的设计
  2. 一周7天,每天24小时连续工作,无需任何额外操作免维护
  3. 内核级 CAPI 接口,使运行速度最大化
  4. 高度灵活的SQL接口
  5. 优秀的掉电恢复能力
  6. 强壮的交易和锁存机制
  7. 支持SCSI,RAID,IDE,RAM,CD-RW,DVD-ROM,CF,等存储介质
  8. 支持Unicode 码
  9. 引擎可加载于磁盘和内存

eXtremeDB eXtremeDB特点:

  1. 内存数据库,eXtremeDB将数据以程序直接使用的格式保存在主内存之中,不仅剔除了文件I/O的开销,也剔除了文件系统数据库所需的缓冲和Cache机制。其结果是每个交易一微秒甚至更少的极限速度,相比于类磁盘数据库而言,速度成百上千倍地提高。作为内存数据库,eXtremeDB不仅性能高,而且数据存储的效率也非常高。为了提高性能并方便程序使用,数据在eXtremeDB中不做任何压缩,100M的空间可以保存高达70M以上的有效数据,这是其他数据库所不可想象的。
  2. 混合数据库,eXtremeDB不仅可以建立完全运行在主内存的内存数据库,更可以建立磁盘/内存混合介质的数据库。在eXtremeDB,我们把这种建立在磁盘、内存或磁盘+内存的运行模式称为eXtremeDB Fusion融合数据库。eXtremeDB Fusion兼顾数据管理的实时性与安全性要求,是实时数据管理的台阶性进步。
  3. 嵌入式数据库,eXtremeDB内核以链接库的形式包含在应用程序之中,其开销只有50KB~130KB。无论在嵌入式系统还是在实时系统之中,eXtremeDB都天然地嵌入在应用程序之中,在最终用户毫不知情的情况下工作。eXtremeDB的这种天然嵌入性对实时数据管理至关重要:各个进程都直接访问eXtremeDB数据库,避免了进程间通信,从而剔除了进程间通信的开销和不确定性。同时, eXtremeDB独特的数据格式方便程序直接使用的,剔除了数据复制及数据翻译的开销,缩短了应用程序的代码执行路径。
  4. 由应用定制的API,应用程序对eXtremeDB数据库的操作接口是根据应用数据库设计而自动产生,不仅提升了性能,也剔除了通用接口所必不可少的动态内存分配,从而提高了应用系统的可靠性。定制过程简单方便,由高级语言定制eXtremeDB数据库中的表格、字段、数据类型、事件触发、访问方法等应用特征,通过eXtremeDB预编译器自动产生访问该数据库的C/C++ API接口。
  5. 可预测的数据管理 eXtremeDB独特的体系结构,保证了数据管理的可预测性。eXtremeDB不仅更快、更小,而且更确定。在80双核CPU的服务器上,eXtremeDB在1TB内存里保存15B条记录;无论记录数多少,eXtremeDB可以在八十分之一微秒的时间内提取一条记录。

Firebird嵌入服务器版(Embedded Server)

从Interbase开源衍生出的Firebird,充满了勃勃生机。虽然它的体积比前辈Interbase缩小了几十倍,但功能并无阉割。为了体现Firebird短小精悍的特色,开发小组在增加了超级服务器版本之后,又增加了嵌入版本,最新版本为2.0。

Firebird的嵌入版有如下特色:

1、数据库文件与Firebird网络版本完全兼容,差别仅在于连接方式不同,可以实现零成本迁移。

2、数据库文件仅受操作系统的限制,且支持将一个数据库分割成不同文件,突破了操作系统最大文件的限制,提高了IO吞吐量。

3、完全支持SQL92标准,支持大部分SQL-99标准功能。

4、丰富的开发工具支持,绝大部分基于Interbase的组件,可以直接使用于Firebird。

5、支持事务、存储过程、触发器等关系数据库的所有特性。

6、可自己编写扩展函数(UDF)。

UnQLite

由 Symisc Systems公司出品的一个嵌入式C语言软件库,它实现了一个自包含、无服务器、零配置、事务化的NoSQL数据库引擎。UnQLite是一个文档存储数据库,类似于MongoDB、Redis、CouchDB等。同时,也是一个标准的Key/Value存储,与BerkeleyDB和LevelDB等类似。

UnQLite是一个嵌入式NoSQL(键/值存储和文档存储)数据库引擎。不同于其他绝大多数NoSQL数据库,UnQLite没有一个独立的服务器进程。UnQLite直接读/写普通的磁盘文件。包含多个数据集的一个完整的数据库,存储在单一的磁盘文件中。数据库文件格式是跨平台的,可以在32位和64位系统或大端和小端架构之间,自由拷贝一个数据库。UnQLite的主要特点,如下:

  1. 无服务器数据库引擎。
  2. 事务化(ACID)数据库。
  3. 零配置。
  4. 单一数据库文件,不使用临时文件。
  5. 跨平台的文件格式。
  6. UnQLite是一个自包含的C语言程序库,无任何外部依赖。
  7. 标准的Key/Value存储
  8. 基于Jx9的文档存储(JSON)数据库。
  9. 支持游标,满足线性记录遍历。
  10. 插件式运行时可交换存储引擎。
  11. 支持磁盘持久化和内存模式的数据库。
  12. 内建强大的磁盘存储引擎,支持O(1)查询。
  13. 线程安全,完全可重入。
  14. 简单、清晰,很容易使用的API。
  15. 支持TB(Terabyte)尺寸的数据库。
  16. 采用BSD开源许可协议。
  17. 合并:UnQLite和Jx9相关所有C源代码文件,都合并到单一的文件中。
  18. 很好的在线支持。

UnQLite是,一个自包含的C库,无外部依赖。它要求非常小的外部库或来自操作系统的支持。特别适合应用于嵌入式设备,也适用于应用程序内部(那些需要运行于大量的计算机,而无需修改各种配置)。

UnQLite是,100%手工编码,使用ANSI C,线程安全,完全可重入,编译无需修改,而且可运行于绝大多数的平台,包括受限的嵌入式设备,仅需要一个C编译器。UnQLite已经在非常广泛的平台 进行了测试,包括Windows和UNIX系统,特别是Linux、FreeBSD、Oracle Solaris及Mac OS X。

UnQLite是,一个标准的key/value存储,与BerkeleyDB和LevelDB等相似。但是,拥有更加丰富的特性集,包括支持事务 (ACID),并发读等。在KV存储下,键和值都被视为简单的字节数组,所以内容可以是任何东西,包括ASCII字符串、二进制对象和磁盘文件等。应用程 序,可以通过接口API来访问KV层,包括

unqlite_kv_store() unqlite_kv_append() unqlite_kv_fetch_callback() unqlite_kv_append_fmt() unqlite_kv_delete() 等等。

UnQLite用来在数据库中存储JSON文档(如,对象、数组、字符串等)的文档存储接口,是通过Jx9编程语言支撑/实现的。Jx9是一种嵌入式的脚本语言,也叫扩展语言,被设计用于通用过程化编程,具备数据表述的特性。Jx9是一个图灵完备(Turing-Complete),基于JSON的,动态类型编程语言,作为UnQLite内核的一个库而存在。

总之,UnQLite一块开源软件,在 2-Clause BSD协议下开放源代码。

需要比较的:

Berkeley DB

SQLite

UnQLite

SQLite VS UnQLite

https://stackshare.io/stackups/sqlite-vs-unqlite#description

总的来说,相较于UnQLite,选择SQLite的公司更多

SQLite VS Berkeley DB

SQLite更适合数据集少的单线程的数据存储

以下来自Stateflow的回答:

 I participated in the beta evaluation of the BDB SQLite code and one of the things I tried to get a handle on was the performance difference. At this point, I cannot publish exactly what I found until I have at least one other person evaluate my code, run the tests, and confirm the numbers I got (which is being done). However, I can generalize here and say that there are cases where BDB offers significant performance improvements over SQLite, specifically in the area of handling heavy loads that involve write-concurrency.
 
 There are, generally, two measures of "fast" right -- (1) efficiency: how long does it take for a single process to do XYZ vs. (2) concurrency: how many times can many processes do XYZ per unit time. The main problem BDB addresses is concurrency -- large-scale transaction processing. Thus you think of many concurrent connections writing to and/or modifying the contents of the database.
 
 SQLite by design uses database-level locking so there is a maximum of one writer who can be working in the database at a time. Thus, SQLite's transaction rate stays more or less constant with the number of concurrent connections, so it's scalability in write-intensive applications is really measured by its efficiency (1).
 
 BDB on the other hand uses page level locking, which allows multiple writers to be working in the database at a given time (provided that they are working on separate pages). Thus BDB's rate potentially increases with the number of connections and so its scalability is both a matter of efficiency (1) and concurrency (2), which can add up.
 
 Mainly what it boils down to is (write) concurrency. BDB can push more TPS than SQLite for multiple writers. By transaction, I mean something that modifies the database (how are they of any real help for read-only operations?). That said, for read concurrency (apps that mainly do SELECTs), SQLite could very well go head to head with BDB because locking is no longer a critical issue.
 
 As for the size of the dataset, I am not sure. I've not looked into that. Ultimately, they both use B-trees for storage. There may be factors in their respective implementations to consider, but I've not investigated that. I know that SQLite can gracefully handle data sets into the hundreds of MBs and double digit GBs (and perhaps more now that the dirty page map implementation has been changed).
 
 Therefore, if you have an application which employs many connections that modify a given database and page contention is relatively low, then BDB can offer significant performance improvements. But page contention is a critical variable. In the limit, if you had a BDB database whose data consisted of a single page, then its performance would match that of SQLite in all cases because page-level locking here effectively degenerates into the equivalent of database level locking -- everybody is fighting over one thing. However, as the number of pages increases in BDB (and page contention decreases), then the maximum TPS will start to grow with the number of concurrent connections. Then from that point, memory becomes the next limiting factor. But that's another story.
 
 BTW, I am in the process of writing an article about using BDB for those coming from SQLite.

转载于:https://zhuanlan.zhihu.com/p/109227826

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐