Java 内存数据库与线程安全数据结构的建议

Java 内存数据库与线程安全数据结构的建议,java,database,concurrency,Java,Database,Concurrency,TLDR:与锁和并发数据结构相比,使用内存中数据库的优缺点是什么 我目前正在开发一个应用程序,它有许多(可能是远程)显示器,可以从多个数据源收集实时数据,并在屏幕上实时呈现。另一位开发人员建议使用内存中的数据库,而不是我们其他系统的标准行为方式,即使用并发哈希映射、队列、数组和其他对象来存储图形对象,并在必要时使用锁安全地处理它们。他的论点是,DB将减少对并发性的担忧,因为它将自动处理读/写锁,而且DB将提供一种更简单的方法,将数据组织到我们需要的尽可能多的表中,而不是创建列表的哈希映射等,并跟

TLDR:与锁和并发数据结构相比,使用内存中数据库的优缺点是什么

我目前正在开发一个应用程序,它有许多(可能是远程)显示器,可以从多个数据源收集实时数据,并在屏幕上实时呈现。另一位开发人员建议使用内存中的数据库,而不是我们其他系统的标准行为方式,即使用并发哈希映射、队列、数组和其他对象来存储图形对象,并在必要时使用锁安全地处理它们。他的论点是,DB将减少对并发性的担忧,因为它将自动处理读/写锁,而且DB将提供一种更简单的方法,将数据组织到我们需要的尽可能多的表中,而不是创建列表的哈希映射等,并跟踪所有数据


我自己没有太多数据库经验,所以我问其他用户他们有什么经验,以及将数据库插入系统的优点和缺点是什么?

一个主要的缺点是Java和数据库之间的不匹配。如果你不需要的话,那是一件很头疼的事。对于真正简单的访问,速度也会慢很多。另一方面,好处是事务和文件系统在崩溃时的持久性。此外,根据您的需要,它允许以常规Java数据结构可能难以实现的方式进行查询

对于介于两者之间的东西,我会看一看。它是一个纯Java图形数据库。这意味着它易于嵌入,能够处理并发和事务,具有良好的可扩展性,并且不存在关系数据库所具有的所有不匹配问题

更新如果您的数据结构足够简单—列表映射、映射映射之类的,您可能不需要JDK中的并发集合,或者,但远远超出此范围,您可能会发现自己正在重新创建内存中的数据库。如果您的查询约束甚至有点困难,那么您必须自己实现所有这些功能。然后,您必须确保它们同时工作,等等。如果这需要任何严重的复杂性或规模(大型数据集),除非您真的想承诺,否则我绝对不会使用您自己的


如果您决定使用嵌入式数据库,那么有很多选择。您可能希望首先考虑是使用SQL还是NoSQL路径。除非你看到使用SQL的真正好处,否则我认为它也会大大增加你应用程序的复杂性。Hibernate可能是使用最少实际SQL的最简单路线,但它仍然有点令人头痛。我已经做了,没有严重的问题,但它仍然不是直接的。您可以尝试使用一种对象数据库,它可以嵌入,并且不需要映射。就像我之前说过的,如果是我,我可能会尝试Neo4j,但那可能只是我想要玩新的和闪亮的东西;)我只是认为它是一个非常透明的库,有意义。Hibernate/SQL和db4o似乎太过轻量级了。

我不清楚为什么您认为内存中的数据库不能是线程安全的


为什么不看看JDO和DataNucleus?它们有许多不同的数据存储,您可以在其中插入后端持久性提供程序在运行时的配置步骤。您的应用程序代码依赖于ORM,但ORM可能会插入RDBMS、DB40、NeoDatis、LDAP等。如果一个后端不适合您,请切换到另一个后端。

我曾经为一个使用Oracle TimesTen的项目工作。这要追溯到2006年初,当时Java5刚刚发布,
Java.util.concurrent
类几乎不为人所知。我们开发的系统具有相当大的可扩展性和吞吐量要求(它是SMS/MMS消息传递的核心电信设备之一)

简单地说,TimesTen的理由是公平的:“让我们将并发性/可伸缩性问题外包给其他人,并将重点放在我们的业务领域上”,这样做非常有道理。但这要追溯到2006年。我认为今天不会做出这样的决定

并发很难,但内存中数据库的处理也很难。要摆脱并发问题,您必须成为内存数据库领域的专家。很难为复制微调TimesTen(我们必须从Oracle聘请一名专业顾问来完成这项工作)。许可证不是免费的。您还需要担心额外的层,这些层不是开源的和/或可能使用与您理解的语言不同的语言编写


但在不了解您的经验、预算、时间要求等的情况下,很难做出任何判断。请四处逛逛,花一些时间研究合适的并发框架(例如……),并让我们知道您的决定;)

您可以使用像这样的东西,并从像接口这样的集合和内存中的数据库中获得好处。在实际应用中,像集合这样基本的东西是一个内存中的数据库,没有索引。列表是一个内存中的数据库,只有一个int索引。Map是一个内存中的数据库,只有一个基于T的索引类型,并且没有并发性,除非是同步的或java.util.concurrency.*实现。

下面是一些有助于决策的问题

  • 查询-您是否需要以不同的形式查询/重新投影/聚合数据
  • 事务-您是否需要回滚添加的数据
  • 持久性—您是只需要显示收集的数据,还是还需要以某种方式存储数据
  • 可扩展性—您的数据是否始终适合存储在内存中
  • 性能-应该有多快