扩展 Bens 回答了一点问题,即数据仓库没有正确的答案——它是 IT 的一个广阔的、可变的领域,有很多思想流派。这是您可以追求的一种可能的方向。
假设:1)您有 2 个独立的源数据库,它们都有 2 个表:Product 和 Sales 2)独立的源数据库是孤立的,并且可能具有冲突的主键数据。3) 您想要对产品和销售表进行版本[1]。这是一个重要的假设,因为大多数事实表都没有更新,并且销售表听起来像是一个不错的静态事实表。您的问题不清楚您是否期望销售发生变化,所以我假设您会 4)销售记录只能是 1 个产品(这不太可能,但您的问题只提到了 2 个表格,因此从那里工作得不好,一个1-many 关系将涉及围绕桥接表进行更多调整)
仓库设计:
您将需要 3 个包含以下列的表:
PRODUCT_DIM
- PRODUCT_SK (代理主键数据仓库数据库生成)
- SOURCE_SYSTEM_ID (DW 特定指示符,说明记录来自哪个源 OLTP 数据库 - 如果您愿意,可以是字符串)
- PRODUCT_NK (源系统产品的PK,用于SCD操作)
- DATE_FROM (记录从)
- DATE_TO (记录活动到(当前为空))
- PRODUCT_NAME (源表的产品名称)
- 其他列(您可能需要的任何其他产品列)
SALES DIM
- SALES_SK (生成的代理主键数据仓库数据库)
- SOURCE_SYSTEM_ID (DW 特定指标,表明记录来自哪个源 OLTP 数据库 - 如果您愿意,可以是字符串)
- SALES_NK (来自源系统的销售记录的 PK,已使用用于 SCD 操作)
- DATE_FROM (记录活动自)
- DATE_TO (记录活动至(当前为空))
- SALE_AMOUNT (源表的产品名称)
-其他列(您可能需要的任何其他销售列)
PRODUCT_SALES_BRIDGE
- PRODUCT_SK (复合主键)
- SALES_SK (复合主键)
- DATE_FROM (记录活动自)
- DATE_TO (记录活动至(当前为空))
主要需要注意的是 SALES 和 PRODUCT 暗表中的标识符。
有一个自然键列,用于将每个记录的主键值与源系统中的内容完全相同。
因为您已声明您有多个源系统,所以需要额外的 SOURCE_SYSTEM_ID 列,以便您可以将多个源系统中的记录与仓库中的等效记录相匹配。否则,您的第一个源系统中可能有一个 ID 为 13 的 EGGS 产品,而您的第二个源系统中可能有一个 ID 为 13 的名为 MILK 的产品。如果没有额外的 SOURCE_SYSTEM_ID,您将永远削减 PRODUCT_DIM 自然键 13 的记录。这在您的仓库中看起来像这样:
PRODUCT_SK SOURCE_SYSTEM_ID PRODUCT_NK .. PRODUCT_NAME
..
14 1 13 .. EGGS
15 2 13 .. MILK
..
桥表的存在是为了防止新的 SALES 或 PRODUCT 记录在其相关记录发生更改时被剪切。考虑以 10 美元的价格出售 Red Eggs。下一个数据,红蛋产品更名为“超级红蛋”。这将导致仓库中 Red Eggs 的新 PRODUCT 记录。如果 SALES 表包含到 PRODUCT_SK 的直接链接,则新的 SALES 记录将被删除,仅仅是因为我们的 Red Eggs 有一个新的产品 SK。桥接表将新记录的参照完整性诱导切割从 DIMENSION/FACT 表移动到桥接表中。这还有一个额外的好处,那就是让数据仓库的新来者非常清楚他们以与传统 RDBMS 不同的思维方式运行。
2 个自然键列应该可以帮助您解决最初的问题,桥接表只是个人喜好,为了完整性而添加 - 如果您已经有适合您的 DW 设计,请坚持使用。
[1] 我将使用版本来指代您选择的不断变化的维度方法。大多数人便宜了他们的整个桌子,只是“以防万一”