问题 需要在Android设备上存储大量数据,考虑去OODB


我目前正在开发一个基于Android的项目。在没有了解许多细节的情况下,该软件将在定制的设备上运行。硬件永远不会改变,并且永远都是一样的。这是一个明确的加:)

话虽如此,该项目要求我们在设备上存储负载和数据负载 - 在某些表中超过3米的行。 SQLite处理扫描这么多行对我们来说很好,当我们开始进行复杂的连接以带回我们需要的所有相关数据时,问题就出现了。我们已经考虑过对数据库进行非规范化,但是担心会将数据库推到可用的范围之外。

我们正在研究使用面向对象的数据库,比如db4o或NeoDatis。我们希望通过存储对象,我们可以在行级别上删除我们的关系并将它们存储在对象上(就像OOP一样)。问题是我们无法找到在Android上运行和使用的这些ODB的任何性能相关基准(至少不是最近的基准)。

有没有人在Android上使用OODB和/或存储和访问这些大量数据?如果是这样,您可以提供的任何建议将不胜感激。

- 编辑

这是我们面临的问题的一个例子。它与我们的应用程序无关(我的NDA说我不能发布任何特定内容),但这个例子很好地代表了问题。

想象一下,我们正在构建一个应用程序,以监控在任何给定时间在新泽西收费公路上行驶的每辆车。对于任何给定的汽车,我们需要跟踪汽车制造和模型,汽车中有多少人以及汽车中人员的人口统计。所以基本上你最终得到的数据看起来像 -

汽车

id | 颜色| make_id | in_toll_lane | MODEL_ID

使

id | 名称

模型

id | 名字| make_id

car_person

id | 年龄| 性别 is_driver | car_id

toll_lanes

id | cars_in_line | ideal_cars_in_line | ideal_occupants

这些数据将经常变化。它也会变得相当庞大,因为毫无疑问,很多人在任何时候都会驾驶新泽西派克。

根据这些数据,我们需要能够根据需要快速拍摄任何驾驶梭子鱼的人。我们还需要能够快速拍摄所有正在驾驶的男性或收费公路上的所有女性。我们还需要能够按年龄,性别,品牌,模特等进行搜索。

现在想象一下,我们需要根据车内人数,理想乘员人数,已经排队的车辆数量以及应该排队的理想车辆数量来确定每辆车应该进入的收费车道。 。

这是一个非常简单的例子,虽然很能代表我们的问题。

- 结束编辑

提前致谢!


7764
2017-12-01 01:41


起源

听起来像一个非常有趣的项目!这并不直接解决您的问题,但您可能希望在选择使用它之前仔细查看db4o许可: db4o.com/about/productinformation/whitepapers/#gpl - elevine
谢谢你的评论!这是def。一个有趣的项目:)我已经看过他们的许可模式,如果需要,我们已经做好充分的准备来支付解决方案。我把它从原来的帖子中删了,因为我希望避免BerkelyDB的建议。 (那里的个人喜好,真的)=) - Jason L.
好吧,如果BDB是可能的,那么SQLite肯定是。您可以将它用作简单的键/对象存储,并且一些用户发誓它在该空间中大大优于BDB,特别是对于大数据集。 (免责声明:我没有亲自尝试过) - Javier
这是一个很好的观点,哈维尔,这是我们正在测试的东西。虽然我们没有真正的键/值,但我们正在添加一些其他元数据列,以便更轻松地获取所需内容。我们确实预见到了几个问题。在SQLite方法中,我们如何搜索对象中的属性?我们的解决方案(我们正在测试,因此不是真正的解决方案)是将这些字段添加为元数据列。还存在交叉链接问题。我们可以找到一个项目有哪些类别(它在对象上),但我们如何找到哪个项目属于某个类别? - Jason L.


答案:


这里有一些观察,但我怀疑它不会直接帮助你。

我认为主要的问题是:当事件生成或更改数据时,您是否会通过应用程序运行时逻辑发现复杂的关系,或者您是否只需将数据转储到商店中,然后通过查询发现不期望的关系?

如果您的业务逻辑将填充模型,那么您可以轻松地创建数据模型的不同切片的基于模型的视图,例如知道所有拥有男/女司机的汽车的收藏品。在这种情况下,基本上,你的关系是半静态的很少改变(而这些关系另一端的数据值可能会发生很大变化)。如果是这种情况,那么为什么尝试将数据存储在数据库技术中,这迫使您不断重新计算关系(JOIN)。这只是浪费CPU,这就是为什么当模型变得复杂时你会看到性能不佳的原因。因此,一旦您回答了这些问题,ODB或RDB是否是最佳选择将非常清楚。

现在的问题是,在Android上运行什么并处理大量数据?这是我认为我无法帮助的地方。我在拥有(db4o和Versant)ODB的Versant工作。现在db4o将在Android上运行,但它确实是大数据的正确选择...不。除非你有非常孤立的数据,这些数据可以在单独的数据库中,只能在隔离的情况下访问,而且它听起来不像我这样情况。我们的另一个数据库,Versant意味着不能近乎实时处理大量数据,但只有客户端是100%Java,服务器是用C语言编写的,所以它不能在Android上运行。

我想你需要做一些研究,看看谁有ODB可以处理Android上的大量数据。

最好, - 罗伯特·


3
2017-12-01 16:57



非常感谢你非常有见地的帖子。我们最初尝试实时发现联接,但是我们现在正在研究在数据更改后在后台编译这些复杂联接的结果。我们不需要立即准备好更改。更改和更新之间的一些(<10)秒延迟不是交易破坏者。如果我们这样做,我们可以将数据存储在不同的数据库存储中,因为我们只需要实时访问一个数据库。 db4o在这种情况下是否会表现良好?如何在对象上搜索特定的prop值? - Jason L.
嗨Jason,是的,我认为在这种情况下db4o可以工作。我建议你接受卡尔的建议,给他一个ping。试试db4o论坛来抓住他...... developer.db4o.com/Forums.aspx     当涉及到特定属性值的查询时,您将获得具有索引​​的优秀性能,并具有一些很好的可用性选项,如本机查询,它将为您提供编译时检查的可重构查询代码。祝这个项目好运。 - Robert
哦......也想指出。我一定错过了3M的评论,这是我的扫描结果。我把“巨大”用来表示100万和/或更多的数据,而不是轻易地放入单个文件中。对于db4o来说,像3M实例这样的东西不会有问题。 - Robert
理解并且我道歉 - 我在我们实际构建的内容中使用“巨大”。对于我们的设备将要生存的地方3M数据记录很多=) - Jason L.


您没有详细说明您的数据访问需求或数据加载。

如果你有3M主行,然后是一堆较小的叶子表,那么你可以通过缓存RAM中的所有叶子表并手动“连接”它们来做得很好。许多系统都有非常小的叶表(特别是与主数据相比),因此将它们加载到RAM中然后在加载行时简单地查找它们可能是一个巨大的胜利。

显然,你没有用主要的父 - >子关系做这个,但是如果你可以消除叶子连接,那么读取成为父和子之间的单个连接,而不是半打到父,子和叶表。

即使这对所有叶子表都不起作用,如果它适用于大多数叶子表,它可能足以让你超越驼峰。


3
2017-12-01 02:07



谢谢你的回复!你提出了一个好点,我没有真正考虑到我们的数据需求。我们有很多关系,其中很多都是不断变化的,不能真正缓存(我们会经常使缓存失效)。还有叶表,虽然它们中的一些(2或3)不会很小(也超过1米+行)。这些叶表包含类别和其他子信息。 - Jason L.


说到db4o:我们在Android上运行所有的回归测试,因为我们认为它将成为db4o的一个非常重要的平台。

db4o非常适合300万个对象的数量级。

我们正在对其他数据库进行基准测试 http://www.polepos.org/ 我们将很快发布一个新版本的基准测试,我们运行一个复杂的设置,也针对SqlLite。将基准测试移植到Android也是一个考虑因素。

如果联接会破坏您的性能并且您拥有非常异构的数据,那么db4o可能比关系数据库更好。

你的应用听起来很有趣如果您需要帮助评估db4o,请给我一个大喊。


3
2017-12-01 19:00



谢谢你的回应,卡尔!我现在正在研究评估db4o。我现在的问题是我有很多关于OODB的问题,因为我以前从未使用过它们。我很感激你的帮助!我试着在StackOverflow上给你发一条消息,但显然我不能? =) - Jason L.
我们正在监视stackoverflow上的db4o标记,因此您可以在此处或在我们的论坛中提出问题: developer.db4o.com/Forums.aspx。我的电子邮件:carl at db4o dot com - Carl Rosenberger


Jason:要访问任何db4o成员,您必须使用以下模式:firstname @ db4o.com 最好!


2
2017-12-02 00:33



非常感谢你的提示,德语:) - Jason L.