Анализировать и проверять данные текстового файла и импортировать их в базу данных MySQL

я использую PHP-спасательное анализировать и проверять данные в больших файлах, а затем импортировать эти данные в базу данных mysql.

Я уже знаю, что LOAD DATA INFILE может использоваться для чтения строк из текстового файла в таблицу, но не выполняет никакой проверки вообще.

Моя структура базы данных:

ItemsFile Таблица:

id  filename  fileepath  valid_items invalid_items processed_items  processed

Вещь Таблица:

id  uid  item file_id created_at

Мой Resque Job Class выглядит так:

PHP-спасательное разветвляется дочерний процесс и создает экземпляр класса ItemsFileProcessor

  1. setUp () вызывается
  2. выполнять () вызывается
/**
* Read and validate items form a file, and store them in a database.
*/

class ItemsFileProcessor {

//ItemsFile Model instance
private $items_file = null;

//Item Model instance
private $item = null;

//retrieved from ItemsFile table.
private $file = null;

public function __construct() {
$this->items_file = new ItemsFile();
$this->item       = new Item();
}

public function setUp() {

if (isset($this->args['file_id'])) {

//get file from ItemsFile Table by id.
$this->file = $this->items_file->getFile($this->args['file_id']);

if (empty($this->file)) {

//End job processing if file does not exist.
exit(-1);

}

}
}

function perform() {

//NodeJs, socket.io, redis, broadcasting system
EventBroadcaster::broadcast('app-jobs-channel', 'file_processing_started');

$processed_items = 0;
$valid_items     = 0;
$invalid_items   = 0;

//item validation class instance
$item_validator = new ItemValidator();

try {

$tmp_file = new SplFileObject($this->file->filepath);

//Read items from file, and validate each item.
while ($tmp_file->valid()) {
$line = trim($tmp_file->fgets());
if ($line !== '') {
if ($item_validator->isValid($line, new ItemValidationRule())) {

//store item in Item table.
$this->item->create([
'uid'     => 'foo',
'item'    => $line,
'file_id' => $this->file->id,
]);

$valid_items++;

} else {

$invalid_items++;

}

$processed_items++;

}
}

//update ItemsFile Table record
$this->items_file->update(
$this->file->id,
[
'processed_items'  => $processed_items,
'valid_items'      => $valid_items,
'invalid_items'    => $invalid_items,
'processed'        => 'Processed',
]
);

EventBroadcaster::broadcast('app-jobs-channel', 'file_processing_completed');

} catch (LogicException $exception) {

//broadcast failure.
EventBroadcaster::broadcast('app-jobs-channel', 'file_processing_failed');
Logger::getInstance()->log('ProcessContactFile Exception: '.$exception->getMessage(), Logger::LOGTYPE_ERROR);

exit(-1);

}
}

}

Мои проблемы:

  • Обработка файла занимает слишком много времени
  • Mysql должен обрабатывать все запросы вставки один за другим. ЗАГРУЗКА ДАННЫХ INFILE намного быстрее.

Мой вопрос:

Есть ли способ оптимизировать это или, может быть, ввести LOAD DATA INFILE как-то.

0

Решение

При управлении файлами с помощью PHP может возникнуть много проблем с производительностью. Затем я предлагаю вам сделать это с помощью SHELL, чтобы проанализировать файл и вернуть одну строку (которая представляет ваш общий запрос со всеми вашими вставками). Отныне вы просто должны выполнить этот запрос.

Может помочь, если не ясно.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]