【问题标题】:Application design for processing data prior to database在数据库之前处理数据的应用程序设计
【发布时间】:2008-10-11 15:21:54
【问题描述】:

我在 excel 文件(和 csv 文件)中有大量数据。数据需要放入数据库(mysql)中。但是,在它进入数据库之前需要对其进行处理。例如,如果第 1 列小于第 3 列,则将 4 添加到第 2 列。在持久化信息之前必须遵循很多规则。

完成这项任务的最佳设计是什么? (使用java)

补充说明

这个过程需要自动化。从某种意义上说,我不必手动进入并更改数据。我们谈论的是数千行数据,每行包含 15 列信息。

目前,我建立了一种责任链设计。每个规则一个类(Java)。当一个规则完成时,它会调用以下规则。

更多信息

通常每个数据表大约有 5000 行。速度不是一个大问题,因为 这种大的输入并不经常发生。

我考虑过流口水,但我不确定任务是否复杂到流口水。

示例规则:

  1. 所有货币(特定列中的数据)不得包含货币符号。

  2. 类别名称必须统一(例如,书柜 = 书柜)

  3. 输入日期不能是未来日期

  4. 文本输入只能包含[A-Z 0-9 \s]

等等..
此外,如果任何一列信息无效,则需要在何时报告 处理完成 (或者可能停止处理)。

我当前的解决方案有效。但是我认为还有改进的空间,所以我正在寻找 关于如何改进以及其他人如何处理类似问题的理想 情况。

我曾考虑过(非常简短地)使用 drools,但我不确定这项工作是否足够复杂以利用 drools。

【问题讨论】:

    标签: java design-patterns chain-of-responsibility


    【解决方案1】:

    如果我不想一步完成(正如 Oli 提到的),我可能会使用 pipe and filters 设计。由于您的规则相对简单,我可能会做几个基于委托的课程。例如(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);
         }
      }
    }
    

    从那里,您可以直接使用委托过滤器,也可以根据具体情况对它们进行子类化。然后,将它们注册到将它们通过每个过滤器的管道。

    【讨论】:

      【解决方案2】:

      我认为你的方法还可以。特别是如果您在每个处理器上使用相同的接口。

      你也可以看看一些叫做 Drules 的想法,目前是 Jboss-rules。前段时间我将它用于我的应用程序的一个规则繁重的部分,我喜欢它的是业务逻辑可以用例如电子表格或 DSL 来表达,然后编译成 java(运行时,我认为有也是一个编译时选项)。它使规则更加简洁,因此更具可读性。它也很容易学习(2 天左右)。

      这里是开源Jboss-rules 的链接。在 jboss.com 上,如果更符合您公司的口味,您无疑可以购买官方维护的版本。

      【讨论】:

        【解决方案3】:

        只需创建一个函数来强制执行每个规则,并为每个值调用每个适用的函数。我不明白这需要任何异国情调的架构。

        【讨论】:

          【解决方案4】:

          每个规则都有一个类? 真的吗?也许我不了解这些规则的数量或复杂性,但我会(半伪代码):

          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);
          

          【讨论】:

            【解决方案5】:

            您为每个规则使用类的方法听起来确实有点重,但它的优点是在新规则出现时易于修改和扩展。

            至于加载数据批量加载是要走的路。我已经阅读了一些信息,这些信息表明它可能比使用插入语句加载快 3 个数量级。你可以找到一些关于它的信息here

            【讨论】:

              【解决方案6】:

              将数据批量加载到临时表中,然后使用 sql 应用您的规则。 使用临时表,作为插入真实表的基础。 删除临时表。

              【讨论】:

                【解决方案7】:

                你可以看到所有不同的答案都来自他们自己的经验和观点。

                由于我们对您系统中的复杂性和行数了解不多,因此我们倾向于根据我们之前所做的提供建议。

                如果您想将实施方案缩小到 1/2,请尝试提供更多详细信息。

                祝你好运

                【讨论】:

                  【解决方案8】:

                  这可能不是您想听到的,无论如何都不是“有趣的方式”,但有一种更简单的方法可以做到这一点。

                  只要您的数据逐行评估...您可以在 Excel 文件中设置另一个工作表并使用电子表格样式函数进行必要的转换,并引用原始数据表中的数据。对于更复杂的功能可以使用嵌入在excel中的vba来写出自定义操作。

                  我已经多次使用这种方法并且效果很好;它只是不是很性感。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 2011-12-07
                    • 1970-01-01
                    • 1970-01-01
                    • 2020-05-14
                    • 1970-01-01
                    • 2021-08-08
                    • 2018-01-31
                    相关资源
                    最近更新 更多