如何扁平化一对多的关系

Posted

技术标签:

【中文标题】如何扁平化一对多的关系【英文标题】:How to flatten a one-to-many relationship 【发布时间】:2014-10-08 07:34:32 【问题描述】:

在尝试使用 Talend 构建数据仓库应用程序时,我们面临以下情况。

我们有两个表格,看起来像

表主

ID | CUST_NAME | CUST_EMAIL
------------------------------------
1  | FOO       | FOO_BAR@EXAMPLE.COM

事件表

ID | CUST_ID | EVENT_NAME  | EVENT_DATE      
---------------------------------------
1  | 1       | ACC_APPLIED | 2014-01-01
2  | 1       | ACC_OPENED  | 2014-01-02
3  | 1       | ACC_CLOSED  | 2014-01-02

master 和 events 表之间存在一对多的关系。因为,鉴于事件名称的数量有限,我建议我们将此结构非规范化为看起来像

ID | CUST_NAME | CUST_EMAIL          | ACC_APP_DATE_ID | ACC_OPEN_DATE_ID |ACC_CLOSE_DATE_ID      
-----------------------------------------------------------------------------------------
1  | FOO       | FOO_BAR@EXAMPLE.COM | 20140101        | 20140102         | 20140103

DATE_ID 列引用时间维度表中的条目。

第一个问题:这是个好主意吗?该方案的其他替代方案是什么?

第二个问题:如何使用 Talend Open Studio 实现这一点?我想出了一种方法,使用tMap 组件将每个事件名称的数据与cust_id 一起移动到它自己的临时表中,然后使用另一个tMap 将它们链接在一起。在 talend 中是否有其他方法可以做到这一点?

【问题讨论】:

【参考方案1】:

要在 Talend 中执行此操作,您需要首先对数据进行排序,使其可靠地按照每个帐户的应用、打开和关闭顺序,然后将其非规范化为具有单个分隔字段的单行日期使用 tDenormalizeRows 组件。

在此之后,您将需要使用 tExtractDelimitedFields 来拆分单个日期字段。

【讨论】:

非常感谢。那也行。使用 tPivotToColumnsDelimited 组件怎么样? tPivotToColumnsDelimited 输出一个分隔文件,因此不适合您想要的。可以说,您可以输出一个临时文件,然后再将其读回,但这对于您的用例来说是混乱且不必要的。【参考方案2】:

是的,这是个好主意,这称为累积快照事实。 http://www.kimballgroup.com/2012/05/design-tip-145-time-stamping-accumulating-snapshot-fact-tables/ 不确定如何在 Talend 中执行此操作(不知道该工具),但使用 Case 或 Pivot 语句在 SQL 中很容易实现

【讨论】:

【参考方案3】:

仅关于您的第一个问题,这当然是一个好主意 - 除非同一个人有可能多次申请-打开-关闭他们的帐户并且您希望保留所有这些信息在他们的历史中(所以更新不会有帮助)。

【讨论】:

感谢您的意见。但这不是问题,因为真实结构包含每个帐户持有人的自然密钥..【参考方案4】:

如果您要设计数据仓库,Snowflaking 绝对不是一个好的选择。因此,在这种情况下,非规范化肯定是一个不错的选择。下面的文章几乎可以完美地消除这种情况的空气,

http://www.kimballgroup.com/2008/09/design-tip-105-snowflakes-outriggers-and-bridges/

【讨论】:

以上是关于如何扁平化一对多的关系的主要内容,如果未能解决你的问题,请参考以下文章

如何在greenDAO中设置一对多的关系?

如何实现一对多关系

如何与 Spring 和 thymeleaf 创建一对多的关系?

如何迭代到 Django 关系一对多的列表

一对多和一对多的关系 laravel

CoreData:查询一对多对多的关系