在将数据暂存到生产中时,是否有非 DDL 方法来保留反向引用?

Aar*_*ght 5 sql-server-2008 sql-server etl

假设我有这个假设的模式:

源 (OLTP) 数据库:

Table Orders
------------
OrderID int IDENTITY (PK),
CustomerID int NOT NULL,
OrderAmount decimal NOT NULL
Run Code Online (Sandbox Code Playgroud)

目的地 (DSS) 数据库:

Table Activity
--------------
ActivityID int IDENTITY (PK),
PersonID int NOT NULL,
Amount decimal NOT NULL

Table ActivityOrderImport
--------------------
ActivityID int NOT NULL,
SourceOrderID int NOT NULL

Table CustomerMapping
---------------------
CustomerID int NOT NULL,
PersonID int NOT NULL
Run Code Online (Sandbox Code Playgroud)

显然,随着更多的转换,真正的交易要复杂得多。但暂时假设 ETL 所做的只是将来自外部实体的特定事务(“订单”)合并到跟踪通用“活动”的 DSS 中。外部客户和 DSS 人员之间的链接位于 CustomerMapping 表中。

“导入”表的想法是在出现问题时提供某种审计跟踪。我们对源系统没有太多控制权,并且知道它有点不稳定。因此,能够了解任何给定活动的起源对我们来说非常重要。

现在,有一个使用 DDL 执行此操作的脚本,如下所示:

ALTER TABLE Activity
ADD OrderID int NULL

MERGE Activity
USING #StagingOrders
(...)

INSERT ActivityOrderImport (ActivityID, SourceOrderID)
SELECT a.ActivityID, s.OrderID
FROM #StagingOrders s
INNER JOIN Activity a
    ON a.OrderID = s.OrderID

ALTER TABLE Activity
DROP COLUMN OrderID
Run Code Online (Sandbox Code Playgroud)

工作得很好,从不崩溃和燃烧的意义上说,每次我看到 DDL 都会让我感到恶心。

  • 向表中永久添加一OrderIDActivity确实不是一种选择,因为数据可能来自多个源,每个源当前都需要自己的日志表。为所有这些在主表中添加一个单独的列会破坏规范化并迅速将生产数据库变成狗的早餐。

  • IDENTITYActivity表中删除约束并使用一些自然派生键是更好的选择,但出于同样的原因仍然不切实际 - 因为每个系统都有不同的定义方式,我们最终不得不使用一nvarchar列作为主键(咳)。更不用说我们会失去对很多事情很重要的顺序性。

所以我一直在想,有没有更好的方法来做到这一点,不涉及 DDL 但仍然考虑到外部键的异构性质(因此需要为每个源使用不同的跟踪表)?

我不一定只要求一个可以在当前设计下工作的脚本。我意识到设计可能需要修改,我愿意创建更多的表,甚至是单独的临时数据库;唯一的东西,我舍得在这一点上做的是:(a)添加那些跟踪列的基表和/或(b)中删除IDENTITY字段。重要的是在这里保持关注点的分离并将实际活动数据与导入的“日志”数据分开。

关于我可以用这个设计做什么来实现这里的所有目标的任何想法,或者我把自己画在一个角落里,并在当前的限制下使这成为不可能?

Eri*_*elp 4

我建议向目的地添加一组(一组)临时表或可以更好控制且更稳定的中介。将跟踪信息放在那里。然后进行从暂存到最终目的地的所有转换,要么携带跟踪信息,要么丢弃它。

您可以通过多种方式从多个系统生成跟踪密钥,只要它们都遵循相同的算法,它不必是 INT。它可以是带有序列号的 2 个字符的前缀。就此而言,它不必只是一列。