Разработка приложения для обработки данных до создания базы данных
У меня есть большая коллекция данных в файле excel (и csv-файлах). Данные должны быть помещены в базу данных (mysql). Однако, прежде чем он попадет в базу данных, его необходимо обработать..например, если столбец 1 меньше столбца 3, Добавьте 4 к столбцу 2. Существует довольно много правил, которым необходимо следовать, прежде чем информация будет сохранена.
Что было бы хорошим дизайном для выполнения этой задачи? (используя java)
Дополнительные примечания
Процесс должна быть автоматизирована. В том смысле, что мне не нужно вручную входить и изменять данные. Мы говорим о тысячах строк данных с 15 столбцами информации в строке.
В настоящее время у меня есть своего рода схема цепочки ответственности. Один класс (Java) для каждого правила. Когда одно правило выполнено, оно вызывает следующее правило.
Подробнее
Обычно на лист данных приходится около 5000 строк. Скорость не является большой проблемой, потому что это большой вклад не случаться часто.
Я рассматривал слюни, однако не был уверен, что задача достаточно сложна для дролов.
Пример правил:
-
Все валюты (данные в определенных столбцах) не должны содержать символов валют.
-
Названия категорий должны быть одинаковыми (например, книжный шкаф = книжный шкаф)
-
Даты вступления не могут быть будущими датами
-
Ввод текста может содержать только [A-Z 0-9 s]
И т.д..
Дополнительно, если таковые имеются колонка информации является недействительным, он должен быть сообщенным когда
обработка завершена
(или, может быть, остановить обработку).
Мое текущее решение работает. Однако я думаю, что есть место для улучшения, поэтому я ищу для идеалов о том, как это может быть улучшено и или как другие люди справились с подобным ситуации.
Я рассматривал (очень кратко) использование слюней, но я не был уверен, что работа была достаточно сложной, чтобы воспользоваться слюнями.
8 ответов:
Если бы я не хотел сделать это за 1 шаг (как упоминает Оли), я бы, вероятно, использовал конструкцию трубы и фильтры. Поскольку ваши правила относительно просты, я, вероятно, сделаю пару классов на основе делегатов. Например (код C#, но Java должен быть очень похож...может быть, кто-нибудь сможет перевести?):
interface IFilter { public IEnumerable<string> Filter(IEnumerable<string> file) { } } class PredicateFilter : IFilter { public PredicateFilter(Predicate<string> predicate) { } public IEnumerable<string> Filter(IEnumerable<string> file) { foreach (string s in file) { if (this.Predicate(s)) { yield return s; } } } } class ActionFilter : IFilter { public ActionFilter(Action<string> action) { } public IEnumerable<string> Filter(IEnumerable<string> file) { foreach (string s in file) { this.Action(s); yield return s; } } } class ReplaceFilter : IFilter { public ReplaceFilter(Func<string, string> replace) { } public IEnumerable<string> Filter(IEnumerable<string> file) { foreach (string s in file) { yield return this.Replace(s); } } }
Оттуда вы можете либо использовать фильтры делегатов напрямую, либо подклассировать их для специфики. Затем зарегистрируйте их с помощью конвейера, который будет пропускать их через каждый фильтр.
Я думаю, что ваш метод в порядке. Особенно если вы используете один и тот же интерфейс на каждом процессоре.
Вы также можете посмотреть в кс го под названием приложении, в настоящее время на JBoss-правила. Я использовал это некоторое время назад для тяжелой части моего приложения, и мне понравилось, что бизнес-логика может быть выражена, например, в электронной таблице или DSL, которые затем компилируются на java (время выполнения, и я думаю, что есть также опция времени компиляции). Это делает правила немного более лаконичными и, таким образом, читаемыми. Это также очень легко учиться (2 дня или около того).
Вот ссылка на opensource JBoss-rules. Ат jboss.com вы, несомненно, можете приобрести официально поддерживаемую версию, если это больше по вкусу вашим компаниям.
Просто создайте функцию для принудительного применения каждого правила и вызовите каждую применимую функцию для каждого значения. Я не вижу, как это требует какой-то экзотической архитектуры.
Класс для каждого правила? неужели? Возможно, я не понимаю количество или сложность этих правил, но я бы (полу-псевдо-код):
public class ALine { private int col1; private int col2; private int coln; // ... public ALine(string line) { // read row into private variables // ... this.Process(); this.Insert(); } public void Process() { // do all your rules here working with the local variables } public void Insert() { // write to DB } } foreach line in csv new ALine(line);
Ваша методология использования классов для каждого правила звучит немного тяжеловесно, но она имеет то преимущество, что ее легко модифицировать и расширять, если появятся новые правила.
Что касается загрузки данных, то массовая загрузка - это путь. Я читал некоторую информацию, которая предполагает, что это может быть на целых 3 Порядка быстрее, чем загрузка с помощью инструкций insert. Вы можете найти некоторую информацию об этом здесь
Массовая загрузка данных во временную таблицу, а затем используйте sql для применения правил. используйте временную таблицу, как основу для вставки в реальную таблицу. отбросьте временную таблицу.
Вы можете видеть, что все различные ответы исходят из их собственного опыта и перспективы.
Поскольку мы мало знаем о сложности и количестве строк в вашей системе, мы склонны давать советы, основанные на том, что мы сделали ранее.Если вы хотите сузить свою реализацию до 1/2 решений, попробуйте дать более подробную информацию.
Удачи
Это может быть не то, что вы хотите услышать, это ни в коем случае не "забавный способ", но есть гораздо более простой способ сделать это.
Пока ваши данные оцениваются строка за строкой... вы можете настроить другой лист в файле excel и использовать функции стиля электронных таблиц для выполнения необходимых преобразований, ссылаясь на данные из необработанного листа данных. Для более сложных функций можно использовать встроенный в excel vba для записи пользовательских операций.
Я использовал этот подход много раз и это действительно хорошо работает; это просто не очень сексуально.