2010-10-11 113 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