Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/64.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 寻找一种更有效的方法在我的数据库中存储CSV数据_Php_Mysql_Laravel - Fatal编程技术网

Php 寻找一种更有效的方法在我的数据库中存储CSV数据

Php 寻找一种更有效的方法在我的数据库中存储CSV数据,php,mysql,laravel,Php,Mysql,Laravel,我每天都会收到一个.txt文件,其中包含分号分隔的数据。我的应用程序的用户每天都要将此文件上载到数据库 目前,我正在读取并存储以下信息: $array = array(); $csv = str_getcsv($request->file, "\n"); foreach ($csv as &$row) { $row = str_getcsv($row, ";"); $array[] = $row; } array_splice($array, 0, 1); for

我每天都会收到一个.txt文件,其中包含分号分隔的数据。我的应用程序的用户每天都要将此文件上载到数据库

目前,我正在读取并存储以下信息:

$array = array();
$csv = str_getcsv($request->file, "\n");
foreach ($csv as &$row) {
    $row = str_getcsv($row, ";");
    $array[] = $row;
}
array_splice($array, 0, 1);

foreach ($array as &$row) {
    $query = Table::firstOrNew(['col2' => $row[1], 'col3' => $row[2]]);
    $query->col1 = $row[0];
    $query->col2 = $row[1];
    $query->col3 = $row[2];
    $query->col4 = $row[3];
    $query->col5 = $row[4];
    // [...]
    $query->col72 = $row[71];
    $query->col73 = $row[72];
    $query->save();
}
此方法的问题是,成功运行所需时间太长(每天的数据量约为5000条,使用上述代码需要约2分钟)。正如您所看到的,列的数量是巨大的,必须像处理.CSV文件一样读取数据,而且我根本不能丢弃任何列

更不用说,如果出于某种原因,一个用户(或多个用户)必须同时上传几天甚至一个月的数据,那么这个问题会大大增加


我需要想出更好的办法来处理这种情况。我到处寻找解决方案,但我能找到的最好办法是我应该使用
for
循环,而不是
foreach
,这并没有真正解决问题。

您正在检查每一行是否存在,如果存在,则更新,如果没有插入,对吗? 如果是这样,则无法优化此代码以加快运行速度,除非每行都有唯一的列,并在重复键更新时使用
运行原始查询参见:

第二种解决方案是删除属于该文件或用户的所有旧记录,或者删除一些无法上载两次的唯一记录,然后使用
insert
方法插入新行块 速度会快得多。范例

DB::beginTransaction();

try {
    Table::where('unique_file_rows_identified_column', $something)->delete();

    foreach(array_chunk($array, 1000) as $rows) {
        $rows_to_insert = [];
        foreach($rows as $row){
            $rows_to_insert[] = [
                'col1' => $row[0],
                'col2' => $row[1],
                'col3' => $row[2],
                'col4' => $row[3],
                'col5' => $row[4],
                // [...]
                'col72' => $row[71],
                'col73' => $row[72],
            ];
        }

        Table::insert($rows_to_insert);
    }
} catch (\Exception $e){ // If something went wrong and exception is thrown deleted rows will be restored
    DB::rollBack();
    dd($e->getMessage());
}
DB::commit();

如果文件包含5000行,则只运行5个查询,插入速度会快得多

是否可以选择让数据库为您完成这项工作

将数据填充'/tmp/user_DATA.csv'加载到以';'结尾的表测试字段中;


当然,您需要确保CSV有效。

谁使用这些数据?上传者是否拥有唯一的访问权限,还是所有人都可以访问?数据本身是否需要加载到数据库中,而不仅仅是保存路径?这需要用户两分钟的时间还是服务器两分钟的时间?我的意思是,用户可以在10秒钟后上传一个文件吗?所有用户都可以访问数据,并且在当前上传完成之前,用户无法上传另一个文件。这不会阻止其他用户上载。此外,数据需要加载到数据库中。当使用多个(批量)更新()/save()/::insert()时,最好使用
try/catch