я использую 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
/**
* 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);
}
}
}
Мои проблемы:
Мой вопрос:
Есть ли способ оптимизировать это или, может быть, ввести LOAD DATA INFILE как-то.
При управлении файлами с помощью PHP может возникнуть много проблем с производительностью. Затем я предлагаю вам сделать это с помощью SHELL, чтобы проанализировать файл и вернуть одну строку (которая представляет ваш общий запрос со всеми вашими вставками). Отныне вы просто должны выполнить этот запрос.
Может помочь, если не ясно.
Других решений пока нет …