如何导出大尺寸的json feed到MYSQL表?

问题描述 投票:0回答:1

我有一个PHP脚本,从JSON feed导出数据到MYSQL表,下面是我使用的代码。

<?php
@ini_set( 'max_execution_time', 0);

require_once 'db_connect.php';

/* DEFINE TABLE NAME AND SOURCE URL HERE */
$str_tbl_name   = 'table_name';
$str_source_url = 'https://www.json-feed.com/example';

/* FETCH DATA FROM RESOURCE LINK */
$str_source_content = file_get_contents($str_source_url);
$arr_data           = json_decode($str_source_content);

$str_date_time  = date('Y-m-d H:i:s');
$str_start_date = date('Y-m-d H:i:s', strtotime($arr_data->meta->start_date));
$str_end_date   = date('Y-m-d H:i:s', strtotime($arr_data->meta->end_date));
$arr_value_sql  = [];
foreach ($arr_data->data as $data) {
    /* DATA CLEANSING */
    $data->source_subregion        = !empty($data->source_subregion) ? $con_db->real_escape_string($data->source_subregion) : null;
    $data->source_country_code     = !empty($data->source_country_code) ? $con_db->real_escape_string($data->source_country_code) : null;
    $str_input_name                = !empty($data->metadata->search_name) ? $con_db->real_escape_string($data->metadata->search_name) : null;
    $data->document_url            = !empty($data->document_url) ? $con_db->real_escape_string($data->document_url) : null;
    $str_document_tags             = !empty((array) $data->document_tags) ? $con_db->real_escape_string(serialize($data->document_tags)) : null;
    $data->document_sentiment      = !empty($data->document_sentiment) ? $con_db->real_escape_string($data->document_sentiment) : null;
    $data->source_name             = !empty($data->source_name) ? $con_db->real_escape_string($data->source_name) : null;
    $data->document_publish_date   = !empty($data->document_publish_date) ? $con_db->real_escape_string($data->document_publish_date) : null;
    $str_document_matched_keywords = !empty((array) $data->document_matched_keywords) ? $con_db->real_escape_string(implode(',', $data->document_matched_keywords)) : null;
    $data->document_language_code  = !empty($data->document_language_code) ? $con_db->real_escape_string($data->document_language_code) : null;
    $str_document_key_phrases      = !empty((array) $data->document_key_phrases) ? $con_db->real_escape_string(implode(',', $data->document_key_phrases)) : null;
    $data->document_hit_sentence   = !empty($data->document_hit_sentence) ? $con_db->real_escape_string($data->document_hit_sentence) : null;
    $data->document_hidden         = ($data->document_hidden === true) ? 'TRUE' : 'FALSE';
    $str_document_authors          = !empty($data->document_authors[0]->name) ? $con_db->real_escape_string($data->document_authors[0]->name) : null;
    $data->document_city           = !empty($data->document_city) ? $con_db->real_escape_string($data->document_city) : null;

    $str_value_sql = " ("
            . "'{$data->document_publish_date}'"
            . ", '{$data->document_url}'"
            . ", '{$data->source_name}'"
            . ", '{$str_document_authors}'"
            . ", '{$data->source_country_code}'"
            . ", '{$data->source_subregion}'"
            . ", '{$data->document_language_code}'"
            . ", '{$data->source_reach}'"
            . ", '{$data->source_ave}'"
            . ", '{$data->document_sentiment}'"
            . ", '{$str_document_key_phrases}'"
            . ", '{$str_input_name}'"
            . ", '{$str_document_matched_keywords}'"
            . ", '{$data->document_city}'"
            . ")";
    array_push($arr_value_sql, $str_value_sql);
}

现在的问题是,如果JSON feed是小尺寸的数据,低于100MB,一切顺利。但是有一个JSON feed的大小是1.5GB,即使我给它分配了8GB的内存,PHP也用完了。

我怎样才能在一个脚本运行中完成这个任务,或者怎样改变脚本,使它能将JSON feed分解,一次导出500行到MYSQL表中。

php mysql json scripting php-7
1个回答
0
投票

所以关于我在评论中说的。

基本上,当你正在建立 str_value_sql 数组不要把整个文件推送到它那里,做for循环,就像

for (i=1000; i<number_lines_in_feed; i+=1000) {
  for (j=0; j<i; j++) {
    array_push($arr_value_sql, $str_value_sql);
  }
  run sql query for insert
}

你要知道,这只是一个快速的例子,但这里的想法是,你解析的json数据对象一次1000项,这使得arr_value_sql小了很多,可能会使查询内存占用等很多小...... 我建议你可以试试... 我希望它适合你的json结构。

© www.soinside.com 2019 - 2024. All rights reserved.