我在服务器上有多个数据库,每个数据库都有一个大表,其中大多数行在所有数据库中都是相同的。我想将此表移动到共享数据库,然后在每个应用程序数据库中都有一个覆盖表,该表具有共享表和原始表之间的差异。
目的是使数据更新和分发更容易,同时保持数据库大小不变。
问题限制
该表是具有基于日期的有效性的分层数据存储。
table DATA (
ID int primary key,
CODE nvarchar,
PARENT_ID int foreign key references DATA(ID),
END_DATE datetime,
...
)
DATA中的每个唯一CODE可能有多行,但最多只有一行,其中END_DATE为null或大于当前时间(每个CODE一个有效行)。新引用仅针对有效行。
更新共享数据库不应要求在应用程序数据库中运行任何内容。这意味着任何覆盖表一旦生成就是最终的。
对DATA.ID的现有引用必须指向相同的CODE,但其他列不需要相同。这意味着如果需要,任何当前行都可以无效,并且可以组合多次出现的相同CODE。
PARENT_ID引用在拆分之前和之后必须具有相同的父CODE。如有必要,实际的PARENT_ID值可能会发生变化。
共享表定期从外部源更新,这些更新需要反映在每个数据库的DATA中。未出现在外部源中的代码可被视为无效,不会添加对这些代码的新引用。
现有功能将继续使用DATA,因此新视图(或替代)必须是透明的。但是,它可能包含的行数比原先提供的约束条件要多。
新功能将直接使用共享表。
选择性能是一个问题,插入/更新/删除不是。
该解决方案需要支持SQL Server 2008 R2。
可能的解决方案
-- in a single shared DB
DATA_SHARED (table)
-- in each app DB
DATA_SHARED (synonym to DATA_SHARED in shared DB)
DATA_OVERRIDE (table)
DATA (view of DATA_SHARED and DATA_OVERRIDE)
将现有的DATA表变为DATA_SHARED。
排除具有多个可能CODE的ID,因此只保留所有数据库中共有的行。第一次更新数据后,这些缺失的行将被添加回来。
不幸的是,每个DATA_OVERRIDE都需要所有表中不同的行,而不仅仅是DATA_SHARED和前一个DATA之间不同的行。有几个ID仅在单个数据库中有所不同,这会导致所有其他数据库膨胀。想法?
此解决方案导致DATA_SHARED具有不连续的ID空间。这是一个轻微的烦恼,而不是一个主要问题,但值得注意。
编辑:我应该能够保留DATA_SHARED中的所有行,只是使它们无效,然后我只需要在DATA_OVERRIDE中存储不同的行。
我想不出PARENT_ID引用变得无效的任何情况,想法?
在:
DB1.DATA
ID | CODE | PARENT_ID | END_DATE
1 | A | NULL | NULL
2 | A1 | 1 | 2020
3 | A2 | 1 | 2010
DB2.DATA
ID | CODE | PARENT_ID | END_DATE
1 | A | NULL | NULL
2 | X | NULL | NULL
3 | A2 | 1 | 2010
4 | X1 | 2 | NULL
5 | A1 | 1 | 2020
初始处理后(从DB1.DATA创建DATA_SHARED):
SHARED.DATA_SHARED
ID | CODE | PARENT_ID | END_DATE
1 | A | NULL | NULL
3 | A2 | 1 | 2010
-- END_DATE is omitted from DATA_OVERRIDE as every row is implicitly invalid
DB1.DATA_OVERRIDE
ID | CODE | PARENT_ID
2 | A1 | 1
DB2.DATA_OVERRIDE
ID | CODE | PARENT_ID
2 | X |
4 | X1 | 2
5 | A1 | 1
从外部数据更新后,其中A1存在于源中但X和X1不存在:
SHARED.DATA_SHARED
ID | CODE | PARENT_ID | END_DATE
1 | A | NULL | NULL
3 | A2 | 1 | 2010
6 | A1 | 1 | 2020
编辑:DATA视图类似于:
select D.ID, ...
from DATA D
left join DATA_OVERRIDE O on D.ID = O.ID
where O.ID is null
union all
select ID, ...
from DATA_OVERRIDE
order by ID
鉴于DATA_OVERRIDE中的行数很少,性能足够好。
替代
我还考虑过一种方法,而不是DATA_SHARED与原始DATA共享ID,将有映射表将DATA.ID链接到DATA_SHARED.IDs。这意味着DATA_SHARED会有更清晰的ID空间,并且可能会有更少的数据重复,但DATA视图需要一些相当重的连接。额外的复杂性也是一个重大的负面因素。
结论
感谢你的时间,如果你一直到最后,这个问题结束了很长时间,因为我正在思考它,因为我写了它。任何建议或意见将不胜感激。