嵌入式非关系型(NoSQL)数据存储

21

我在考虑为我的Windows桌面应用程序使用/实现一种嵌入式键值(或文档)存储。我希望能够存储各种类型的数据(GPS轨迹就是一个例子),当然也能够查询这些数据。由于数据量太大,在同一时间内无法全部加载到内存中。

我考虑使用sqlite作为键值存储的存储引擎,类似于.NET编写的y-serial。我还阅读了有关FriendFeed使用MySQL存储无模式数据的文章,这是如何将RDBMS用于非关系型数据的好指针。由于其简单性、可移植性和库大小,sqlite似乎是一个不错的选择。

我的问题是是否有其他选项可供使用嵌入式非关系型存储?它不需要分发,也不必支持事务,但必须可以从.NET访问,并且应具有较小的下载大小。

更新:我找到了一篇名为“SQLite作为键值数据库”的文章,其中比较了sqlite和Berkeley DB,后者是一个嵌入式键值存储库。

8个回答

19

@Laurion,我见过ESENT并且一开始非常兴奋。唯一的问题是它只能在Windows上运行(考虑Mono + Linux/Mac)。 - Igor Brejc

10

看看RavenDB。看起来它可以被嵌入,是无模式的,并且可以与.NET一起使用。

来自网站:

  • 可扩展的基础设施:Raven建立在现有的、经过验证的和可扩展的基础设施之上
  • 简单的Windows配置:Raven在Windows上作为服务或IIS7网站进行设置和运行非常简单
  • 事务性:Raven支持具有ACID事务的System.Transaction。如果你将数据放入其中,那么该数据将保留在那里
  • Map/Reduce:使用Linq查询轻松定义map/reduce索引
  • .NET客户端API:Raven带有一个完全功能的.NET客户端API,实现了工作单元等等
  • RESTful:Raven围绕着RESTful API构建

5

个人建议使用SQLite和NHibernate(以及Fluent NHibernate)进行开发。NHibernate可以自动为您的类生成数据库架构,因此您只需要指定要持久化的类即可。使用Fluent NHibernate也非常容易。此外,您可以搜索特定对象,而不需要将所有数据加载到内存中。


但他想要一个无模式存储。 - Viktor Klang
Astor是正确的:我想避免关系模型。我希望能够存储几乎任何类型的数据,而无需先为其准备数据库架构。此外,如果数据结构稍后发生更改,则具有严格的关系模型可能会出现问题 - 我需要为存储中的现有数据编写SQL更改脚本。 - Igor Brejc
1
我知道他在寻找什么,但是像NHibernate这样的工具,带有模式生成功能,几乎完全隐藏了关系方面。你不需要定义任何模式,只需要为你的类编写映射(使用Fluent NHibernate非常简单),当你的类发生变化时,你需要在任何持久化策略中进行某种更新。 - Oliver Hanappi
我很感激,但隐藏关系方面并不等同于完全没有关系模型。在实践中,这种隐藏只能做到一定程度 - 迟早需要“手动”处理它(例如在模型更改的情况下)。另一方面,如果您将数据存储为文档(某些NoSQL解决方案可以实现),则您实际上不需要更新旧数据 - 您只需要确保支持以旧格式读取数据即可。 - Igor Brejc

2

你能创建一个包含两列的简单sqlite数据库吗:

==documents==
id|data

数据将是JSON格式的数据。

您还可以创建一个键表,其内容如下:

==keys==
keyname|keyvalue|id

可以索引关键字和关键值,以便快速查找。

一个单独的数据库文件可以是一个集合,您可以为多个集合创建多个数据库文件。

您可以使用文件夹作为“dbs”,以匹配mongodb的层次结构:db->collection->document


只是一个提示:您可以创建一个模板sqlite数据库文件,并在需要创建新集合的任何时候复制它。如果有人想要创建一个处理此事并开源的php设置,请告诉我。我认为这将是很棒的,但从未费心去做它。 - RobKohr
你的建议是朝着y-serial的做法方向的。你看过它吗?http://yserial.sourceforge.net/ - Igor Brejc
不是,但我自己正在寻找php的解决方案。 - RobKohr

2

如果你想将KISS原则应用于你的问题,我建议你使用文件。

也就是说,文件名是关键。 文件内容是价值。 Windows文件夹是索引。

简单、快速、高效、灵活且防错(只要傻瓜的智商不高)。


不错的方法,虽然我觉得对于简单的值(例如单个整数),使用文件存储值可能有点过头了。 - Igor Brejc
这个问题有点暗示了存储的内容可能相当大(文档/数据量太大而无法加载到内存中)。文件方法的一个优点是你可以免费获得一组很好的流处理类,这在处理大块数据时非常有用,比如将数据分割成任意大小的块并存储在数据库中要干净得多。 - James Anderson
2
真的。文件系统的物理限制是什么?当记录数达到> 100,000时,这样的存储会如何表现?另外:当我谈论“太多数据”时,我指的是整个数据库 - 我提到这一点是为了避免像对象树序列化等类似答案。 - Igor Brejc

2
这是一个老问题,但我认为我可以回答一下以便任何人都能看到它。 我的公司刚发布了一个名为Nxdb的开源嵌入式XML数据库,适用于.NET平台。 它采用Apache 2.0许可证,并已在公司内部开发和使用多年。 基本上它是绑定到经过交叉编译(使用IKVM)的BaseX的版本(一个非常好的Java XML数据库),并具有嵌入式使用情况和.NET环境的额外功能。 项目页面在此处:https://dracorp.assembla.com/spaces/nxdb 对于这种类型的数据存储,XML非常有效,因为只要您尝试存储的内容可序列化为文本,您就可以存储复杂的分层树。实际上,如果直接访问数据库,则不必接触“XML”。它还可以通过XQuery进行查询,这是一种强大且完整的查询语言。

1
你可以尝试使用这个https://github.com/mdsoftware/mData。它是一个小巧、免费且非常不寻常的工具。它具有类似Lisp的数据查询语言、表达式编译器和高性能二进制序列化等功能。

1
感谢您对y_serial的友善提及...更确切地说,这是一个Python模块:
使用SQLite存储Python对象
“序列化+持久化:只需几行代码,将Python对象压缩和注释到SQLite中;然后可以通过关键词按照时间顺序检索它们,而无需任何SQL。这是用于存储无模式数据的最有用的“标准”模块。”

http://yserial.sourceforge.net

在我的经验中,对于大多数项目而言,SQLite比大多数数据库(包括PostgresQL和Berkeley DB)都更快速、更可靠——当然,它也不需要服务器守护程序。
yserial非常易于实现(并且比“文件名为键/文件内容为值”的方法要快得多;-)

是的,我真的很喜欢y-serial的方法,特别是它使用了sqlite。继续保持好工作!也许当我从其他项目中腾出一些时间时,我会尝试在C#中做类似的事情 :) - Igor Brejc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接