假设我的公司销售许多产品,例如域名,T恤和货车。
在我当前的数据仓库星形模式设计中,我有一个包含以下(略微简化)模式的发票项目的事实表
fact_invoice_item
id | pk
invoice_item_id | id of invoice in OLTP
dim_customer_key | fk to customer dimension
dim_product_key | fk to product dimension
dim_billing_date_key | fk to date dimension
dim_due_date_key | fk to date dimension
invoice_amount | fact
item_amount | fact
dd_invoice_id | degenerate dimension to group together invoice items on the same invoice
我现在想开始围绕这些发票项目记录元数据。例如,如果购买了一个域名,那么域名是什么。如果购买了面包车,车牌号是多少。如果买了一件T恤,那是什么颜色。 (理想情况下)遵循星型/星座图式的最佳方法是什么?
当前思想:
选项1
拥有一个invoice_item_metadata
表中带有fk的通用invoice_item
维表。该维度表可以json格式存储项目元数据。甚至只是将购买的元数据以json形式存储在事实表中。这会使事情变得有些棘手,因为我需要解压json以便对其进行任何分析。
选项2
对于每种购买的产品都有一个事实表,例如fact_domain_purchase
和fact_van_purchase
。这些事实表可以具有自己的结构,以最适合产品元数据。这些似乎合乎逻辑,但随后我开始认为域更多是SCD,因为它可能具有诸如suspended / active / expired之类的属性,这些属性会随时间而变化。这使我认为我可以有一个fact_domain_purchase
表,并且fk到dim_domain
表,但是dim_domain
表的增长速度与fact_domain_purchase
相同表,这是不希望的。
有人对如何处理这种情况有什么聪明的主意吗?我敢肯定我不能成为第一个解决这个问题的人,但是我发现很难从Google获得任何有用的东西。预先感谢您的帮助
答案 0 :(得分:0)
理想情况下,商品属性应在产品尺寸中进行描述,即每种T恤衫的尺寸和颜色都有一个额外的product_id。
如果处理更多唯一项(属性未完全涵盖在产品维度中),则会在事实表中添加那些缺少的属性。
在一个主要事实表中的任何一个中,这意味着它包含所有产品子类型(T恤,货车,..)的属性,但仅填充所售子类型的属性,所有其他属性均为NULL。
或者(如果您的环境高度异构),您可以为每个子类型定义一个单独的事实表,该表与主事实表相关,并具有可选的1:1关系。 这里没有通用规则有效,唯一的可能性就是原型您的解决方案,看看什么可行,什么失败。
我绝对不建议使用替代键(例如dim_billing_date_key)作为时间维度,而不是本机DATE列(引用时间维度)。 事实表通常根据时间维度进行分区,并且代理键可能会干扰分区修剪,这是查询性能的关键-也在原型中进行仔细测试。
答案 1 :(得分:0)
我认为您需要解决where
和how
这两个问题,以存储您的元数据
对于存储,您的用例是Extension table
的完美示例
fact_invoice_item_ext
id | pk
fact_invoice_item_id | id of fact_invoice_item table
此表与事实表类似,但从本质上讲,它是事实记录的扩展,用于存储其他(可能也是可选的)数据
为此,由于您不知道数据的特征,因此可以在表中创建键值对以存储信息。与json相比,它更易于访问并且更易于管理,因此这些额外的列将存储键值对
attr_key | attribute key; domain, van, t-shirt etc.
attr_value | attribute value; domain name, license plate etc.
使用这种方法,您可以为发票项目添加多个其他属性(元数据)。
请告诉我这是否有意义,或者您对此概念还有其他疑问