3

我一直在寻找一些关于如何处理我正在从事的项目的建议,但无济于事。我几乎正在进行第四次改进我正在开发的“应用程序”的迭代;前两次在 Excel 中,第三次在 Access 中,现在在 Visual Studio 中。该领域是制造业。

基本思想是我从大型 Sybase 服务器获取只读数据,对其进行过滤并每天在 Access 中创建更小的表(使用删除和附加查询),然后做很多事情。更具体地说,我使用一系列查询来组合来自多个表的数据或以特定方式(聚合函数)对数据进行分组,然后将这些数据放入一个表中(这样我就可以使用 DAO.recordset 对数据进行排序和操作并运行多种自定义算法)。然后在整个数据库中重复此过程多次,直到创建一组相关表。

很多时候,我会在查询中创建一个值为 1.1 的字段,这样当我将它附加到表时,我可以将算法中的信息存储在字段中。因此,随着流程的继续,表格的字段数会发生变化。

整个应用程序由 4 个“后端”数据库组成,这些数据库在共享驱动器上链接在一起,具有各种输出(前端访问应用程序或 Excel)。

所以我的问题是,有多少数据驱动的应用程序可以解决问题?每个后端数据库每天都会使用新数据更新,每次更新大约需要 10 秒(3 秒)和 2 分钟(1 秒)。

项目目标。我想/即将迁移到 SQL Server。前端将是一个 Web 应用程序(我知道基本的 Web 开发,并且喜欢管理灵活性),Visual-studio 将是带有 c#/.NET 的 IDE。

这些算法应该在“数据库内部”运行,还是在每个服务器请求上使用一系列 C# 函数。我知道你不应该将数据存储在数据库中,除非它是一个实际的数据点,并且在 Access 中我有很多列只保存 vba 中算法的计算。

事实是,我见过多个专业的 Access 应用程序,但从未见过一个具有复杂性甚至接近我所做的(无论好坏)的应用程序。但我知道一些专业的软件应用程序比我的要好 1000 倍。

所以请请给我一些建议。我已经完全靠自己了,需要一些关于如何以正确的方式处理这个项目的指导。

4

3 回答 3

1

如果您打算使用 sql server 或任何其他完整的客户端服务器 DBMS,则诀窍(通常)是在服务器上做尽可能多的事情。

取决于您实际上是如何编写代码的。一般来说,桌面的优化与服务器的优化相反。

例如,如果您是 Find Customer 设施。

在桌面上,您将获得整个表格,然后使用说定位来按名称、邮政/邮政编码等查找记录。因为实际上您的应用程序既是服务器又是客户端。

在客户端服务器设置中,您将客户名称等传递给 DBMS,让它找到匹配的客户并仅将这些客户传回。

所以在你忘记web应用程序的情况下,你必须看看你的应用程序做了什么,然后说我可以用sql写这个吗?

所以

如果你有

// get orders 
foreach(Order order in clientOrders)
{
   if (Order.Discount > 0)
   {
      Order.Value = Order.ItemCount * Order.ItemPrice * Order.Discount;
   }
}
// save orders

你会用一个查询替换它

Update Orders Set Value = ItemCount * ItemPrice * Discount 
Where ClientID = @ClientID and Discount > 0

让服务器在服务器上完成工作,而不是将大量数据拉入和推出应用程序。

如果我是你,我会做 sql server 部分,或者我会做 web server 部分,而不是同时做两者。在客户端服务器方面有很多重叠。任何一个都不能排除另一个,但很多时候你可以使用其中任何一个来解决相同的问题,但方式略有不同。

于 2012-10-14T16:19:03.177 回答
1

随着更多细节的出现,您的应用程序的一个部分似乎涉及在您的 Access db 文件中存储 15K 行,以便您以后可以对这些数据执行计算。

但是,不清楚为什么您认为必须将这些数据存储在 Access 中才能执行计算。

理想情况下,我们会创建一个查询来要求服务器执行这些计算。如果您的服务器功能无法做到这一点,或者计算密集型以至于在服务器上放置了不可接受的处理负载,您仍然不需要将所有原始数据下载到 Access 以便将其用于计算。相反,您可以打开由服务器上的查询填充的记录集,在记录集行中移动以执行计算并将结果仅存储在 Access 表中(通过第二个记录集)。

Public Sub next_level_outline()
    Dim db As DAO.Database
    Dim rsLocal As DAO.Recordset
    Dim rsServer As DAO.Recordset
    Dim varLastValue As Variant

    Set db = CurrentDb
    Set rsLocal = db.OpenRecordset("AccessTable", dbOpenTable, dbAppendOnly)
    Set rsServer = db.OpenRecordset("ServerQuery", dbOpenSnapshot)
    Do While Not rsServer.EOF
        rsLocal.AddNew
        rsLocal!computed_field = YourAlgorithm(varLastValue)
        rsLocal.Update
        varLastValue = rsServer!indicator_field.value
        rsServer.MoveNext
    Loop
    rsLocal.Close
    Set rsLocal = Nothing
    rsServer.Close
    Set rsServer = Nothing
    Set db = Nothing
End Sub

这只是一个粗略的轮廓。很大程度上取决于YourAlgorithm(). 从评论中,我收集到它与前一行有关......所以我将varLastValue其作为占位符包含在内。

您的部分方法是将 200 万个源行过滤到适用于您选择的工厂的 15K 行。使用以下WHERE子句执行此操作ServerQuery

WHERE factory_id = 'foo'

如果行顺序对 很重要YourAlgorithm(),请在 中包含一个ORDER BY子句ServerQuery

此建议的驱动力是避免在 Access 中冗余存储数据。而且,如果你不能完全消除冗余,至少限制它的范围。

然后,您可能会发现可以将 Access 存储合并到一个 db 文件中,而不是四个。单个 db 文件可以简化应用程序的其他方面,并且还应该提供改进的性能。

我认为您应该确保在进入应用程序发展的下一个阶段之前彻底解决了这个问题。我不相信这个挑战在 ASP.Net 中会变得更容易。

于 2012-10-14T19:27:56.453 回答
1

您描述的应用程序似乎是“ ETL ”的一个示例 - 提取、转换、加载。

这是我作为专业程序员从事的第一个项目之一——而且它显然不平凡。您可以使用许多工具来帮助完成此过程(包括来自 Microsoft 的工具),但它们主要用于填充数据仓库 - 目前尚不清楚您正在构建什么,因此可能没有太大用处。不过,通读 Wikipedia 文章,或许可以查看一些 ETL 工具以获得一些想法。

如果你走自己的路,我建议编写一个 Windows 服务来自动运行你的 ETL 过程。我假设您在某种触发器上运行导入 - 每晚,每小时,当制造系统向您发送消息或其他时;编写您的 Windows 服务来轮询此触发器。

然后,我会从服务中执行您需要移动数据、运行算法等的任何数据库命令;注意错误处理和日志记录(服务没有用户界面,因此您必须将错误写入系统日志并确保有人注意)。考虑将您的数据库代码包装在存储过程中——这使得它们更容易从服务中调用。

听起来这是一个相当复杂的应用程序;注意代码质量,考虑单元测试(尽管很难对数据库代码进行单元测试)。购买 Steve McConnell 的“Code complete”,如果您不是专业的编码员,请从头到尾阅读。

于 2012-10-14T20:09:53.100 回答