事件多时如何设计事实表及其属性

Posted

技术标签:

【中文标题】事件多时如何设计事实表及其属性【英文标题】:How to design fact table when there are many events and its atttributes 【发布时间】:2018-07-17 15:39:04 【问题描述】:

我有一个场景要建立一个仓库来记录租赁活动。基本上,我有 3 个表,分别是rental_orders、rental_events 和rental_charges。表的架构如下,

Rental_orders:-

create table rental_orders
( order_id varchar(256),
order_item_id varchar(256),
rental_credit_amount numeric(28,4),
rental_credit_unit numeric(28,4),
customer_id varchar(512),
country_code varchar(56),
shipping_cost numeric(28,4),
return_cost numeric(28,4)
)

Create table rental_events(
order_item_id varchar(256),
event_id varchar(256),
event_type varchar(512),
charge_id varchar(1024),
event_start_date timestamp,
event_end_date timestamp,
extension_type varchar(256),
credit_amount decimal(28,4),
due_date_original timestamp,
due_date_extended timestamp
)
Create table rental_charges(
charge_id varchar(1024),
customer_id varchar(512),
charge_type varchar(1024),
amount decimal(28,4),
response varchar(1024)
)

以上架构遵循以下规则

    rental_orders 表中的order_item_id 可以有多个事件,这些事件是在rental_events 表中预设的。 rental_events 中的每个事件都可以有多个费用,这些费用存储在rental_charges 表中。

因此,要使用上述模式设计非规范化事实表,我曾考虑使用累积快照事实表,但在我的场景中,rental_order_item_id 可能会发生 35 个不同的事件,而我的企业想要记录数据和时间戳对于每一个事件。所以在我的情况下,一个事件可以有自己的extension_typecredit_amountdue_date_originaldue_date_extended,创建累积快照将有 35*4 = 140 列,这些列太多需要维护。

任何人都可以建议一种更好的方法来为上述表模式设计事实表。

【问题讨论】:

【参考方案1】:

根据您对所面临问题的描述,您可以使用这种方法,我称之为“透视事实”,它本质上是将值存储在行中,并带有指向父表的链接,避免多列。

创建表event_details

Create table event_details (
event_detail_id integer,       # primary key for this table
event_id varchar(256),         # link to parent table, use what makes sense for you
extension_type varchar(256),   # additional attributes for each event
credit_amount decimal(28,4),
due_date_original timestamp,
due_date_extended timestamp)

有了这个,您可以在行中为每个事件提供一个或多个详细信息,而不是创建 140 列。您始终可以根据要求为选择事件类型等创建派生表。

此外,如果可能的话,您可能需要考虑使用整数或 bigint 作为您的 ID,以获得最佳实践和性能。

【讨论】:

感谢 Mdem7 的回复。我认为将事件存储在行中可能会出现问题,因为当我们将 events 表与 rent_contracts 表连接以获取 shipping_cost、return_cost 等时,由于 Order_item_id 和 event_id 列之间的 1:M 多连接,度量值会被夸大.【参考方案2】:

事实上,数据仓库(如 Redshift)的 140 列单表并不是很大或新的,通常它被认为是好的设计。

Redshift 本身在单个表中支持多达 1600 列。

虽然,我理解将规范化数据转换为非规范化数据的挑战,但您可以提出好的 ETL 脚本和流程,在我看来这将是更好的设计。我们有类似的电子商务类别Tree structure 的用例,我们的OLTP 只有4 列,我们将其转换为Redshift 中的300 多列,效果很好。 希望对您有所帮助。

【讨论】:

以上是关于事件多时如何设计事实表及其属性的主要内容,如果未能解决你的问题,请参考以下文章

仓库设计:跟踪没有事件

数仓设计--事实表

使用父行 ID 设计事实表

如何避免星型模式中事实表之间的连接?

事实表事件使用啥维度”

wpf(Application 如何创建一个事件,及其Application相关的属性)