我一直在寻找一些关于如何处理我正在进行的项目的建议,但无济于事。我正在进行第四次改进我正在研究的“应用程序”;前两次是在Excel中,第三次在Access中,现在在Visual Studio中。该领域正在制造中。
基本思想是我从大型Sybase服务器获取只读数据,过滤它并在Access中创建更小的表(使用删除和追加查询),然后做一堆东西。更具体地说,我使用一系列查询来组合来自多个表的数据或以特定方式组合数据(聚合函数),然后将这些数据放入表中(这样我就可以使用DAO.recordset对数据进行排序和操作并运行多种自定义算法)。然后在整个数据库中重复此过程多次,直到创建一组相关表。
我会在查询中创建一个字段,其值为1.1,这样当我将其附加到表格时,我可以从算法中将信息存储在字段中。因此,随着流程的继续,表的字段数会发生变化。
整个应用程序由4个“后端”数据库组成,这些数据库在共享驱动器上链接在一起,具有各种输出(前端访问应用程序或Excel)。
所以我的问题是,有多少数据驱动的应用程序解决问题基本上有效?每个后端数据库每天更新一次新数据,每次更新大约需要10秒钟(三个)和2分钟(一个)。
项目目标。我希望/我很快就会转移到SQL Server。前端将是一个Web应用程序(我知道基本的Web开发和管理灵活性),visual-studio将是带有c#/ .NET的IDE。
这些算法应该在“数据库内部”运行,还是在每个服务器请求上使用一系列C#函数。我知道你不应该将数据存储在数据库中,除非它是一个实际的数据点,而在Access中我有很多列只能保存vba中算法的计算。
事实是,我已经看过多个专业的Access应用程序,并且从未见过一个具有复杂性或甚至接近我的做法(无论好坏)。但我知道一些专业的软件应用程序比我的好1000倍。
所以请请给我一些建议。我完全依靠自己,需要一些关于如何正确处理这个项目的指导。
答案 0 :(得分:1)
如果您要使用sql server或任何其他完整客户端服务器DBMS,那么(通常)就是尽可能在服务器上执行此操作。
取决于你是如何编写代码的。通常,桌面的优化与服务器的优化相反。
例如,如果您是查找客户工具。
在桌面上,您将获得整个表格,然后使用“说明定位”按名称,帖子/邮政编码等查找记录。因为您的应用程序实际上是服务器和客户端。
在客户端服务器设置中,您将客户名称等传递给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 piece,要么我做web服务器,而不是同时做两件事。就客户端服务器而言,存在很多重叠。两者都没有排除另一个,但很多时候你将能够用稍微不同的方式解决同样的问题。
答案 1 :(得分:1)
随着更多细节的出现,您的应用程序中有一部分涉及在Access数据库文件中存储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中会变得更容易。
答案 2 :(得分:1)
您描述的应用程序似乎是“ETL”的示例 - 提取,转换,加载。
这是我作为专业程序员工作过的第一批项目之一 - 这显然是非平凡的。您可以使用大量工具来帮助完成此过程(包括Microsoft的一个),但它们主要用于填充数据仓库 - 目前尚不清楚您正在构建的内容,因此可能不会非常有用。不过,请阅读维基百科的文章,或许可以看看一些ETL工具来获得一些想法。
如果你按自己的方式行事,我建议编写一个Windows服务来自动运行你的ETL过程。我假设您在某种触发器上运行导入 - 每晚,每小时,当制造系统向您发送消息或其他任何内容时;编写您的Windows服务以轮询此触发器。
然后,我会从您需要的服务执行任何数据库命令来移动数据,运行您的算法等;注意错误处理和日志记录(服务没有用户界面,因此您必须将错误写入系统日志并确保有人关注)。考虑将数据库代码包装在存储过程中 - 这样可以更容易地从服务中调用它们。
听起来这是一个相当复杂的应用程序;注意代码质量,考虑单元测试(尽管单元测试数据库代码很难)。如果您不是专业编码员,请购买史蒂夫麦康奈尔的“代码完整”并阅读封面以涵盖。