我需要快速实现一个只读数据库,其中包含从两个相同结构的实时数据库中提取的数据。
实时数据库实际上是来自Dynamics会计系统的公司数据库,所以我很高兴有任何Dynamics特定的建议,但这主要是一个SQL问题。在Great Plains被微软收购之前,这是一个相当老的Dynamics版本。这是在SQL Server 2000上。
我们有访问动态数据的报告和应用程序。这些应用程序被设计成查看一个公司的数据库。现在我们需要添加另一个。这些报告和应用程序中的大多数都可以看到组合数据。他们并不真正关心订单或发票存在于哪一家公司。他们只看了一小部分表格。
在我看来,最简单的解决方案是创建一个只包含组合数据的报表数据库。最好是,我们需要一种有效的方法来更新这个数据库,每天更改几次。
我是一名开发人员,不是数据库专家,但我的计划是:
创建具有所需表的组合报告数据库,该表最初具有与实时数据库相同的表结构。
所有的Dynamic表似乎都有一个名为DEX_ROW_ID的int标识列,我不确定它是用来做什么的(它没有索引),但这似乎是唯一标识行的明显通用方法。在报告数据库上,我会将它更改为一个普通的int (而不是一个标识)。我将在所有数据库的DEX_ROW_ID上创建一个唯一的索引。
Dynamics没有时间戳,所以我将向实时数据库中的表添加一个时间戳列,并在报告数据库中添加相应的二进制(8)列。我假设并希望Dynamics不会被额外的索引和列打乱。
将int CompanyId列添加到报表数据库表中,并将其添加到任何唯一索引的末尾。即使没有这一点,大多数数据也自然是唯一的。也就是说,订单和发票编号等将是不同的两个直播直播。我们可能需要对应用程序做一些小的更改,但我不希望做太多的事情,除了将它们指向新的报告数据库。
假设我的报告数据库名为Reports,实时数据库为Live1和Live2,时间戳列称为TS,所有数据库都在同一服务器上……这是我第一次尝试使用更新脚本将Live1中名为MyTable的表中的更改复制到报告数据库。
USE Reports
CREATE TABLE #Changes
(
ReportId int,
LiveId int
)
/* Collect in a temp table the ids or rows which have been deleted or changed
in the live db L.DEX_ROW_ID will be null if the row has been deleted */
INSERT INTO #Changes
SELECT R.DEX_ROW_ID, L.DEX_ROW_ID
FROM MyTable R LEFT OUTER JOIN Live1.dbo.MyTable L ON L.DEX_ROW_ID = R.DEX_ROW_ID
WHERE R.CompanyId = 1 AND L.DEX_ROW_ID IS NULL OR L.TS <> R.TS
/* Delete rows that have been deleted or changed on the live db
I wonder if using join syntax would run better than the subquery. */
DELETE FROM MyTable
WHERE CompanyId = 1 AND DEX_ROW_ID IN (SELECT ReportId FROM #Changes)
/* Recopy rows that have changed in the live db */
INSERT INTO MyTable
SELECT 1 AS CompanyId, * FROM Live1.dbo.MyTable L
WHERE L.DEX_ROW_ID IN (SELECT ReportId FROM #Changes WHERE LiveId IS NOT NULL)
/* Copy the rows that are new in the live db */
INSERT INTO MyTable
SELECT 1 AS CompanyId, * FROM Live1.dbo.MyTable
WHERE DEX_ROW_ID > (SELECT MAX(DEX_ROW_ID) FROM MyTable WHERE CompanyId = 1)然后对Live2数据库执行相同的操作。对报告中的每个表重复此操作。我知道我应该使用参数@CompanyId而不是文字,但我不能对活动的数据库名称这样做,我可能会用C#程序或其他什么动态生成这些名称。
我正在寻找任何关于我在这里所做的事情的建议,建议或批评。我知道它不会是原子的。当此脚本运行时,实时数据库上可能会发生一些事情。我想我们可以接受这个事实。我们可能会在直播的dbs上没有发生任何事情的时候,每晚或每周做一份完整的拷贝。
我们需要更注重性能而不是优雅或完美。一些初始测试的第一个查询对于最大的表,TS比较运行了大约30秒,所以我乐观地认为这将会起作用,但我也想知道我是否遗漏了一些明显的东西,或者没有看到树的森林。
我们并不是真的想处理报表数据库上的日志文件。我们是否可以将其设置为简单恢复模式,而不考虑日志?
谢谢
发布于 2009-05-10 19:28:37
我认为这里有几个悬而未决的问题。
发布于 2009-05-10 19:14:28
我最不想做的事情就是编写一个自定义的更新脚本。首先尝试以下防弹方法:
这可能看起来像是蛮力。但是,由于您正在复制一个2000年代的数据库,因此暴力破解对于今天的硬件来说不是问题。作为一个额外的优势,这些方法可以由系统管理员而不是开发人员支持。
方法1具有作为备份验证的附加优势。:)
https://stackoverflow.com/questions/845842
复制相似问题