对你的回调应用“深入”是不好的做法?

时间:2009-02-19 14:46:22

标签: database architecture

奇怪的问题,但我不确定它是否是反模式。

假设我有一个将1000条记录呈现给html表的Web应用程序。

我见过的典型方法是将查询发送到数据库,将记录以某种方式转换为某种抽象状态(无论是数组还是对象等),并将已翻译的记录放入集合中然后在视图中迭代。

随着记录数量的增加,这种方法会占用越来越多的内存。

为什么不在查询中发送回调,该回调在从数据库中读取每个已翻译的行时执行操作?这意味着您不需要在视图中收集数据以进行进一步迭代,因此内存占用量会缩小,并且您不会对数据进行两次迭代。

这种方法肯定存在一些隐含的错误,因为我很少看到它在任何地方使用过。这种方法有什么问题?

感谢。

5 个答案:

答案 0 :(得分:4)

实际上,这正是一个发展良好的应用程序的行为方式。

这种方法没有任何问题,除了并非所有数据库接口都允许您轻松完成此操作。

如果我们谈论对另一个社交网络的10记录进行制表,那么如果您可以通过一个已经为您实现的单个调用获得一系列哈希或其他任何内容,则无需使用回调。

答案 1 :(得分:1)

  

这种方法肯定存在一些隐含的错误,因为我很少看到它在任何地方使用过。

我用它。经常。即使我不会使用过多的内存重复复制数据,使用回调似乎更清晰。在带闭包的语言中,它还允许您将相关代码保存在一起,同时分解出混乱的数据库内容。

答案 2 :(得分:1)

这是一个“受你的工具限制”的问题类:大多数编程语言都不允许说“做这个代码的事情”。随着封闭的出现,这在近年来得到了解决。可以将闭包视为将代码传递到另一个方法的方法,然后在上下文中执行该方法。例如,在GSQL中,您可以写:

def l = []
sql.execute ("select id from table where time > ?", time) { row ->
    l << row[0]
}

这将打开与数据库的连接,创建语句和结果集,然后为DB返回的每一行运行l << it[0]。请注意,代码在sql.execute()内运行,但它可以访问lsql.execute())中定义的局部变量(row变量。< / p>

使用这种代码,您甚至可以随时生成HTTP请求的结果,而无需在RAM中保留大部分页面。在我的情况下,我只使用几KB的RAM将2MB文档传输到浏览器,然后浏览器会咀嚼83s来解析它。

答案 3 :(得分:0)

这大致是迭代器模式允许您执行的操作。在许多情况下,这会破坏应用程序和数据库之间的接口。像LINQ这样的技术甚至可以将代码发送回数据库。

答案 4 :(得分:0)

我发现使用接口解析器比深度回调更容易,因为它连接了几个类。 MS的版本比我的版本更加漂亮。这提供了一种更清晰的方式来访问不应该紧密耦合的类

http://www.codeplex.com/unity