我应该将多个客户压平成一行维度还是使用桥接表

时间:2013-04-04 08:35:46

标签: data-warehouse star-schema

我是数据仓库的新手,我有一个带有合同事实表的星型模式。它包含基本合同信息,如开始日期,结束日期,金额等。

我必须将这些事实与客户维度联系起来。每份合约最多有4个客户。所以我认为我有两个选择,或者我将4个客户排成一行,例如:

DimCutomers

name1, lastName1, birthDate1, ... , name4, lastName4, birthDate4

我听到的另一个选择是在事实和客户维度之间创建一个桥接表。从而使模型复杂化。

你觉得我应该怎么做?每种解决方案的优点/缺点是什么?是否有更好的解决方案?

2 个答案:

答案 0 :(得分:3)

我首先要创建一个客户维度,其中包含所有客户,每行只有一个客户。对于CRM和其他目的,客户维度本身可以是一个有用的工具,它意味着您将拥有一个单一,可靠的客户列表,这使得您实现的任何设计都变得更加容易。

之后,它取决于客户与合同之间的关系。我能想到的主要方案是:a)一个合同有4个客户'角色',b)一个合同有1-4个客户,都有相同的角色,c)一个合同有1个n个客户,都有同样的角色。

方案A将是每个合同有4个客户角色,例如一个客户要求签订合同,第二个签署合同,第三个人见证合同,第四个人为此付费。在这种情况下,您的事实表将包含每个合同一行和4个客户ID列,每列都引用客户维度:

...
RequesterCustomerID int,
SignatoryCustomerID int,
WitnessCustomerID int,
BillableCustomerID int,
...

当然,如果一个客户既是请求者又是证人,那么RequesterCustomerIDWitnessCustomerID中的ID都会相同,因为您的客户维度中只有一行。这是完全正常的。

方案B是所有客户都具有相同的角色,例如每份合同都有1-4个签署人。如果签署者的数量永远不会超过4,并且如果您非常确信这将“永远”成立,那么简单的解决方案也是在事实表中每个合同有一行,其中4列引用客户维度:

...
SignatoryCustomer1 int,
SignatoryCustomer2 int,
SignatoryCustomer3 int,
SignatoryCustomer4 int,
...

即使大多数合同只有1个或2个签名者,但表中有2个不常使用的列也没有太大的危害。

情景C是一个合同有1-n个客户的地方,其中n是一个变化很大的数字,甚至可能非常大(集体诉讼?)。如果您在一个合同上有50个客户,那么在事实表中添加50个列将变得难以管理。在这种情况下,我将添加一个名为ContractCustomers的桥接表或任何将事实表与客户维度相关联的表。这不像其他解决方案那样“整洁”,但纯粹的星型模式在处理这样的n:m关系方面并不是很好。

可能还有更复杂的情况,您可以混合方案A和C:合同有3个请求者,5个签署者,2个证人,并且在请求者之间分配3个方法。在这种情况下,您将别无选择,只能创建某种桥接表,其中包含每个合同的特定客户组合,因为它只能用一个事实和一个维度表来干净地表示。

答案 1 :(得分:0)

无论哪种方式都可行,但每种解决方案都有不同的含义。当然,您需要客户和合同表。一个关键问题是:它总是最多四个还是最终会增加?如果它将保持在4,那么您可以在合同中拥有一组包含4个客户ID的重复组。这样做的缺点是它是固定的。如果合同没有四个,则有一些空格。但是,如果可能有4个以上,那么唯一可行的解​​决方案是使用桥接表,因为在桥接表中,您可以通过插入新行来添加更多客户(不会更改表结构)。在固定解决方案中,在这种情况下,您可以通过更改表来添加4个以上的客户。桥接表是几十年来ER建模已经称为关联实体的一个例子。这两种解决方案更灵活。但是,我曾经使用过保证金制度,其中大额保证金需要五级经理批准。他们告诉我,已经五岁,将永远是五岁。每个审批经理代表不同的组织级别。在这种情况下,我们使用了一个包含五个经理ID的重复组,每个级别一个,并将它们包含在交易中。因此,了解当前的业务规则和未来前景非常重要。