Php mysql | DB表导入策略

Php mysql | DB表导入策略,php,mysql,database,import,Php,Mysql,Database,Import,我正在编写DB导入函数。我的语言是php。我的数据是JSON格式的 我的代码如下: public function import($data = '') { if (!isset($data)) { return array( 'error' => "Error: no data" ); } $data_arr = json_decode($data, true); if (is_array(

我正在编写DB导入函数。我的语言是php。我的数据是JSON格式的

我的代码如下:

public function import($data = '') {

    if (!isset($data)) {
        return array(
            'error' => "Error: no data"
        );  
    }

    $data_arr = json_decode($data, true);

    if (is_array($data_arr) && sizeof($data_arr)) {

        // Truncate DB table

        $sql = 'TRUNCATE `ms_data`';
        $this->db->query($sql)->execute();

        // Import data
        $sql =  'INSERT INTO `ms_data` (
                `id`, 
                `name`, 
                `parent`, 
                `ordering`
                ) VALUES (
                    :id,
                    :name, 
                    :parent,  
                    :ordering
                )';

        foreach($data_arr as $d) {

            $this->db->query($sql)
                ->bind(":id",        $d['id'])
                ->bind(":name",      trim($d['name']))
                ->bind(":ordering", $d['ordering'])
                ->execute();
        }

        return array(
            'status' => 1,
            'message' => 'Data has been imported'
        );                  

    } else {

        return array(
            'error' => "Input is not array"
        );  
    }       
}
这是有效的代码,但是:也许你知道上面的代码问题,我现在不知道,或者有什么改进建议


谢谢

我看到一个问题:

如果您使用此功能加载了大量信息,则需要很长时间才能结束

您可以使用一个查询加载所有数据,代码如下:

<?php
public function import($data = '') {

   if (!isset($data)) {
      return array(
         'error' => "Error: no data"
      );    
   }

   $data_arr = json_decode($data, true);

   if (is_array($data_arr) && sizeof($data_arr)) {

         // Truncate DB table

         $sql   = 'TRUNCATE `ms_data`';
         $this->db->query($sql)->execute();

         $itemCount = count($data_arr);

         // Import data
         $sql       = 'INSERT INTO `ms_data` (
                     `id`, 
                     `name`, 
                     `parent`, 
                     `ordering`
                     )  VALUES ';

        for($i=1; $i <= $itemCount; $i++)
        {
            // Last item should not put comma after values. 
            if ($i == $itemCount)
            {
                $sql = $sql . "(?,?,?,?)"
            }
            else
            {
                $sql = $sql . "(?,?,?,?),"
            }
        }

        $stmt = $this->db->prepare($sql);

        $i = 1;
        foreach($data_arr as $d) {


             $stmt->bindParam($i++, $d['id'])
             ->bindParam($i++, trim($d['name']))
             ->bindParam($i++, $d['ordering']);
         }

         $stmt->execute();

         return array(
             'status' => 1,
             'message' => 'Data has been imported'
         );                 

    } else {

         return array(
            'error' => "Input is not array"
         ); 
    }
}       
?>


使用这种方式,您将在一个查询中插入所有行,这将大大减少执行时间,并且将是一个巨大的挑战。

如果您有大量数据,您应该执行以下操作:

1) 创建将用于加载数据的新表:
创建表新数据,如ms_数据

2) 按您认为合适的方式填充数据:即
插入新的数据值(?,?,?)

3) 用新表替换旧表:
将ms_数据重命名为旧ms_数据,将新ms_数据重命名为ms_数据
。此操作是原子操作,因此其他用户应该看不到它
4) 清理、删除旧表:
删除旧表数据

CREATE TABLE
DROP TABLE
RENAME TABLE
都会导致隐式提交,因此不能作为单个事务执行此操作,但由于
RENAME TABLE
替换“ms_data”中的数据的性质,这仍然是原子的


请注意,如果您对临时表使用静态名称(例如“new_data”),则无法同时执行两个加载过程。

希望您永远不必处理大量数据。此功能将用于我们的车间脚本(产品导入):)第一次审阅后,我有一些问题:请发布“SHOW CREATE TABLE ms_data”的输出以了解表结构的详细信息,好吗?您是将PDO用于mysql驱动程序还是mysqli类?:parent参数发生了什么变化?它永远不会被束缚。可能发布$this->db实例的类也会很有用。请注意,这在非常大的数据集上也会失败。这是数千或数百万,取决于MySQL的最大允许数据包,以及您设置的参数的大小。顺便说一下,上面的代码中有一些代码重复。更改为:
$sql=$sql。"(?,?,?,?)"; 如果($i<$itemCount){$sql.=',';}