将数据内容定期复制到MySQL表中最优雅的方法是什么?

时间:2014-12-04 11:21:26

标签: php mysql sql performance optimization

我需要解析API路由中的内容并插入MySQL数据库。解析内容的目的是将数据从API复制到我的数据库表。

我需要每天(在指定的时间)使用预定的cron作业检查API响应,并且应该将所有可用记录提取并插入到数据库中。每次响应都可能发生变化,并且应该按照提供的方式反映出来。 API。

也没有任何字段可以考虑制作唯一的ID。

我不能单独搜索和排序它不是一个更新任务,因此我们不应该“更新”记录,而应该从API中“复制”数据。我们需要考虑,

  • 从API响应中删除已删除的记录,
  • 更新已修改的记录字段和
  • 还插入新记录。

考虑一个例子:

第1天,

让API提供的记录为A1,A2,A3,A4

此记录中可能存在重复的条目。

我们将解析API响应并按原样插入可用的记录。该脚本将获取记录(A1,A2,A3,A4)并将其插入我们的表格。

因此,我们的表格将包含记录:( A1,A2,A3,A4)

第二天考虑,

让API提供的记录为A1,A2,A3,A5,A6 -

可能的情况:

  • 可以更新每个记录A1,A2和A3的字段值 第1天

  • A4已从API响应中删除

  • 现在添加新记录A5,A6。

在这种情况下,我们的目标是更新表格,使其只有记录A1,A2,A3,A5,A6及其更新值。

预计数据将被构建。有一些来自API的特定字段,需要进行解析和获取。我们无法估计更改的频率,并要求每天进行更新。

响应字段值可能会更改但不会更改结构。应为其提取值的字段将保持不变,只有更改才会影响字段值。

目前大约有2000条记录,很快就会增加到5000条。

不应该有任何停机时间,因为此表中的服务是由另一个应用程序实时使用的。 修改 我正在解析并将API响应插入到一个表中,该表充当另一个应用程序的主表。该应用程序需要在没有任何停机时间的情况下工作,即;即使我们在桌子上进行一些操作(重新创建表格),也应该尽可能减少停机时间。

示例API响应:

[
    {
        "company": "XYZ",
        "company_id": 123,
        "owner": null,
        "owner_id": null
    },
    {
        "company": null,
        "company_id": null,
        "owner": "ABC",
        "owner_id": 321
    },
    {
        "company": "XYZ",
        "company_id": 123,
        "owner": null,
        "owner_id": null
    },
    {
        "company": null,
        "company_id": null,
        "owner": "PQR",
        "owner_id": 100
    }
]

数据库表应该按照给定的方式复制API响应 - 无论API结果中是否有任何错误/重复.API响应无法事先预测,也没有任何直接字段可以视为一个独特的身份。

我正在使用PHP-MySQL.API响应是JSON格式。我在SO中看到过类似的问题,但它并不能很好地满足我的要求,而且也没有接受的答案。

What is the best way to periodically load data into table

从上面的问题来看,我的情况似乎也需要使用某种临时表格。

考虑到安全性,性能和无停机时间,最优雅的方法是解决这个问题。在这种情况下使用哪种最好的MySQL存储引擎 - (InnoDB / MYISAM)? 请指教。

2 个答案:

答案 0 :(得分:2)

我不太确定您的要求是什么,以及为什么RichardBernards的答案不符合您的要求。

您谈论的是一个少于10,000个json对象的数组,从而产生一个少于10,000行的表。 json和最后一行之间的差异很容易适合内存。您可以生成一个长sql脚本,其中包含应用更新所需的所有插入,更新和删除,并在一个事务中应用更新。

从要求中不明确的一件事是提及"实时"并提到这个"每日"更新,这显然是一种批处理类型。您将更新描述为批次,但是提到有实时要求吗?

如果您确实需要连续访问但不需要实时数据,则可以使用新值构建新表,并按照https://dba.stackexchange.com/questions/22108/how-do-i-swap-tables-in-mysql中的说明重命名表。我们假设您有一个名为" CurrentValues"包含系统其余部分工作的数据,然后构建一个表" NewValues"看起来像你的" CurrentValues"表会在瞬间看起来像。然后,您重命名" currentValues" - >" oldvalues"," newValues-> currentValues"在一个原子交易中。然后执行删除" oldvalues"。如果你是幸运的"来自API的数据是一个完整的列表,可以插入到你的" NewValues"表。

答案 1 :(得分:1)

要实时更新:

  

您可以在本地副本中添加标记(类似于更新的标记)   旗)。在更新之前,将所有记录设置为已更新= 0   API结果解析过程,更新和插入设置更新的标志   解析过程完成后,删除所有记录   仍设为updated = 0

当您按特定顺序收到ID时,您可以简化此过程(通过首先从数据库中检索相同顺序的集合,您将知道丢失了哪一个)。你几乎可以在飞行中删除丢失的那些。

在你的例子中显示这个;您收到的第二天A1,A2,A3,A5,A6。您从本地副本加载前5个记录(因为只有4个,最终得到A1,A2,A3,A4) 您迭代API接收的值(伪代码):

$difference = array_diff($localCopyItems, $apiItems);
// $difference now contains all items present in $localCopyItems which are not present in $apiItems
foreach($difference as $deletionItem) {
    // delete $deletionItem from database
}

当然,这是一个过于简单的例子,但这就是它的主旨。