“大师”联想表?

时间:2010-11-27 02:59:23

标签: database-design design-patterns anti-patterns associative-table

考虑匹配客户端和服务的模型。客户可能在不同时间成为服务的提供者和消费者。客户可以是个人或团体(公司),后者具有多个联系人。联系人可能有多个地址,电话,电子邮件。这些关系中的一些将是一对一的(例如,对提供商的服务),但大多数将是一对多或多对多(公司的多个联系人将具有相同的地址)。

在此模型中,通常会存在多个关联表,例如client_contact,contract_addr,contact_phone,contact_email,service_provider,service_consumer等。

假设您为给定服务的使用者发出简单查询联系信息。除了包含数据的六个实体表之外,连接还将引用五个关联表。关于这种查询当然没有什么特别有趣的 - 我们每天都这样做。

但是我想到了:为什么不拥有一个包含所有关联的“主”关联表?除了两个PK之外,它还需要这个主表具有“关联类型”,并且所有PK都具有相同的类型(整数,GUID等)。

一方面,查询会变得更复杂,因为每个连接都需要指定类型和PK。另一方面,所有联接都将访问同一个表,并且具有适当的indexng和缓存性能可以显着提高。

我假设可能有一种模式(或反模式)描述这种方法,但没有找到任何在线的东西。有人试过吗?如果是这样,它会扩展吗?

您可以提供任何参考资料。

3 个答案:

答案 0 :(得分:1)

您所描述的内容让我想起数据仓库中的事实表。我的理解是,您从一个典型的事务模式开始,使用表来模拟每个多对多关系。然后,要重构数据以便于进行维度分析,您可以将模式中的部分/全部关系聚合到一个宽表中,其中每列都是一个键。这有效地提前执行了所有可能的连接,并将它们转储到表中,将查询连接的目的从反对跟随转换为实体的属性。

无论如何,我对这些东西的理解是模糊的,我的经验实际上是零,但也许你的想法是另一个名字的事实表,使它们对调查有用。

答案 1 :(得分:0)

首先,我认为你肯定会为可维护性付出代价。任何时候我都有这样的“类型”专栏,我认为是红旗。它似乎可能会在您的过程中导致魔术字符串 - 您需要确保类型在插入和选择中是一致的,例如。因此,任何性能提升都需要足够大才能证明这种头痛。

其次,您需要为存储更多数据付出代价 - 每个关联的额外“类型”列。然后,在运行查询时需要检索此数据,这会影响一次可能在内存中的行数(可能)。

第三,每个查询可能需要访问相同的总行数,无论它们是存储在多个表中还是存储在一个表中。因此,除非您了解可以创建聚簇索引或其他内容的数据,否则在运行查询时可能会检索相同数量的页面。

第四,可能的性能提升来自假设索引具有对数行为,并注意到5log(N)大于log(5N),因此最好使用一个大索引而不是5个较小索引。但是,添加类型列会降低此优势。我不确定如何分析它是否会完全消除它,或者只是减少它。

第五,看起来很可能至少在一些查询中,你最终会加入那个巨大的表的多个副本,这看起来好像是一个杀手。

我有兴趣看看你得到了什么结果,但如果有性能优势,我会感到惊讶。

答案 2 :(得分:0)

这可以通过抽象和表继承来解决。

个人客户,组织客户,服务提供商都是扮演角色的各方。

电子邮件地址,电话号码,网址和物理地址都是地址。