我正在尝试执行以下操作。

我正在使用Web服务咨询外部数据库。 Web服务要做的就是将客户使用的ERP系统中的所有产品带给我。由于服务器和连接的速度不是很快,因此我决定要做的是基本上同步Web服务器上的数据库并在那里处理大多数操作,以便网站可以平稳运行。

一切正常,我只需要最后一步,以确保网站上的库存与ERP上可用的库存匹配。唯一的问题是当他们(客户端)删除ERP系统上的内容时。

目前,我正在考虑如果在Web服务结果中未收到产品,则从“产品”表中删除产品的理想策略(最少的资源和时间)是什么。

所以我基本上有以下过程:


我在Web服务中查询所有产品,给它们一些格式,然后将它们存储在数组中。最终大小约为600个索引。
然后,我要做的是执行一个foreach循环并具有以下子过程。


我查询数据库以检查是否存在product_id
如果存在该产品,我只需使用最新信息(库存数据)对其进行更新。
如果产品不存在,请插入。



因此,我正在考虑执行以下操作,但我认为这不是理想的方法:


进行SELECT * FROM Products并生成包含所有乘积的数组。
在结果阵列中执行一个foreach循环,然后在每个循环中扫描ERP阵列以检查特定产品是否存在。如果不是,请删除它;如果是,我继续下一个产品。


现在考虑到在完成上述所有步骤之后,这将涉及几个嵌套的foreach,我有点担心它可能会占用过多的内存,并且处理时间也会更长。

我当时以为也许array_diffarray map可以解决问题,但是我对这些功能并不真正了解,并且两个数组的结构差异很大,所以我不确定是否可以使用容易。

你们会推荐什么?

最佳答案

实际上很简单:

SELECT id FROM Products


然后,您有一个产品ID数组,例如:

[123,5679,345]


然后,当您进行更新或插入操作时,请从阵列中删除ID。


  [有关更新]我查询我的数据库以检查product_id是否存在。


现在这是多余的。

有几种方法可以从数组中删除值(当您进行更新时),这就是我可能要做的方法。

 if(false !== ($index = array_search($data['product_id'],$myids))){
   //note the !== type comparison because array_search can return 0 for the first index, we must check for boolean false.
   //find the index of the product id in our list of id's from local DB
     unset($myids[$index]);
     //If our incoming product_id is in the local list we Do Update
 }else{
     //Otherwise we Do Insert
 }


如上文所述,在执行更新/插入操作时,您不再需要检查ID是否存在,因为您已经通过从数据库中获取ID数组来知道这一点。仅此一项就可以节省您(n)个查询(apx 600)。

然后,如果您还有ID,则非常简单。

  //I wouldn't normally concatenate variables into SQL, in this case it's a list of int IDs from the database.
  //you can of course come up with a loop to make it a prepared statement if you wish, but for the sake of simplistically, I'll leave that as an exercise for another day..
  'DELETE FROM Products WHERE id IN('.implode(',', $myids).')'


并且由于您在更新时未设置这些设置,因此剩下的仅是不再存在的产品。

结论:

您别无选择(否则,请执行重复键查询或忽略异常),然后再提取产品ID。您已经在逐行执行此操作。这样一来,我们就能有效杀死2只鸟。

如果需要更多数据,则只需ID,例如,在进行更新之前,请检查产品是否已更改。然后拉出该数据,但我建议使用PDO和FETCH_GROUP选项。我不会详细介绍它,但是可以说它使您可以轻松地以这种方式构建数组:

 [{product_id} => [ {product_name}, {product_price} etc..]];


基本上product_id是具有行数据嵌套数组的键,这将使查找更加容易。

这样,您可以像这样查找它。

   //then instead of array_search
  //if(false !== ($index = array_search($data['product_id'],$myids))){

  if(isset($myids[$data['product_id']])){
     unset($myids[$data['product_id']]);
      //do your checks, then your update
  }else{
      //do inserts
  }


参考文献:

http://php.net/manual/en/function.array-search.php


  array_search —在数组中搜索给定值,如果成功,则返回第一个对应的键
  
  警告此函数可能返回布尔值FALSE,但也可能返回非布尔值,其值为FALSE。请阅读有关布尔值的部分以了解更多信息。使用===运算符测试此函数的返回值。


更新

还有另一种非常好的方法,那就是添加一个名为sync_date的字段,现在当您进行插入或更新时,将sync_date设置为当前数据。

这样,完成后,可以删除那些具有比今天更早同步日期的产品。在这种情况下,最好在执行操作时将时间缓存起来,以便您知道确切的时间。

$time = data('Y-m-d H:i:s'); //or time() if you prefer timestamp
//use this same variable for the whole coarse of the script.


那你就可以

 'DELETE from products WHERE sync_time != $time'


实际上,这可能会好一点,因为它具有更多的实用性。它是上一次运行的时间,现在您知道了。

10-06 05:24
查看更多