Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP是检查行是否存在的最有效方法_Php_Mysql_Doctrine - Fatal编程技术网

PHP是检查行是否存在的最有效方法

PHP是检查行是否存在的最有效方法,php,mysql,doctrine,Php,Mysql,Doctrine,考虑下表 +-------------+---------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------------+---------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL

考虑下表

+-------------+---------+------+-----+---------+----------------+
| Field       | Type    | Null | Key | Default | Extra          |
+-------------+---------+------+-----+---------+----------------+
| id          | int(11) | NO   | PRI | NULL    | auto_increment |
| date        | date    | NO   |     | NULL    |                |
| sku         | varchar(10)    |     |         | NULL           |         
| impressions | int(11) | NO   |     | NULL    |                |
| sales       | int(11) | NO   |     | NULL    |                |
+-------------+---------+------+-----+---------+----------------+
该表每天从前几天销售记录的批量下载中填充

每天下载的内容不仅包括前几天的销售数据,还包括过去90天的所有数据(可能有50k+记录)

但是,由于我们无法控制的事项,前几天的数据可能自原始插入后发生变化,例如:

第一天

Date: 2015-01-01
SKU:  ABCD
Impressions:  100
Sales: 0
第二天

Date: 2015-01-01
SKU:  ABCD
Impressions:  100
Sales: 3

Date: 2015-01-02
SKU:  ABCD
Impressions:  105
Sales: 0
因此,对于数据下载中的任何给定记录,它可能是

a) 已看到且与以前相同-忽略 b) 新建-添加到数据库 c) 已看到但新数据-更新

可以说,这可以通过检查每一行来解决

while (!$file->eof()) {
      $row = $file->fgets();
      $data = explode("\t", $row);
      $sku = $data[0];
      $date = $data[1];
      $impressions = $data[2];
      $sales = $data[3];
      $order = $em->getRepository('Orders')->findOneBy(['sku' => $sku, 'date' => $date]);
      if($order && $order->getImpressions() != $impressions && $order->getSales() != $sales) {
            $order->setImpressions($impressions);
            $order->setSales($sales);               
      } else {
        ... create new model
      }
      $em->persist($order);
}
然而,具有更新数据的行将是最小的,并且对每一行进行选择意味着由于行的数量太多,这项工作将非常缓慢

所以我的问题是,什么样的模式可以用来尽可能有效地解决这个问题


欢迎任何想法

我建议您用新下载的数据完全替换之前90天的数据。

理由很简单:

  • 执行此操作的处理时间很短。50000行在数据库中很小。我可能会这样做,即使它是一百万行
  • 尝试仅替换更改的行很复杂,可能会导致错误。
当你说“与以前一样”时,键似乎是
日期
库存单位
(组合),销售和印象是可以更新的字段。如果这是正确的,那么在MySQL中最有效的方法就是使用
INSERT。。。在重复密钥更新时…
查询:

  • date
    sku
    列上创建唯一键

  • 在php脚本中,预解析文件中的所有数据(如果愿意,也可以分批进行)

  • 运行与此类似的查询(从步骤1中解析的值中替换实际数据):

  • 几点注意:

    • 请查看有关此语法的详细信息
    • 如果第二天包含前一日期记录的数据更新是补充,您可以执行
      sales=sales+VALUES(sales)
      ,但我认为您的情况并非如此
    INSERT INTO
        mytable (`date`, sku, impressions, sales)
    VALUES
        ('2015-01-01', 'ABCD', 100, 3),
        ('2015-01-02','ABCD', 100, 3),
        ...
    ON DUPLICATE KEY UPDATE
        impressions = VALUES(impressions),
        sales = VALUES(sales)