假设我们有一个包含许多其他关联表的表的数据库。如果您绘制了数据库的图表,那么这将是中心的表格,其中有许多外键关系。它突然出现。
为了使其更具体,让我们说这个中心表中的两个记录是 Initech 和 Contoso 。 Initech和Contoso都与关联表中的许多其他记录相关联,例如 Employees , AccountingTransactions 等。假设两者合并(Initech购买了Contoso)并且从数据的角度来看,它真的就像合并所有记录一样简单。获取所有Contoso相关记录的最简单方法是什么,让它们指向Initech,然后删除Contoso?
使用CASCADE的更新非常接近,但是如果不关闭约束然后重新打开(yuck),它显然无法工作。
有没有一个很好的通用方法来做到这一点,而不是搜索每个链接表并逐个迁移它们?这必须是一个共同的要求。它出现在这个项目的两个地方,可以总结为:实体A需要控制实体B当前控制的所有内容。我怎样才能实现呢?
合并前:
Companies
ID Name
1 Contoso
2 Initech
Employees
ID Name CompanyId
1 Bob 1
2 Ted 2
合并后:
Companies
ID Name
2 Initech
Employees
ID Name CompanyId
1 Bob 2
2 Ted 2
我所有的搜索尝试都只提出了关于合并单独数据库的问题......很抱歉,如果之前已经提出这个问题。
答案 0 :(得分:1)
此查询可能依赖于供应商,但在MySQL中:
UPDATE Employees e, Cars c, OtherEntity o
SET e.CompanyId = 2, c.CompanyId = 2, o.CompanyID = 2
WHERE e.CompanyID = 1 OR c.CompanyId = 1 OR o.CompanyId = 1;
答案 1 :(得分:0)
简洁,不;没有通用的方法来做到这一点。
使用表Companies,Employees,Departments和AccountingTransactions来考虑您的示例数据库。
您需要删除其中一条公司记录(因为在合并之后,您只会记录当前的事务状态。)
您需要更改员工记录以更改雇用公司。但是,两家公司的员工编号很可能是N,其中一个(可能是Contoso)必须分配一个新的员工编号。
您可能面临的问题是Conotoso数据中的部门1是工程部门,但Initech的部门是财务部门。因此,您需要担心如何在两家公司之间映射部门编号,然后您面临将Contoso员工分配给Initech部门的问题。
对于历史会计事务,您可能必须将Contoso的历史会计记录保存为Contoso的名称,而某些(最新的)事务将需要迁移到Initech的名称。因此,也许您不会从公司表中删除Contoso记录,但您将无法使用它来识别任何新记录。
这些只是为什么这些映射无法轻易实现自动化的一小部分原因。
答案 2 :(得分:0)
不,没有简单的通用方法可以合并行并在整个系统中级联这些更改。您可以编写所有脚本 - 这可能是最佳方式,具体取决于您的方案 - 或设计解决方法。
一种解决方法可能是在中央表上实现父项模式(或将其抽象到另一个表)。然后你会得到像
这样的东西Companies
ID ParentID Name
1 2 Contoso
2 null Initech
或
Companies
ID ParentID Name
1 3 Contoso
2 3 Initech
3 null MegaInitech
并且您加入此中央Companies
表的所有查询现在都会检查ID和ParentID;
SELECT *
FROM Employees
WHERE CompanyId IN (SELECT ID FROM Companies WHERE ID = @id OR ParentID = @ID)
将其抽象为视图或函数
CREATE FUNCTION fn_IsMemberOf
(
@companyId INT,
@parentId INT
)
RETURNS BIT
AS
BEGIN
DECLARE @result BIT = 0
SELECT @result = 1 FROM Companies
WHERE ID = @companyId
AND COALESCE(ParentID, ID) = @parentID
RETURN @result
END
SELECT *
FROM Employees
WHERE fn_IsMemberOf(CompanyId, 1) = 1
(没有测试过,但你明白了)