Добрый день. Есть много организаций с почтовыми адресами, которые оказывают услуги.
Имеем XML файл в 13 000 000 строчек и весом в 1.2 GB
<companies_list>
<company>
<name>ООО "Солнышко"</name>
<type>Партнер<type>
<inn>775634541</inn>
<addresses_list>
<address>
<city>Москва</city>
<street>Солнечная улица, 5</street>
<services_list>
<service>Услуга 1</service>
<service>Услуга 2</service>
<service>Услуга 3</service>
</services_list>
</address>
<address>
<city>Нягань</city>
<street>Лунная улица, 5</street>
<services_list>
<service>Услуга 1</service>
<service>Услуга 5</service>
<service>Услуга 3</service>
</services_list>
</address>
</addresses_list>
<ogrn>5235452345235</ogrn>
<date>01.08.2017</date>
</company>
</companies_list>
Мне необходимо загнать это в базу, вида
'id','inn','ogrn','name','type','city','street'
и, соответственно, вторая таблица, связанной с первой, с помощью
key_id
'key_id','service'
Вариант 1
while ($reader->read()) {
if ($reader->nodeType == XMLReader::ELEMENT && XMLReader::ELEMENT !== 'companies_list') {
if ($reader->localName == 'company') {
$node = simplexml_import_dom($doc->importNode($reader->expand(), true));
try {
$id = ID::next()->getId();
$inn = (string)$node->inn;
$ogrn = (string)$node->ogrn;
$type = (string)$node->type;
$date = (string)$node->date;
foreach ($node->addresses_list->address as $address_list) {
$city = (string)$address_list->city;
$street = (string)$address_list->street;
$address_service = [];
foreach ($address_list->services->service as $service) {
$address_service[] = $service;
}
$insertQuery->execute([
':id' => $id,
':inn' => $inn,
':ogrn' => $ogrn,
':type' => $type,
':name' => $name,
':date' => $date,
':city' => $city,
':street' => $street
]);
foreach ($address_service as $row) {
$insertQueryWorks->execute([
':key_id' => $id,
':service' => $row
]);
}
}
}
В этом варианте скрипт работает, но порядка 23 часов. При этом (тут уже вопрос больше про mySql), непонятно, что сделать первичным или уникальным ключом. Скрипт отрабатывает положенные 300 000 компаний и не останавливается, а дальше продолжает работать. Второй минус - если я делаю запись в базу во внутреннем цикле - я не получу значение поля date - на тот момент оно недостижимо.
Вариант 2
Воспользоваться
LOAD XML
Его я еще не пробовал, ибо не могу сообразить, как один файл разбить на несколько таблиц. Когда то я делал с большим csv, как это сделать с xml, неясно
Кто что посоветует для загрузки большого XML?