Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/406.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database design &引用;大师;关联表?_Database Design_Design Patterns_Anti Patterns_Associative Table - Fatal编程技术网

Database design &引用;大师;关联表?

Database design &引用;大师;关联表?,database-design,design-patterns,anti-patterns,associative-table,Database Design,Design Patterns,Anti Patterns,Associative Table,考虑一个匹配客户机和服务的模型。客户可能在不同的时间既是服务的提供者又是服务的消费者。客户可以是个人或团体(公司),后者有多个联系人。联系人可能有多个地址、电话、电子邮件。其中一些关系将是一对一(例如,服务提供商对提供商),但大多数关系将是一对多或多对多(一家公司的多个联系人将具有相同的地址) 在此模型中,通常会存在多个关联表,例如,客户联系人、合同地址、联系人电话、联系人电子邮件、服务提供商、服务消费者等 假设您为给定服务的消费者发出一个简单的联系信息查询。除了包含数据的六个实体表之外,联接还

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

在此模型中,通常会存在多个关联表,例如,客户联系人、合同地址、联系人电话、联系人电子邮件、服务提供商、服务消费者等

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

但我突然想到:为什么不使用一个包含所有关联的“主”关联表呢?除了两个PK之外,它还需要此主表具有“关联类型”,并且所有PK都具有相同的类型(INT、GUID等)

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

我假设可能有一种模式(或反模式)描述这种方法,但在网上没有发现任何东西。有人试过吗?如果是,它是否具有规模


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

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


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

首先,我认为你肯定为可维护性付出了代价。每当我有这样一个“类型”专栏时,我都会觉得很危险。这似乎可能会在您的过程中产生神奇的字符串——您需要确保插入和选择的类型是一致的,例如,任何性能的提高都需要足够大以证明这一头痛

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

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

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

第五,至少在一些查询中,您很可能会加入这个巨大表的多个副本,这看起来真的是一个杀手


我很想看看您得到了什么结果,但如果有性能方面的好处,我会感到惊讶。

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

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


电子邮件地址、电话号码、Web地址和物理地址都是地址

我觉得这是一个非常糟糕的主意,但我不能确切地指出确切的(技术)原因。有人可能会说,在这种设置中,您非常、非常容易受到锁定问题的影响,如果需要,您无法向多对多关系中添加元数据。另外,我假设一个合适的RDBMS是为处理您在案例中提到的情况而优化的。这是我的想法,这就是为什么我惊讶地发现它没有被记录为一个非常糟糕的主意,至少在有大量CRUD的地方。我怀疑,在TX容量较低的情况下,如果查询的隔离度较低,那么它可能是可行的。我假设单个“主”表可能会产生更好的优化,但这可能取决于特定的RDBMS。比较这些计划(与“master”和reguar assoc比较)会很有启发性。我认为类型将成为键或索引的高阶部分,因此连接将类似于:on type='Type1'和PK1=PK2?在这种情况下,性能真的会更好吗?谢谢dacc,这给了我一个研究的模式,也许还可能导致其他模式。快速搜索发现了几篇与星型模式(仓储)相关的文章,描述了抵押贷款批准和制造流程等应用程序的“累积快照”。这些并不与我的模型平行,但模式确实有一些相似之处,使用视图作为别名的技术(例如客户端、联系人、服务等)可能会很有用。假期里我有一些休息时间,我可能会整理一些东西看看它的表现如何。谢谢