我是一名核物理研究生,目前正致力于数据分析计划。数据由数十亿个多维点组成。
无论如何我使用空间填充曲线将多个维度映射到单个维度,我使用B +树来索引数据页面。每个页面内都有一些恒定的最大点数。
当我从原始文件中读取原始数据(几百个演出)并进行预处理和索引时,我需要将各个点插入到页面中。显然,将有太多页面只是将它们存储在内存中,然后将它们转储到磁盘上。所以我的问题是:将页面写入磁盘的好策略是什么,以便当页面达到最大大小并需要拆分时,最少重新调整数据。
根据评论,让我稍微减少一点。
我有一个包含有序记录的文件。这些记录被插入到文件中,并且有太多这些记录只是在内存中执行此操作然后写入文件。我应该使用什么策略来最小化插入记录时所需的重新洗牌次数。
如果这有任何意义,我将不胜感激任何解决方案。
编辑:
数据是多维空间中的点。基本上是整数列表。这些整数中的每一个都是2个字节,但每个整数还有一个与之相关的额外2个字节的元数据。因此每个坐标4个字节,3到20个坐标之间的任何位置。所以基本上数据由数十亿个块组成,每个块大约在12到100个字节之间。 (显然,4个维度的点将在提取后与5个维度的点位于不同的文件中。)
我使用的技术与本文中讨论的技术类似: http://www.ddj.com/184410998
编辑2: 我有点后悔在这里问这个问题,所以考虑一下它被正式撤销;但这是我不使用现成产品的原因。我的数据是范围从3到22维的点。如果您将每个点视为一个列表,您可以将我想要查询点的方式视为与这些数字出现在同一列表中的所有数字。以下是一些维度较低的示例(数据点比正常情况少得多) 例: 数据 237,661,511,1021 1047,661,237 511,237,1021 511,661,1047,1021
Queries:
511
1021
237, 661
1021, 1047
511, 237, 1047
Responses:
237, 661, 1021, 237, 1021, 661, 1047, 1021
237, 661, 511, 511, 237, 511, 661, 1047
511, 1021, 1047
511, 661
_
对于大多数数据库程序来说,这是一个很难解决的问题,尽管我知道存在一些可以很好地解决这个问题的程序。
但问题变得更加复杂。并非所有坐标都相同。很多时候我们只使用gammasphere运行,因此每个坐标代表一个伽马射线能量。但是在其他时候我们将中子探测器插入到gammasphere或称为微球的探测器系统中,或者有时在gammasphere中产生的核素被引导到碎片质量分析器中,所有这些和更多的探测器系统可以单独使用或与gammasphere结合使用。不幸的是,我们几乎总是希望能够以与上述类似的方式选择这些附加数据。所以现在坐标可以有不同的含义,如果除了gammasphere之外只有微球,你可以用与方程x + y = n的正解相同的方法构成n维事件。此外,每个坐标都有与之关联的元数据。所以我展示的每个数字都至少有2个与它们相关的附加数字,第一个是探测器编号,用于拾取事件的探测器,第二个是效率值,用于描述特定伽马射线的次数计数(因为实际检测到的伽玛射线进入探测器的百分比随探测器和能量而变化)。
我真诚地怀疑任何现成的数据库解决方案都可以同时执行所有这些操作并且性能良好,而无需大量的自定义。我相信花在这上面的时间最好花在写我自己的,更不那么通用的解决方案上。由于失去了一般性,我不需要为任何数据库代码实现删除函数,我不需要构建二级索引来对不同类型的坐标进行门控(只有一个集合,有效地只计算每个点一次),等
答案 0 :(得分:1)
我相信你应该首先看看商业和免费数据库提供什么。它们旨在执行快速搜索(给定正确的索引)并有效地管理内存和将页面读/写到磁盘。
如果不这样做,请查看二进制Space Partition(BSP)树的变体之一。
答案 1 :(得分:0)
所以第一个方面是在线程应用程序中执行此操作以更快地完成它。将您的数据块分解为可行的部分。这让我想到了......
我最初建议你使用Lucene ......但是考虑到这听起来像是你应该用Hadoop处理的东西。它是为这种工作而做的(假设你有基础设施)。
我当然不会在数据库中这样做。
当您谈到索引数据并使用数据点填充文档时......如果您没有infrstructure,知道如何或实施hadoop的时间,那么您应该回到我原来的想法并使用Lucene。您可以实际索引数据,并将数据点直接存储到索引中(我认为是数字范围),并且您认为最好使用“文档”(对象)结构。
答案 2 :(得分:0)
我自己想出了一个答案。当页面需要拆分时,事件被插入到页面中,在文件末尾创建新页面。原始页面的一半事件将移动到该页面。这使得页面未被排序,这在一定程度上违背了快速检索机制。
然而,由于我只是在一个大的初始热潮(可能持续几天)中写入数据库,我可以证明在写完之后花费一点额外的时间来浏览页面并在它们全部构建之后对它们进行排序。事实上,这部分很容易,因为用于索引页面的B +树的性质。我只是从B +树的最左边的叶子节点开始,然后读取第一页并将其放在最终文件中,然后我读取第二页并将其放在第二页,依此类推。
以插入结尾的方式,所有页面都将在其文件中进行排序,允许我使用的方法将多维请求映射到单维索引,以便在从磁盘读取数据时高效快速地工作。