建议的模式/策略,用于比较两组数据(新数据与现有数据)...保留现有

时间:2016-04-08 13:19:12

标签: c# etl

我有一个ETL进程/作业,它以预定的方式从源到目标获取数据库数据。

  1. [Source data]会定期更新来自某些外部的新数据 资源。 [Destination data]是使用的[Source data]的子集 商业下游。
  2. [Destination data]中的约束要求是应该的 没有重复(例如,在工作的情况下可能会发生) 失败,然后在导入一些数据后运行新的提取)
  3. 作业一次导入1000条记录
  4. 调度程序/作业还有其他职责和其他可用的数据
  5. 我的一个可行的"选项涉及:

    • 从目标
    • 获取所有投射的复合/关键列
    • 与新的1000个记录进行比较(仍然很多 记录)。
    • 然后保存不在的新[Source data] [Destination Data]
    • 我认为包含现有[Destination data]的数据结构将是以下结构的Hashset,例如HashSet<int,string,string>。 3个数据项唯一标识记录的地方。
    • 然后我会获得1000条记录,循环遍历它们,与HashSet进行比较。

    我担心在内存中处理太多数据。

    有关更好方法的建议,或者这是最有效的方法吗?

1 个答案:

答案 0 :(得分:0)

为了分享,我找到了类似的问题并给出了全面的答案。它在Java中很容易转换为C#。

仍然对任何替代方案持开放态度。否则会将此标记为答案并表示为重复。

...我们可以按照ID(一次O(n log n)成本)按升序对所有元素进行排序,并使用O(n)算法迭代它们,只要它们是跳过元素大于其他序列的当前元素。这样更好,但仍然不是最佳的。

最佳解决方案是创建bs集的ID哈希集。这不需要对两个集合进行排序,并允许线性时间成员资格测试。组装ID集合需要一次O(n)费用。

HashSet<Integer> bIds = new HashSet<>(bs.size());
for (B b : bs)
    bIDs.add(b.getId());

for (A a : as)
    if (bIds.contains(a.getId()))
        cs.add(a);

此解决方案的总体复杂性为O(|as| + |bs|)

https://softwareengineering.stackexchange.com/a/258325/132218