2010-10-11 117 views
0

我目前有一个主表与其他多个表通过多对多连接(连接表)关联。使用此数据库的应用程序需要具有搜索功能,该功能将打印出符合特定条件的多行,包括连接表中的所有值。来自连接表的值也需要是能够搜索与该值匹配的所有其他行的链接。我想弄清楚如何在不征税的情况下做到这一点。SQL Server多对多连接查询

这里是表结构的一个例子

**Metrics (Main Table)** 
MetricID (pk) 
Metric 

**Domains (ValueList Table)** 
DomainID (pk) 
Domain 

**MetricsDomains (Join Table)** 
MetricsDomainsID (pk) 
MetricID (fk) 
DomainID (fk) 

**MetricTypes (ValueList Table)** 
MetricTypeID (pk) 
MetricType 

**MetricsMetricTypes (Join Table)** 
MetricMetricTypesID (pk) 
MetricID (fk) 
MetricTypeID (fk) 

**Studies (ValueList Table)** 
StudyID (pk) 
Study 

**MetricsStudies (Join Table)** 
MetricsStudiesID (pk) 
MetricID (fk) 
StudyID (fk) 

当有人通过各种标准的公制搜索,他们应该得到以表格的形式输出,看起来是这样的:

Metric1 | Description | Study1, Study2, Study3 | MetricType1, MetricType2 | Domain1, Domain2 
Metric2 | Description | Study5, Study2, Study4 | MetricType2, MetricType3 | Domain5, Domain9 

的度量标准将成为对度量标准完整描述的链接。然而,此外,研究(即研究1,研究2,研究3等)和MetricTypes(MetricType1,Metric2等)和域(Domain1,Domain 2等)也应该是链接,即当点击时,将对包含该研究,类型或域的所有其他指标执行新的搜索。这使我相信,除了文本之外,为了放置在href中,我还需要研究,类型或域的主键。

无论如何,考虑到一次搜索可能会返回20多个度量标准,我需要弄清楚的是编写优化查询以返回多个多对多连接的结果的好方法。我知道在一个查询中加入所有这些表格通常会产生所有联接的笛卡尔积,但我不确定是否有另一种方式去处理它。我也读到一种方法,我可以用这样的方法在外地返回的许多一对多结果作为逗号分隔的列表:

SELECT m.MetricID, Description, 
    STUFF((
    SELECT ', ' + s.Study 
    FROM Studies s, Metrics_Studies ms 
    WHERE s.StudyID = ms.StudyID AND ms.MetricID = m.MetricID 
    ORDER BY s.Study 
    FOR XML PATH('') 
    ),1,1,'') as Study, 
FROM Metrics m 
WHERE Metric_PK = 13 

但是,我不知道的对性能的影响这种方法,还是它会真正让我找到我想要的,因为我认为我可能还需要研究的主键。

任何帮助,将不胜感激。

谢谢!

+0

MetricsMetricTypes中的最后一个字段应该是MetricTypeID而不是DomainID吗? – 2010-10-11 14:20:54

+1

在你的joing表(即MetricsDomains)中,你是否真的需要一个单独的PK(MetricsDomainsID),​​还是可以将它组合成两个FK? (MetricID,DomainID)。这意味着你只能有一种组合,但是无论如何,这种感觉都是正确的。 – 2010-10-11 14:27:48

+0

@Mark你说得对。我已经修复了原来的问题。 – Kirsehn 2010-10-11 18:13:22

回答

1

我建议先用你的多连接做它 - 只有这样你才能知道perforrmance是否足够好。一如既往,你必须小心过早的优化。一旦你的查询对你的规范化模型正确运行,你可以检查查询计划等。这可能会强调你需要扁平化你的一些连接,如果这种情况你可能需要将数据存储在两个不同的格式,一个用于报告/一个用于搜索等等。但是,第一件事是看看性能是否真的可以接受。希望有帮助。

+1

谢谢保罗。到目前为止,因为我需要继续使用这个应用程序,所以我一直在使用上面发布的子查询方法的一个变体(尽管我为了节省一些数据库处理而删除了STUFF()函数,因为我可以消除领先逗号通过应用程序内的后处理)。这是你的建议吗?到目前为止,查询处理时间还没有达到百分之一秒,所以我不认为这会是一个问题。我只是想知道是否有一个更清洁/更好的方式去实现它。 – Kirsehn 2010-10-11 19:33:21

+0

@Kirsen:是的,就是这样 - 得到一些干净的东西(你明白)。就像你说的那样,这可以让你继续申请。只有如果你需要的话,如果需要的话,重新访问以提高性能。在您开发应用程序时,其他情况可能会触发数据模型的更改,否则您可能会优化所做的任何优化,或者提供更简单的优化代码的方式。 – 2010-10-11 19:40:33