Как выполнить SQL-подобное соединение в Perl? - PullRequest
8 голосов
/ 03 января 2012

Мне нужно обработать некоторые данные, объединив два разных файла. У них обоих есть два столбца, которые образуют первичный ключ, который я могу использовать, чтобы сопоставлять их рядом. Файлы в вопросах огромны (около 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 ]

8 голосов
/ 03 января 2012

Думаю, я бы просто создал новую базу данных mysql / sqlite / what и вставил строки.Должно быть ~ 20 строк perl.

Это, конечно, требует простого доступа к БД.

Думаю, вы также можете отсортировать файлы по интересующим полям, а затем для каждой строкиfile1 найти и распечатать соответствующие строки в file2.

2 голосов
/ 03 января 2012

Старомодный способ сделать это - использовать системные утилиты для сортировки обоих файлов в последовательности ключей и затем сопоставлять их построчно.Прочитайте оба файла, если ключи совпадают, выведите данные.Если они не совпадают, читайте файл с меньшим ключом, пока они не совпадут.Установите ключ бесконечно высоким для файла, если он нажмет eof.Когда оба ключа бесконечно высоки, все готово.

0 голосов
/ 09 января 2012

Также вы можете попробовать DBD :: AnyData

0 голосов
/ 09 января 2012

Вы также можете использовать мой 3-летний модуль CPAN Set :: Relation, который предназначен для таких вещей, что позволяет вам выполнять все функции SQL, такие как join в Perl.Создайте объект Set :: Relation для каждого файла и затем используйте метод join ().Тем не менее, этот реализованный модуль будет хранить все ваши операнды и приводить к памяти, поэтому он ограничен вашей оперативной памятью.Но вы по-прежнему можете посмотреть, как работает join (), и затем реализовать на его основе более эффективную версию для ваших целей.

0 голосов
/ 04 января 2012

Я на самом деле не пробовал, но более креативное решение может быть:

  1. Прочитайте каждый файл один раз и создайте карту между уникальными комбинациями id + dob и их позициями в файле. Используйте tell () .
  2. Создать карту в Perl
  3. Считать фактические данные из файлов, используя позиции на карте и sysread ()
  4. Записать данные в новый файл
0 голосов
/ 03 января 2012

Или, просмотрите эту замечательную статью Techrepublic - вам все равно может потребоваться 5 ГБ памяти.Интересно, где бы вы могли использовать утилиты сортировки / объединения CLI unix / linux?Просто мысль.

...