【问题标题】:How to insert a new record if old record is updated?如果更新旧记录,如何插入新记录?
【发布时间】:2015-08-14 12:59:08
【问题描述】:

我正在使用 mysql 作为 php 应用程序的数据库。

我必须解析一个 csv 表,并且只有在更新旧记录时才将数据插入数据库。

一种方法是使用我在 csv 中的 ID 从数据库中获取记录,然后检查值,如果有差异则添加一条新记录,但是因为我有数百 MB 的数据,所以我无法返回从数据库中来回,有没有办法在 sql 中完全做到这一点?

Id 不是唯一的,必须插入的新记录将使用相同的 id。

例如以下是当前记录
| 1001 | M 丹麦语 |新加坡 |

国家更改为美国,表格将有如下两行
| 1001 | M 丹麦语 |新加坡 |
| 1001 | M 丹麦语 |美国 |

【问题讨论】:

  • 向我们展示您所做的事情。表结构、数据结构……id是唯一的吗?如果csv id表示dub中具有相同id的记录已更新,插入的新行的id是什么?
  • @rjdown 这更新了相同的记录,我不必更改它。我必须添加一个新的。
  • MySQL 没有instead of 触发器,所以我建议您以编程方式解决它,使用 PHP 函数或 MySQL 存储过程。
  • @LelioFaieta 请查看编辑

标签: php mysql sql database csv


【解决方案1】:

正如我从您的问题中了解到的那样,您可以在将 csv 数据插入数据库检查该记录之前,在您的数据库表名中创建另一个原始值“更新”值 0 或 1(假或真),然后将您的操作作为其值(假或真)

【讨论】:

    【解决方案2】:

    就相对成本而言,往返数据库通常非常昂贵。面对这种情况时,我通常会尝试将本地映射(即带有字符串键的 PHP 数组)与要比较的值进行比较,从而只允许我往返数据库所需的更新/插入。

    为了便于说明,这里有一个过于简化的示例:

    // variable created in php file from previous run
    $records = [
        "1001 | M Danish | Singapore" => true
        // ... other records
    ];
    // check if value present, a constant time operation on a map
    if (!isset($records["1001 | M Danish | USA"])) {
        // insert into db
    }
    

    值得注意的是,上面的示例并没有遍历所有记录、处理重复键、删除旧键等。但是,希望它可以为您提供一个总体思路,以大大减少数据库往返(或整体大小)往返)通过在进行查询之前在 PHP 中进行一些快速工作。

    【讨论】:

    • 这是一个很好的解决方案,但是我有超过 50K 条记录,有 21 列,并且随着时间的推移而增长,因此将所有这些数据保留在内存中是不可行的
    • @mdanishs 不必全部存储在内存中。地图可以通过 id 或其他一些字段组合(类似于大型数据库)跨多个文件分解(分片)。
    • @mdanishs 此外,您可以存储校验和/哈希值而不是列值以观察更改,这将节省内存。
    【解决方案3】:

    向您的表格添加一个自动递增的 ID。然后在 php 中运行查询以选择与 csv 中的行匹配的最后一个 Id。比较两者,如果有差异则插入。对于您的表结构,这是我能想到的最有效的方法。

    我将创建一个包含不变数据的表和一个包含重复 id(csv Id) 的表,您将只在更改时插入该表。这将使您的事情变得更容易和更快。第二个表将有一个自动递增 Id 以检查 csv 中具有相同 Id 的最后一行。

    希望清楚。

    【讨论】:

      【解决方案4】:

      您可以在重复键更新 sql 上运行插入忽略。 仅当您在想要唯一的列中定义了唯一键时,这才有效

      insert ignore into table1(col1, col2) 
      values ('val1', 'val2')
      on duplicate key update
      col1 = VALUES(`col1`),
      col2 = VALUES(`col2`)
      

      这将使用值 val1、val2 更新行,或者如果未找到该行则插入

      如果您有很多插入/更新,您可以将其与批量一起使用

      insert ignore into table1(col1, col2) 
      values 
      ('val1', 'val2'),
      ('val3', 'val4'),
      ('val5', 'val6'),
      ('val7', 'val8'),
      ('val9', 'val10'),
      ('val11', 'val12'),
      ('val13', 'val14')
      on duplicate key update
      col1 = VALUES(`col1`),
      col2 = VALUES(`col2`)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-06-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多