当有许多事件及其贡献时,如何设计事实表



我有一个场景来构建一个用于记录租赁活动的仓库。基本上,我有三个表,分别是rent_orders、rent_events和rent_charges。表格的模式如下,

租金订单:-

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)
)

上述模式遵循以下规则

  1. rental_orders表中的order_item_id可以具有rental_events表中预设的多个事件
  2. rent_events中的每个事件可以具有存储在rental_charges表中的多个费用

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

有人能为上面的表模式提出一种更好的设计事实表的方法吗。

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

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

尽管我理解将规范化数据转换为去规范化数据的挑战,但你可以想出好的ETL脚本和流程,在我看来,这将是更好的设计。我们有类似的电子商务类别Tree structure的用例,并且我们的OLTP只有4列,我们在Redshift中将其转换为300+列,这很好。希望能有所帮助。

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

创建表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列。您总是可以根据需要为选择的事件类型等创建派生表。

此外,如果可能的话,为了获得最佳实践和性能,您可能需要考虑对id使用integer或bigint。

最新更新