Автор Тема: Слияние двух файлов при совпадении в строке  (Прочитано 22298 раз)

Оффлайн stranger573

  • Мастер
  • ***
  • Сообщений: 1 434
    • Email
Во времена 64-разрядных систем и гигабайт памяти? Ну в своп уедет.
Реестр (одна таблица) в xml больше 20ГБ. В csv поменьше будет (сколько пока точно не знаю), но всё же. Свопа хватит хотя-бы на две таблицы?

Оффлайн asy

  • alt linux team
  • ***
  • Сообщений: 8 099
Во времена 64-разрядных систем и гигабайт памяти? Ну в своп уедет.
Реестр (одна таблица) в xml больше 20ГБ. В csv поменьше будет (сколько пока точно не знаю), но всё же. Свопа хватит хотя-бы на две таблицы?
Можно файл подключить в качестве свопа дополнительно.

Оффлайн stranger573

  • Мастер
  • ***
  • Сообщений: 1 434
    • Email
Используя INNER join мы можем потерять данные из первой таблицы.
Т.е. склеиваем две таблицы на основании первой. Если нет пересекающихся ID то данные из первой будут утеряны. А это плохо. Можно просто их пустыми оставлять и всё. Т.е. не заполнять данные в ячейке ( типа null или как то так).

Судя по всему надо использовать FULL Join. Что вы думаете?
Ой не надо. При таких размерах FULL будет работать очень долго, в этом случае сравниваются записи каждая с каждой и объём операций возрастёт неимоверно.
Теперь, когда немного вкурил условия предварительно могу сказать, что наиболее вменяемый результат получается с LEFT JOIN с подключением каждой последующей таблицы к первой опорной (вложения). Попробуйте прогнать мой пример на sqlite, по идее должно быть также.

С реальными таблицами: первой опорной таблицей должен быть реестр. Только там комбинация полей "инн", "наименование", "адрес" полна и уникальна, и эта таблица содержит все "инн" которые тоже сами по-себе уникальны. Для остальных таблиц это не так — там "инн" повторяются и вообще могут отсутствовать (например налоги не заплатили). Последнее только потом в сводной таблице можно проверить. Таблицу реестра нужно продёрнуть по адресу (получим региональную таблицу), что сильно уменьшит количество сравнений при объединении — она и станет первой опорной. Хорошо ещё то, что конвертер может в csv закатывать только нужные поля, отсекая остальные (это тоже уменьшает размер файла).

Оффлайн ASte

  • Мастер
  • ***
  • Сообщений: 1 549
При left outer join если в правой присоединяемой таблице будет несколько строк с одинаковым ИНН, то в итоговом наборе строки "задвоятся". Чтобы этого не было, нужно применять group by с агрегатными функциями, но на ваших предполагаемых  объемах в этом случае  без индексов будут тормоза ИМХО.

Оффлайн stranger573

  • Мастер
  • ***
  • Сообщений: 1 434
    • Email
При left outer join если в правой присоединяемой таблице будет несколько строк с одинаковым ИНН, то в итоговом наборе строки "задвоятся". Чтобы этого не было, нужно применять group by с агрегатными функциями, но на ваших предполагаемых  объемах в этом случае  без индексов будут тормоза ИМХО.
Если в присоединяемой таблице будет несколько строк с одинаковым "инн" то все эти строки должны быть в итоговом наборе. Если в присоединяемой таблице нет записей для "инн" левой таблицы — в итоговом наборе в этих строках будут пустые поля. Так и нужно получить. В итоговом наборе "инн" не является primary key и не должно быть, это поле для связывания таблиц только. Ничего там не "задвоится", поскольку в других полях присоединяемой таблицы другие данные. Будут повторены поля левой таблицы и к ним добавятся поля из присоединяемой. Выше показал же в примере оба варианта и как будет выглядеть итоговая таблица.

На этом этапе целью является получение таблицы в которой будут записи только для конкретного региона и сохранить все записи из исходных таблиц (для региона). В полученной таблице уже не будет того огромного количества записей и её можно вынести в другую БД и там уже группировать если такая необходимость будет.
« Последнее редактирование: 19.02.2019 14:41:50 от stranger573 »

Оффлайн rits

  • Завсегдатай
  • *
  • Сообщений: 1 031
  • ITS
Могу только посоветовать "курить" postgresql. Легко настраивается и устанавливается в альт линукс.
Каковы максимальные размеры для строк в таблице, таблиц и базы данных?

Существуют следующие ограничения:

Максимальный размер базы? неограничен (существуют базы на 32 TB)
Максимальный размер таблицы? 32 TB
Максимальный размер строки? 400 Gb
Максимальный размер поля? 1 GB
Максимальное количество строк в таблице? неограничено
Максимальное количество колонок в таблице? 250-1600 в зависимости от типа
Максимальное количество индексов в таблице? неограничено

Разумеется, понятие "неограничено" на самом деле ограничивается доступным дисковым пространством и размерами памяти/своппинга. Когда значения, перечисленные выше, неоправданно большие, может пострадать производительность.

Максимальный размер таблицы в 32 TB не требует, чтобы операционная система поддерживала файлы больших размеров. Большие таблицы хранятся как множество файлов размером в 1 GB, так что ограничения, которые накладывает файловая система, не важны.

Максимальный размер таблицы и максимальное количество колонок могут быть увеличены в четыре раза, если размер блока по умолчанию будет увеличен до 32k. Максимальный размер таблицы также может быть увеличен при использовании разбиения таблиц.

Существует ограничение, по которому индексы не могут создаваться для колонок длиннее чем 2,000 символов. К счастью такие индексы вряд ли действительно кому-то нужны. Уникальность гарантируется наилучшим образом с помощью функционального индекса из хэша MD5 длинной колонки, а полнотекстовое индексирование позволяет искать слова внутри колонки.
wiki

Создать таблицы, залить данные с помощью команды COPY и потом подключиться к базе с помощью той же либерой, командная строка подключения: dbname=telefons hostaddr=192.168.1.100 port=5432
И уже в удобном интерфейсе запросов (режим встроенный SQL) производить запросы в любых комбинациях и если таблицам добавишь индекс прямо в либре их редактировать, хоть в сыром виде хоть в форме да еще с любой точки удаленно. Всю работу сделает pstgresql возможно  даже без тормозов .
http://repo.postgrespro.ru/doc/pgproee/10.6.2/ru/postgres-A4-fop.pdf
« Последнее редактирование: 19.02.2019 14:50:01 от rabochyITs »

Оффлайн stranger573

  • Мастер
  • ***
  • Сообщений: 1 434
    • Email
Могу только посоветовать "курить" postgresql.
Спасибо, у меня они есть. Рабочие, но подключать к ним одноразовую задачу или ради одноразовой задачи развёртывать — желания нет.
Это хорошая БД в том, что может обрабатывать большие объёмы, но атомарные операции выполняет с той же скоростью, что и другие серверные БД.

Этот топик не появился бы в случае, если некая организация сделала выгрузку БД с нарезкой на регионы. Но они вывалили всё кучей и нарезали каждую таблицу на 6000-11000 файлов xml, причём с хаотическим распределением записей. Большой объём исходный, то что получается для региона уже можно вертеть как угодно хоть в электронных таблицах.
Поэтому интересно получить региональную БД не разворачивая серверных БД. После этого удалить исходные данные, большая часть которых совершенно не интересует.

Оффлайн ASte

  • Мастер
  • ***
  • Сообщений: 1 549
Этот топик не появился бы в случае, если некая организация сделала выгрузку БД с нарезкой на регионы. Но они вывалили всё кучей и нарезали каждую таблицу на 6000-11000 файлов xml, причём с хаотическим распределением записей
Регион же в ИНН закодирован? Файлы в csv (ну или преобразованы в csv). sed-м убираем все регионы, кроме интересующего во всех файлах, потом склеиваем их в один и потом уже грузим куда хотим - объем сильно уменьшится. не?
 

Оффлайн rits

  • Завсегдатай
  • *
  • Сообщений: 1 031
  • ITS
LibreOffice может csv подключить, как базу данных и прекрасно обработать ее sql ными запросами, тем более если эти файлы на ssd залить.

Оффлайн stranger573

  • Мастер
  • ***
  • Сообщений: 1 434
    • Email
Регион же в ИНН закодирован? Файлы в csv (ну или преобразованы в csv). sed-м убираем все регионы, кроме интересующего во всех файлах, потом склеиваем их в один и потом уже грузим куда хотим - объем сильно уменьшится. не?
Закодирован — первые две цифры. Объём уменьшится уже после конвертирования — одни и те же данные в xml 3,8МБ, в csv 600кБ. Можно не все поля сохранять, там много мусора для поставленной задачи (версия ПО, даты регистраций и т.д.). Ну и естественно выкусить нужный регион. Только это не избавит от конвертирования 90% заведомо ненужных данных. А конвертирование это самая затратная по времени операция у меня i5 в четыре потока делает ~1200 файлов в час. Но тут уж что есть, без вариантов.

Вот только вопрос был — как объединить таблицы.
« Последнее редактирование: 20.02.2019 14:11:47 от stranger573 »

Оффлайн stranger573

  • Мастер
  • ***
  • Сообщений: 1 434
    • Email
LibreOffice может csv подключить, как базу данных и прекрасно обработать ее sql ными запросами, тем более если эти файлы на ssd залить.
LO может подключаться к csv, dbf, MySQL, PostgreSQL, JDBC, ODBC. Это не полный список, в новых версиях встроенная БД уже firebird.
Я как правило делаю выгрузки в dbf и к ним подключаюсь. Только для dbf как и csv в режиме подключения нельзя делать запросы к нескольким таблицам (только к одной). Чтобы появилась такая возможность те же csv надо импортировать в hsqldb.

Соберу исходные таблицы в csv, первым делом LO Base и попробую. С sed-ом возиться не хочется.
« Последнее редактирование: 20.02.2019 14:18:47 от stranger573 »

Оффлайн rits

  • Завсегдатай
  • *
  • Сообщений: 1 031
  • ITS
Соберу исходные таблицы в csv, первым делом LO Base и попробую. С sed-ом возиться не хочется.
offtop:
https://www.powershelladmin.com/wiki/An_Advanced_Cmdlet_to_Merge_Csv_Files_in_PowerShell

Оффлайн stranger573

  • Мастер
  • ***
  • Сообщений: 1 434
    • Email
offtop:
В данном случае нужные поля выберет уже конвертер.

Быстро склеить csv (выполнить в каталоге с файлами):
Убрать или изменить расширение одного файла и указать его в качестве outfile.
$ find -name "*.csv" -exec tail -n +2 {} >> outfile \;
Команда за один проход вырежет первую строку в каждом присоединяемом csv и объединит в одном файле. В csv первая строка — заголовки полей. Файлы будут собраны не по порядку, но тут это не важно.
« Последнее редактирование: 21.02.2019 15:11:02 от stranger573 »