9

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

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

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

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

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

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

您可以提供的任何参考资料将不胜感激。

4

3 回答 3

1

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

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

于 2010-11-30T00:46:37.147 回答
0

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

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

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

于 2013-06-17T00:32:23.280 回答
0

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

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

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

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

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

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

于 2010-12-04T23:39:39.553 回答