数据保险库:临时表中的哈希键 - 高级
Posted
技术标签:
【中文标题】数据保险库:临时表中的哈希键 - 高级【英文标题】:Data vault: Hash keys in staging table - advanced 【发布时间】:2018-02-13 19:39:21 【问题描述】:我正在研究使用 datavault 2.0 方法。我了解散列并尝试应用它的原因。我想在数据库的“暂存”阶段应用它,而不是将其加载到 DV 中。
如果一个表中有业务键,那么很容易将其应用到该表(可能成为一个集线器)。但也有像“orderdetail”这样的表(可能成为链接),它们通过代理键多次引用其他元素。
临时表是否应该同时包含每个外键的代理序列以及引用实体 BK 的散列?
示例:如果我有一个带有 customerId 代理序列的订单表,但客户表有一个用作 BK 的 CUST-000xxx 引用,我是否应该在订单和客户之间执行“连接”以解决“CUST -000xxx" 这样我就可以对其进行哈希处理并将其包含在订单暂存表中?
我认为从暂存区加载 DV 中的数据时可能会解决此问题,但在该特定时刻暂存区中可能不存在客户参考,因为订单可能只是新的为未更改的现有客户的订单。
DV 2.0 指定使用哈希的所有这些业务都是为了提高性能并简单地并行加载数据,而无需在 DV 本身中进行昂贵的查找。因此,这个问题通常是如何解决的。
此处添加的示例:
订购 - 订单号 - 客户ID - order_ref - 销售人员
客户 - 客户ID - customer_ref
人 - 人物 - 全名 - 登录
为了填充订单,我是否应该像这样在源数据库中加入:
SELECT
hash_func(o.order_ref) as hash_key_order,
hash_func(c.customer_ref) as hash_key_customer,
hash_func(p.login) as hash_key_person,
o.orderid,
c.customerid,
p.login
FROM
order o inner join customer c on o.customerid = c.customerid
inner join person p on o.salespersonid = p.personid
或者是在datavault中解析的外键解析,所以查询更简单:
SELECT
hash_func(o.order_ref) as hash_key_order,
o.orderid,
c.customerid,
p.personid
FROM
order o
这对我来说不是很清楚。我的理解是,通过散列可以避免昂贵的查找,因此不为外键在暂存时生成散列不会影响性能?
【问题讨论】:
在我看来,这更像是一个业务规则问题而不是加载。如果是这样的话,现在在实际业务中如何解决空引用的问题?他们如何处理新订单或未更改客户的空键。在我看来,只有部分 Data Vault 被应用。也许用实际的行数据扩展问题以使其更清楚。 我添加了一个例子来说明清楚。 【参考方案1】:我不太确定为什么要使用复杂的 SELECT 语句来填充订单。此外,我认为关于 Data Vault 的范例可能存在一些混淆。您希望使用 Data Vault 执行的操作是从源系统读取所有数据。
这意味着首先您将表Order
加载到似乎使用Data Vault 建模的核心DWH 中。然后你会对Customer
、Person
等做同样的事情。直到您稍后需要让您的语句正常工作的所有数据都在核心 DWH 中。
每个实体都有自己的哈希键,具体取决于实体。例如。对于Order
表,这可能是id
。
现在,当所有内容都加载到 Data Vault 中时,您可以在数据之上重新创建业务规则。这意味着,如果您使用代理键,您可能需要重新创建它们。如果代理键是事先在数据库中创建的,并且它们具有商业价值,请使用它们。
但这取决于 ID 的使用。正如我之前评论的那样,您首先需要知道业务如何处理您提供的案例。然后,您将每个数据单独加载到 Data Vault 中。然后然后您继续重新创建您作为示例添加的语句。
所以:
复制数据 重新创建业务规则(如果订单没有客户会发生什么) 创建视图/持久表 使用数据【讨论】:
谢谢。 (我重新编辑了不正确的第二个查询)。在 dv 2.0 技术中让我感到困惑的是,哈希键被声明为一种提高性能的方法,但在加载章节中,BK 仍然会查找所有内容。书中的例子不是很好,因为它是从一个扁平的宽表中派生出来的,因此不关心典型的 3NF 数据中的外键(以及由此产生的连接?)。我认为这确实是这本书的一个缺点。 如果您指的是 Linstedt, Olschimke 的书,那么我认为此处打印的业务密钥仅用于示例。查看语句,每个实体都在自行加载。因此,在 DV2.0 意义上,您的所有陈述都不正确,但您应该单独加载每个实体。外键将在 Links 中解决。 当然,但我认为这是一个巨大的设计差距?很容易加载具有非常清晰的业务键的集线器和表,但链接没有与它们相关联的业务键,就像 datavault 方法中的集线器一样?即,这本书仅显示链接表上的哈希键,没有代理序列或自然键可以从这些表中查找。我在这里写了更多关于生成哈希的三种可能性:gtoonstra.github.io/etl-with-airflow/…。让我知道你的想法... 我仍然不确定我们是否处于同一水平。链接确实有关联的业务键 - 哈希键。如果您需要自然键,您可以加入集线器(这是一个好主意,因为集线器中的自然键应该被索引)或添加带有自然键的列。代理键可以 - 再次 - 像在您的业务中一样构建。就像在业务中一样,代理键是根据规则构建的。该规则可以在数据之上实施。您可以使用该规则建立代理链接。【参考方案2】:问题是您没有导出 BK。您正在导出代理键。在您的查询中将 o.orderid 更改为 o.order_ref 等,一切都应该就位。不幸的是,人们不了解 ID 背后的原因。它们是用于性能和管理目的的内部数据库元素,与业务无关。
pcd
【讨论】:
说得好。我仍然不确定 OP 的想法是否只是 Data Vault 方法建议的一半。 看到数据库开发人员/建模人员一开始在每个表中使用 ID 标识列却不知道为什么,这令人沮丧,然后他们无法满足对自然键的唯一约束表(和其他候选键)。为什么人们坚持执行“select * from以上是关于数据保险库:临时表中的哈希键 - 高级的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Firebird 2.1 中临时禁用表中的所有约束?