您提到您目前有一个包含月度销售数据的事实表。所以每个客户每个月有一个记录。因此,该事实表中的每条记录实际上是相应维度在当月发生的单个销售“交易”的聚合。
因此,在给定的月份中,客户 123 可能有 5 笔单独的销售交易,每笔 10 美元......并且每笔单独的销售交易都可以由不同的销售代表(A、B、C、D、E)处理。在您描述的事实表中,客户 123 将有一条 50 美元的记录……但是我们如何为 SalesReps(ABCDE)建模?
根据你的目标...
- 能够保留在特定销售事实发生时哪个销售代表对客户负责的历史记录
- 了解销售代表办公室在特定销售事实发生时的位置
- 了解特定销售事实时客户组织的规模
...我认为以较低的粒度建模会更容易...特别是销售交易事实表,每个销售交易有 1 条记录。每个销售交易将有一个客户和一个销售代表。
FactSales
DateKey (date of the sale)
CustomerKey (customer involved in the sale)
SalesRepKey (sales rep involved in the sale)
SalesAmount (amount of the sale)
现在对于历史更改跟踪...任何具有要跟踪其历史更改的属性的维度都需要建模为“缓慢变化的维度”,因此需要使用“代理键”。因此,例如,在您的客户维度中,客户 ID 不会是主键...而只是业务键...您将使用任意整数作为主键...此任意键被引用to 作为代理键。
这是我为您的维度建模数据的方式...
DimCustomer
CustomerKey (surrogate key, probably generated via IDENTITY function)
CustomerID (business key, what you will find in your source systems)
CustomerName
Location (attribute we wish to track historically)
-- the following columns are necessary to keep track of history
BeginDate
EndDate
CurrentRecord
DimSalesRep
SalesRepKey (surrogate key)
SalesRepID (business key)
SalesRepName
OfficeLocation (attribute we wish to track historically)
-- the following columns are necessary to keep track of historical changes
BeginDate
EndDate
CurrentRecord
FactSales
DateKey (this is your link to a date dimension)
CustomerKey (this is your link to DimCustomer)
SalesRepKey (this is your link to DimSalesRep)
SalesAmount
这样做是允许您为同一客户拥有多条记录。前任。CustomerID 123 于 2012 年 3 月 5 日从 NC 移至 GA...
CustomerKey | CustomerID | CustomerName | Location | BeginDate | EndDate | CurrentRecord
1 | 123 | Ted Stevens | North Carolina | 01-01-1900 | 03-05-2012 | 0
2 | 123 | Ted Stevens | Georgia | 03-05-2012 | 01-01-2999 | 1
这同样适用于 SalesReps 或您想要在其中跟踪某些属性的历史更改的任何其他维度。
因此,当您按 CustomerID、CustomerName(或任何其他非历史跟踪属性)对销售交易事实表进行切片时,您应该看到一条记录,其中包含跨客户所有交易汇总的事实。如果您决定按 CustomerName 和 Location(历史跟踪的属性)分析销售交易,您将看到与客户在该位置时的销售额对应的客户位置的每个“版本”的单独记录。
顺便说一句,如果您有时间并且有兴趣了解更多信息,我强烈推荐 Kimball 圣经“数据仓库工具包”……它应该为维度建模场景提供坚实的基础。