阵列vs内存数据库

问题描述 投票:0回答:4

我正在构建一个REST API,我需要在其中将2D数据(x:Double,y:Double)保存在应用程序内存中(无需将数据持久保存在磁盘上)。记录/数据对象的数量将来可能会增长/缩小。用户可以添加/删除数据对象,但不能编辑它们。我有2个选择。可以将数据保存在数组/集合中,也可以使用内存数据库(例如H2)。

问题是,我应该选择哪种方法,为什么?这是我已经知道或到目前为止发现的内容。随时不同意并分享您的想法。

  • 数组保留连续的内存块。数据访问可能更快。但是,如果数据变大,则很难找到连续的内存块。
  • 在函数式编程中,如果函数在数组/集合中添加/删除元素,则它正在更改应用程序状态,或者换句话说,它会产生副作用。这是不希望的,因为并行化此功能可能很困难。
  • 并发更新:如果多个请求正在更新数组,由于竞争条件,我们可能最终会导致数据不一致或某些更新可能丢失。因此,需要实现一种用于更新的锁定机制。在数据库(关系)中,可以使用应解决此问题的事务。另一方面,关系数据库支持事务处理,应该注意不一致问题。

我在这里缺少什么,将数据保存在数据库中还会带来其他好处吗?创建一个仅包含1个表并具有2-3列接缝的数据库是一个过大的选择。

提前感谢。

arrays scala h2 in-memory-database
4个回答
3
投票

可以同时被多个线程访问

例如

import java.util.concurrent.ConcurrentHashMap import scala.jdk.CollectionConverters._ case class User(id: Int, name: String) val chm: collection.concurrent.Map[Int, User] = new ConcurrentHashMap[Int, User]().asScala chm.addOne(1 -> User(1, "Picard"))

另一种选择是用Akka Actor包装可变状态,从而保证

处理一封邮件发生在处理下一封邮件之前同一位演员的留言

也许像这样

class MyActor() extends Actor { private val _mutableSate = mutable.Map[Int, User]() def insertUser(u: User): Unit = _mutableSate.addOne(u.id, u) }

关于是否应该使用集合数据库或内存数据库,IMO,这是一项折衷方案,但没有明确答案的工程决策。例如,可以应用principle of minimal power推理,并说如果集合可以充分解决问题,则无需使用更强大的数据库解决方案。另一方面,也应该考虑做解决方案规模。例如,一旦有多个表需要联接,集合将具有足够表达的查询机制吗?


3
投票
    数组无论如何都无法工作(您无法更改其大小),只有集合可以。因此,第1点可能不相关,具体取决于您使用的集合类型。
  1. 这在集合和数据库之间没有区别。

  2. 这里的重要问题是您的交易情况。如果它们只是添加/删除单个元素,则您实际上并不需要锁,只需选择一个并发集合(请查看https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/package-summary.html中“并发集合”下的内容;不幸的是,标准库未涵盖所有用例)。

  3. 另一个问题是您想如何查询/访问数据,是否可以从某些列的索引中受益(数据库支持但集合不支持,等等。


3
投票

3
投票
    使用akka群集分片区域以避免内存锁定以进行并发更新。
  1. 建议使用第三方记忆。示例咖啡因。它可以帮助您控制大小,LRU,到期时间。 Scala有一个名为Scaffeine的咖啡因包装。

  • val profileDocumentCache: Cache[String, T] = Scaffeine() .recordStats() .expireAfterWrite(1.hour) .maximumSize(1024) .build[String, T]()
  • © www.soinside.com 2019 - 2024. All rights reserved.