【问题标题】:Identifying Differences Efficiently有效识别差异
【发布时间】:2019-02-15 21:22:15
【问题描述】:

每天,我们都会收到来自不同供应商的不同格式(CSV、XML、自定义)的大量文件,我们需要将这些文件上传到数据库中进行进一步处理。

问题在于,这些供应商将发送其数据的完整转储,而不仅仅是更新。我们有一些应用程序只需要发送更新(即只发送更改的记录)。我们目前所做的是将数据加载到临时表中,然后将其与以前的数据进行比较。由于数据集很大,而且我们偶尔会丢失 SLA,因此这非常慢。

有没有更快的方法来解决这个问题?非常感谢任何建议或帮助。我们的程序员已经没有想法了..

【问题讨论】:

  • 您使用的是什么数据库?是将数据上传到临时表或进行比较以移动到常规表的缓慢部分?“巨大”有多大?合并了多少条记录?
  • 数据库是 MariaDB。通常包含近 700 万条记录,并且随着更多数据的进入而每天增加
  • 最慢的部分是将数据与之前的数据进行比较以识别增量
  • 7M 是很多记录,但不是 A LOT 记录。老实说,如果您的供应商向您发送他们的整个数据集,为什么不直接核对您的数据并加载供应商发送给您的数据呢?这些是同时出现还是不同时间出现?您是否还在处理需要从数据中删除的已删除记录?您要比较多少列以及数据库有多大?您能否提供一个您当前用于此更新的查询语句示例?
  • 我们不能核对数据,因为它不只是加载到另一个数据库中。我们必须找到差异,然后调用另一个创建和更新数据的服务。如果您再次使用旧数据调用该服务,它将创建新条目。我会在屏蔽几个参数后尝试获取查询,因为它们是严格的保密条款。

标签: sql database algorithm logic generic-programming


【解决方案1】:

在完整转储数据集中有多种检测增量的模式,即更改的记录、新记录和删除的记录。

我见过的一种更有效的方法是为您已有的数据行创建哈希值,在导入数据库后创建导入的哈希值,然后将现有哈希值与传入的哈希值进行比较。

主键匹配 + 哈希匹配 = 未更改的行

主键匹配 + 哈希不匹配 = 更新行

传入数据中的主键但从现有数据集中缺失 = 新行

主键不在传入数据中而是在现有数据集中 = 已删除行

如何散列因数据库产品而异,但所有主要提供商都有某种可用的散列。

优势在于只需比较少量字段(主键列和哈希),而不是逐个字段分析。即使是很长的哈希也可以很快分析。

这将需要对您的导入处理进行一些返工,但所花费的时间将在提高处理速度方面一次又一次地得到回报。

【讨论】:

  • 感谢您的想法。我们使用 MariaDB。让我探索一下,埃里克
  • 我们做到了,而且效果很好。仍有一些改进的余地,但是非常大的改进并且没有更多的 SLA 遗漏。非常感谢 Eric 和 btilly!
  • 很高兴它有帮助!
【解决方案2】:

对此的标准解决方案是散列函数。您所做的是能够获取每一行,并计算一个标识符 + 其内容的哈希值。现在您比较散列,如果散列相同,则假设该行相同。这是不完美的——理论上不同的值可能会给出相同的哈希值。但在实践中,与散列函数无法按承诺工作相比,您更需要担心宇宙射线导致计算机中的随机位翻转。

rsyncgit 都是以这种方式使用哈希的广泛使用软件的示例。

通常,在将哈希放入数据库之前计算哈希比在数据库中执行一系列比较要快。此外,它允许处理分布在多台机器上,而不是数据库中的瓶颈。而且比较哈希比比较许多字段的工作量要少,无论是在数据库中还是在数据库外。

您可以使用many hash functions。根据您的应用程序,您可能希望使用加密哈希,但您可能不必这样做。更多位总比更少好,但 64 位哈希对于您描述的应用程序应该没问题。在处理了一万亿个增量之后,您犯意外错误的机会仍然不到 1000 万分之一。

【讨论】:

  • 多年来我一直忽略碰撞风险,因此请 +1 指出这一点。
  • 非常感谢您。我将对此进行探索和更新。
  • But in practice you have more to worry about from cosmic rays causing random bit flips in your computer than you do about hash functions failing to work as promised.
  • @Shawn 我希望它是原创的,但它是基于我多年前看到的关于在足够多的回合后信任Rabin Miller primality test 的评论。
猜你喜欢
  • 2022-11-13
  • 1970-01-01
  • 2018-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多