【问题标题】:Algorithm for updating a list from a list从列表更新列表的算法
【发布时间】:2009-06-19 18:09:22
【问题描述】:

我有一个提供对象列表及其属性的数据源(一个 CSV 文件,但这没关系)。每次我的程序运行时,它都需要提取对象列表的新副本,将其与存储在数据库中的对象列表(及其属性)进行比较,并根据需要更新数据库。

处理新对象很容易 - 数据源为每个对象提供了一个连续的 ID 号,对照数据库检查新信息中的顶部 ID 号,就大功告成了。我正在寻找其他情况的建议 - 对象的某些属性已更改,或者对象已被删除。

一个天真的解决方案是从数据库中提取所有对象并获取两组(旧的和新的)交集的补集,然后检查这些结果,但如果集合变大。有什么想法吗?

【问题讨论】:

  • 计算并存储每个对象的哈希值?

标签: python google-app-engine set


【解决方案1】:

处理大量数据的标准方法就是这样。

我们假设 list_1 是“master”(没有重复项),而 list_2 是可能有重复项的“updates”。

iter_1 = iter( sorted(list_1) ) # Essentially SELECT...ORDER BY
iter_2 = iter( sorted(list_2) )
eof_1 = False
eof_2 = False
try:
    item_1 = iter_1.next()
except StopIteration:
    eof_1= True
try:
    item_2 = iter_2.next()
except StopIteration:
    eof_2= True
while not eof_1 and not eof_2:
    if item_1 == item_2:
        # do your update to create the new master list.
        try:
            item_2 = iter_2.next()
        except StopIteration:
            eof_2= True
    elif item_1 < item_2:
        try:
            item_1 = iter_1.next()
        except StopIteration:
            eof_1= True
    elif item_2 < item_1:
        # Do your insert to create the new master list.
        try:
            item_2 = iter_2.next()
        except StopIteration:
            eof_2= True
assert eof_1 or eof_2
if eof_1:
    # item_2 and the rest of list_2 are inserts.
elif eof_2:
    pass
else:
    raise Error("What!?!?") 

是的,它涉及潜在的排序。如果将 list_1 写回文件系统时保持排序顺序,则可以节省大量时间。如果 list_2 可以累积在一个保持排序的结构中,那么可以节省大量时间。

对冗长感到抱歉,但您需要知道哪个迭代器引发了 StopIteration,因此您不能(简单地)将整个 while 循环包装在一个大的旧 try 块中。

【讨论】:

    【解决方案2】:

    有没有办法维护“上次修改时间”字段?这就是您真正想要的:增量备份,基于上次运行备份的时间,与上次更改/删除(/添加)对象的时间相比。

    【讨论】:

    • 或修改后的字段也很棒!
    【解决方案3】:

    您的数据库和 CSV 文件中都需要有时间戳。时间戳应该显示记录更新时的数据,您应该比较具有相同 ID 的记录的时间戳来决定是否需要更新它

    关于你对交叉路口的想法...... 反之亦然! 您必须将所有数据从 CSV 导入临时表,并在 2 个 SQL 数据库表之间进行交集。如果您使用 Oracle 或 MS SQL 2008(不确定是否为 2005),您会发现一个非常有用的 MERGE 关键字,因此您可以更轻松地编写 SQL,然后您将花费在其他编程语言中合并数据。

    【讨论】:

      【解决方案4】:

      当您将列表拉入您的程序时,迭代该列表以执行基于数据库表中的列属性的查询,该属性映射到列表中对象的相同属性,例如 ObjectName。或者您可以将整个表格加载到列表中并以这种方式比较列表。我假设您对除了数据库分配的 ID 之外存在的对象有一些独特的东西。

      如果通过查询在表中未找到该对象,则创建一个新条目。如果像提到的 FogleBird 那样找到它,则在表中存储该对象的计算哈希或 CRC,您可以将其与列表中的对象进行比较(在对象上运行计算)。如果哈希值不匹配,请使用列表中的对象更新该对象。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-02
        • 2022-01-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多