обнаружение, когда данные изменились

Хорошо, таким образом, история похожа на это:

- У меня есть много файлов (довольно большой, приблизительно 25 ГБ), которые находятся в конкретном формате и должны быть импортированы в хранилище данных

- эти файлы непрерывно обновляются с данными, иногда новыми, иногда те же данные

- Я пытаюсь выяснить алгоритм о том, как я мог обнаружить, если что-то изменилось для конкретной строки в файле для уменьшения потраченного обновления времени базы данных

- путем это в настоящее время работает, теперь то, что я отбрасываю все данные в базе данных каждый раз и затем повторно импортирую его, но это не будет больше работать, так как мне будет нужна метка времени для того, когда объект изменился.

- файлы содержат строки и числа (заголовки, заказы, цены и т.д.)

Единственные решения, о которых я мог думать:

- вычислите хеш для каждой строки от базы данных, что это сравнено с хешем строки из файла и если они отличаются обновление база данных

- сохраните 2 копии файлов, предыдущих и текущих и сделайте diffs на нем (которые, вероятно, быстрее, чем обновление дб), и на основе тех обновляют дб.

Так как объем данных является очень большим к огромному, я отчасти вне опций на данный момент. На длительном периоде я избавлюсь от файлов, и данные будут продвинуты прямо в базу данных, но проблема все еще остается.

Любой совет, будет цениться.

5
задан hyperboreean 19 July 2010 в 07:25
поделиться

4 ответа

Вместо того, чтобы вычислять хэш для каждой строки из базы данных по запросу, почему бы вам не сохранить вместо этого хеш-значение?

Тогда вы могли бы просто вычислить хеш-значение файла в вопрос и сравните его с данными, хранящимися в базе данных.

Обновление :

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

1
ответ дан 14 December 2019 в 18:54
поделиться

Ну, независимо от того, что вы используете, ваш худший случай будет O(n), что при n ~ 25GB данных не очень красиво.

Если только вы не сможете изменить процесс записи в файлы.

Поскольку вы не обновляете все 25 ГБ постоянно, это ваш самый большой потенциал для экономии циклов.

1. Не пишите случайно
Почему бы вам не сделать процесс, который записывает данные, только append? Так у вас будет больше данных, но у вас будет полная история, и вы сможете отследить, какие данные вы уже обработали (что вы уже положили в хранилище данных).

2. Храните список изменений, если вы должны писать в случайном порядке
В качестве альтернативы, если вы действительно должны делать случайные записи, вы можете хранить список обновленных строк. Этот список может быть обработан, как в #1, и вы сможете отследить, какие изменения вы обработали. Если вы хотите сэкономить немного места, вы можете хранить список блоков, в которых данные изменились (где блок - это единица, которую вы определяете).

Кроме того, вы можете хранить контрольные суммы/хэши измененных блоков/строк. Однако это может быть не очень интересно - вычисление не так дешево, и прямое сравнение может быть дешевле (если у вас есть свободные циклы процессора во время записи, это может сэкономить время чтения позже, YMMV).

Примечание(и)

  • И #1, и #2 интересны только если вы можете внести изменения в процесс записи данных на диск
  • Если вы не можете изменить процесс записи 25GB данных, то я не вижу, как контрольные суммы/хэши могут помочь... вам все равно придется прочитать все данные, чтобы вычислить хэши (поскольку вы не знаете, что изменилось), так что вы можете напрямую сравнить их во время чтения и составить список строк для обновления/добавления (или обновить/добавить напрямую)
  • Использование алгоритмов diff может быть неоптимальным, алгоритм diff не только ищет строки, которые изменились, но и проверяет минимальное расстояние редактирования между двумя текстовыми файлами при определенных параметрах форматирования. (в diff это можно контролировать с помощью -H или --minimal, чтобы работать медленнее или быстрее, т.е. искать точное минимальное решение или использовать эвристический алгоритм, для которого, если iirc, этот алгоритм становится O(n log n); что неплохо, но все же медленнее, чем O(n), который доступен вам, если вы делаете прямое сравнение строка за строкой)
1
ответ дан 14 December 2019 в 18:54
поделиться

Определение проблемы в понимании .

Допустим, ваш файл содержит

ID,Name,Age
1,Jim,20
2,Tim,30
3,Kim,40

Как вы сказали, Строка может быть добавлена ​​/ обновлена, следовательно, файл становится

ID,Name,Age
1,Jim,20    -- to be discarded 
2,Tim,35    -- to be updated
3,Kim,40    -- to be discarded 
4,Zim,30    --  to be inserted 

Теперь требуется обновить базу данных, вставив / обновив только более 2 записей в двух запросах sql или 1 пакетный запрос, содержащий два оператора sql.

Я делаю следующие предположения здесь

  • Вы не можете изменять существующий процесс для создания файлов.
  • Вы используете некоторую пакетную обработку [Чтение из файла - Обработка в памяти - Запись в БД] для загрузки данных в базу данных.

Сохраните хеш-значения записи [имя, возраст] по отношению к идентификатору на карте в памяти, где идентификатор является ключом, а значение - хешем [если вам требуется масштабируемость, используйте hazelcast].

Ваша пакетная структура для загрузки данных [опять же, предполагая, что одна строка файла обрабатывается как одна запись], должна проверять вычисленное значение хеш-функции на соответствие идентификатору в карте в памяти. Первое создание также может быть выполнено с использованием вашей пакетной среды. для чтения файлов.

 If (ID present)
--- compare hash 
---found same then discard it
—found different create an update sql 
In case ID not present in in-memory hash,create an insert sql and insert the hashvalue

Вы можете использовать параллельную обработку, обработку фрагментов и разделение данных в памяти с помощью spring -batch и hazelcast.

http://www.hazelcast.com/

http://static.springframework.org/spring-batch/

Надеюсь, это поможет.

3
ответ дан 14 December 2019 в 18:54
поделиться

практически это проблема, которую нужно решать с помощью программного обеспечения для резервного копирования, так почему бы не использовать некоторые из их стандартных решений? Лучше всего перехватить вызовы WriteFile, чтобы вы получали обратные вызовы при каждом обновлении. Это будет хорошо работать с двоичными записями.

Я не могу понять: на самом деле это текстовые файлы, которые не просто добавляются, но и обновляются? это крайне неэффективно (вместе с идеей хранить 2 копии файлов, потому что это ухудшит работу кеширования файлов).

0
ответ дан 14 December 2019 в 18:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: