【问题标题】:"Master" associative table?“大师”关联表?
【发布时间】:2010-11-27 02:59:23
【问题描述】:

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

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

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

我突然想到:为什么不使用一个“主”关联表来保存所有关联?除了两个 PK 之外,它还需要此主表具有“关联类型”,并且所有 PK 必须具有相同的类型(整数、GUID 等)。

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

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

如果您能提供任何参考资料,我们将不胜感激。

【问题讨论】:

  • 收藏和投票,因为我有直觉认为这是一个非常糟糕的主意,但我无法确定确切的(技术)原因。有人可能会争辩说,您非常非常容易受到这种设置的锁定问题的影响,并且如果需要,您不能真正将元数据添加到您的多对多关系中。另外,我假设适当的 RDBMS 已针对处理您在案例中提到的情况进行了优化。
  • 这是我的想法,这就是为什么我很惊讶没有发现它被记录为一个非常糟糕的主意,至少在会有很多 CRUD 的地方。我怀疑在低 TX 量的情况下,查询可以在低隔离的情况下存在,它可能是可行的。我假设单个“主”表可能会产生更好的优化,但这可能取决于特定的 RDBMS。比较计划(与“master”与 reguar assoc 的)将是有益的。
  • 我认为类型将成为键或索引的高阶部分,因此连接将类似于:在 Type = 'Type1' AND PK1 = PK2?在这种情况下性能真的会更好吗?

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


【解决方案1】:

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

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

【讨论】:

  • 感谢 dacc,它为我提供了一个研究模式,也许可能会导致其他人。快速搜索发现了几篇与星型模式(仓储)相关的文章,这些文章描述了抵押审批和制造流程等应用程序的“累积快照”。这些与我的模型不平行,但模式确实有一些相似之处,并且使用视图作为别名的技术(例如客户端、联系人、服务等)可能很有用。我在假期有一些休息时间,可能会整理一些东西来看看它的表现如何。谢谢!
【解决方案2】:

首先,我认为您肯定会为可维护性付出代价。每当我有这样的“类型”列时,我认为是危险信号。它似乎可能会导致您的过程中出现魔术字符串——您需要确保插入和选择之间的类型是一致的,例如。因此,任何性能提升都需要足够大,才能证明这种令人头疼的问题。

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

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

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

第五,看起来很可能至少对于某些查询,您最终会加入那个巨大表的多个副本,这看起来真的是一个杀手。

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

【讨论】:

    【解决方案3】:

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

    个人客户、组织客户、服务提供者都是各方,扮演着不同的角色。

    电子邮件地址、电话号码、网址和实际地址都是地址。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多