2010-07-19 131 views
5

好了,故事是这样的:当检测数据已经改变

- 我有大量的文件(相当大,各地25GB)是在一个特定的格式,需要在数据存储需要进口

- 这些文件连续数据,有时新的,有时同样的数据

更新 - 我试图找出我如何可以检测,如果事情在改变特定线路的算法文件,以便最小化更新数据库的时间。

- 它现在的工作方式是每次丢弃数据库中的所有数据,然后重新导入它,但由于我需要时间戳来记录项目发生更改,因此这种方法不再适用。

- 文件包含字符串和数字(​​标题,订单,价格等)

我能想到的唯一的解决方案是:

- 从数据库中的每一行计算哈希,它与文件中该行的散列进行比较,如果它们不同,则更新数据库

- 保留2个文件副本,前一个和当前文件,并对其进行差异化(这可能比更新数据库更快)并基于那些更新数据库。

由于数据量非常巨大,所以我现在有些选择了。从长远来看,我将摆脱文件和数据将直接推入数据库,但问题仍然存在。

任何意见,将不胜感激。

回答

1

而不是从数据库按需计算每行的散列,为什么不存储散列值呢?

然后,您可以只计算有问题的文件的哈希值,并将其与数据库存储的哈希值进行比较。

更新

另一个选项,来到我的脑海是存储在数据库中的最后修改日期/时间信息,然后与之比较的有问题的文件。如果信息不能有意或无意改变,这应该起作用。

+0

如果您要求计算整个文件的散列值,而不是整个数据库的散列值,这对我无能为力。但是如果你打算在数据库中存储每行的散列,是的,这是我想到的解决方案之一。我只是想知道这是否比通过比较元素和元素来判断数据是否已经改变更快。 – hyperboreean 2010-07-19 07:37:04

+0

+1用于暗示存储上次修改日期和时间 – 2010-07-19 07:47:22

+0

我没有该文件中的任何时间戳。 – hyperboreean 2010-07-19 07:55:17

1

那么无论你使用什么样的最坏情况,都会是O(n),这在n〜25GB的数据上并不那么漂亮。

除非您可以修改写入文件的进程。

由于您并未全部更新所有25GB,因此这是您节省周期的最大潜力。

1.不要写随机
你为什么不作出这样的写入数据只追加的过程?通过这种方式,您将获得更多数据,但是您将拥有完整的历史记录,并且可以跟踪已处理的数据(您已经放入数据存储区的数据)。

2。如果您必须随机写入,请保留更改列表
或者,如果您确实必须执行随机写入,则可以保留更新行的列表。这个列表可以在#1中进行处理,并且您可以跟踪您处理的更改。如果您想节省一些空间,您可以保留数据更改的块列表(其中块是您定义的单位)。

此外,您可以保留更改块/线的校验和/散列。然而,这可能不是很有趣 - 计算并不便宜,直接比较可能会更便宜(如果在写入期间有空闲的CPU周期,它可能会为您节省一些读取时间,YMMV)。

说明(S)

  • 无论#1和#2是唯一有趣的,如果你能做出调整,以将数据写入到磁盘
  • 过程中如果不能修改的过程写入25GB数据,然后我看不出校验和/哈希如何提供帮助 - 无论如何您都必须读取所有数据才能计算哈希值(因为您不知道发生了什么变化),因此您可以在读取和想出更新/添加的行列表(或直接更新/添加)
  • 使用diff算法可能不太理想,diff算法不仅会查找已更改的行,还会检查给定特定格式选项的两个文本文件之间的最小编辑距离。 (在diff中,这可以用-H或--minimal来控制,以更慢或更快的速度工作,即搜索确切的最小解或者使用启发式算法,如果iirc该算法变为O(n log n);这并不坏,但随后为O(n),如果通过线做直接比较线这是提供给你)
3

问题的定义仍然比较慢所理解

比方说,你的文件中包含

ID,Name,Age 
1,Jim,20 
2,Tim,30 
3,Kim,40 

正如你说行,可以添加/更新,因此文件将成为

ID,Name,Age 
1,Jim,20 -- to be discarded 
2,Tim,35 -- to be updated 
3,Kim,40 -- to be discarded 
4,Zim,30 -- to be inserted 

现在的要求是通过插入/只更新来更新数据库在两个sql查询中的两个以上记录或包含两个sql语句的一个批处理查询。

我想提出以下假设这里

  • 不能修改现有流程来创建文件。
  • 您正在使用一些批处理[从文件读取 - 在存储器中处理 - 在DB中写入] 以上载数据库中的数据。

在内存映射中存储Record [Name,Age]的哈希值与ID,其中ID是密钥,值是哈希[如果需要可扩展性,请使用hazelcast]。

您的批处理框架加载数据[再次假设将一行文件当作一条记录],需要根据内存中的标识检查计算出的散列值。首次创建也可以使用批处理完成阅读文件的框架。

If (ID present) 
--- compare hash 
---found same then discard it 
—found different create an update sql 
In case ID not present in in-memory hash,create an insert sql and insert the hashvalue 

您可能会使用spring-batch和hazelcast进行并行处理,块处理和内存数据分区。

http://www.hazelcast.com/

http://static.springframework.org/spring-batch/

希望这有助于。

0

实际上这是一种需要备份软件解决的问题,为什么不使用他们的一些标准解决方案? 最好的方法是钩住WriteFile调用,以便每次更新都会收到回调。这对二进制记录非常有效。

我无法理解的东西:这些文件实际上是不仅仅是附加的文本文件,而是更新的文件?这是非常无效的(连同保留两份文件的想法,因为它会使文件缓存工作更糟糕)。

相关问题