Как выполнить SQL-подобное объединение в Perl?
Я должен обработать некоторые данные путем объединения двух разных файлов. У обоих из них есть два столбца, которые образуют первичный ключ, который я могу использовать, чтобы сопоставлять их рядом. Файлы в вопросах огромные (около 5 ГБ с 20 миллионами строк), поэтому мне нужен эффективный код. Как бы я сделал это в Perl?
Я приведу пример:
Если файл A содержит столбцы
id, name, lastname, dob, school
Файл B содержит столбцы
address, id, postcode, dob, email
Мне нужно объединить эти два файла, сопоставив id и dob в двух файлах, чтобы получить выходной файл со столбцами:
id, name, lastname, dob, school, address, postcode, email
6 ответов
Думаю, я бы просто создал новую базу данных mysql/sqlite/what и вставил строки. Должно быть ~20 строк perl.
Это, конечно, требует легкого доступа к БД.
Думаю, вы также можете отсортировать файлы по интересующим полям, а затем для каждой строки в file1 найти и распечатать соответствующие строки в file2.
Старый способ сделать это - использовать системные утилиты для сортировки обоих файлов в последовательности ключей, а затем сопоставлять их построчно. Прочитайте оба файла, если ключи совпадают, выведите данные. Если они не совпадают, читайте файл с меньшим ключом, пока они не совпадут. Установите бесконечно высокий ключ для файла, если он нажмет eof. Когда оба ключа бесконечно высоки, все готово.
Я на самом деле не пробовал это, но более креативное решение может быть:
Или просмотрите эту прекрасную статью Techrepublic. Тем не менее, вам все еще может потребоваться 5 ГБ памяти. Интересно, где бы вы могли использовать утилиты сортировки / объединения CLI unix/linux? Просто мысль.
Вы также можете использовать мой 3-летний модуль CPAN Set::Relation, который предназначен для таких вещей, что позволяет вам выполнять все функции SQL, такие как join в Perl. Создайте объект Set::Relation для каждого файла, а затем используйте метод join(). Тем не менее, этот реализованный модуль будет хранить все ваши операнды и приводить к памяти, поэтому он ограничен вашей оперативной памятью. Но вы все равно можете посмотреть в его источнике, как работает join(), а затем реализовать на его основе более эффективную версию для ваших целей.