2011-10-07 118 views
7

我有一個用於跟蹤零件的小型數據庫。對於這個例子起見,表看起來像這樣:SQL查詢中的雙向關係

PARTID(PK),整數
PARTNUMBER,VARCHAR(50),唯一
說明,VARCHAR(255)

我有一個要求,定義某些部分被分類爲彼此相似。 要做到這一點,我已經設置看起來像這樣第二個表:

PARTID,(PK),詮釋
SecondPartID,(PK),詮釋
ReasonForSimilarity,VARCHAR(255)

然後在兩個表格之間建立了多對多的關係。

問題來了,當我需要報告被認爲是相似的部分,因爲這種關係是雙向的I.E.如果部分XYZ123類似於ABC678然後ABC678被認爲類似於XYZ123。因此,如果我想列出與給定部分相似的所有部分,我需要確保雙向設置關係(這是因爲數據是重複的,這很糟糕),或者需要有兩個查詢在兩個方向上查看錶。這些解決方案都不適合我。

那麼,應該如何處理這個問題呢?這可以單獨使用SQL來解決,還是我的設計需要更改以適應業務需求?

考慮以下部件XYZ123,ABC123,ABC234,ABC345,ABC456 & EFG456已被輸入到上面輸入的現有結構中。你可能最終與看起來像這樣的數據(省略原因字段這是無關緊要的,在這一點上):

PARTIDSecondPartID
XYZ123,ABC123
XYZ123,ABC234
XYZ123,ABC345
XYZ123,ABC456
EFG456,XYZ123

我的用戶想知道「哪部分與XYZ123」。這可以使用查詢,像這樣做:

SELECT SecondPartID 
FROM tblRelatedParts 
WHERE PartID = 'XYZ123' 

與這雖然問題是,它不會挑選出一部分EFG456儘管該部分已經進入了另一種方式圓事實上這是關係到XYZ123。根據用戶當前正在使用哪個部分以及部件之間的關係總是是雙向的,這是可行的。

雖然我有這個問題,但我現在需要檢查,當用戶建立兩個部分之間的關​​系時,它不會在另一個方向存在。

@Goran

我已經做了使用你的建議,一些初步的測試,這是我打算使用自己的建議來解決這個問題。

上面列出的數據被輸入到新表(請注意,我已經改變了PARTID部件號,以讓這個例子更清楚,我的問題的語義並沒有改變,雖然)

表看起來像這樣:

RelationshipIDPARTNUMBER
1,XYZ123
1,ABC123
2,XYZ123
2,ABC234
3,XYZ123
3,ABC345
4,XYZ123
4,ABC456
5,EFG456
5,XYZ123

我可以然後檢索使用類似的部件的列表這樣的查詢:

SELECT PartNumber 
FROM tblPartRelationships 
WHERE RelationshipID ANY (SELECT RelationshipID 
          FROM tblPartRelationships 
          WHERE PartNumber = 'XYZ123') 

我會進行一些測試,如果這個工程我會反饋和接受的答案。

回答

7

我已經通過建立關係表處理了這個問題。

部分表:

PARTID(PK),整數

PARTNUMBER,VARCHAR(50),唯一

說明,VARCHAR(255)

PartRelationship表:

RelationshipId(FK),詮釋

PARTID(FK),詮釋

關係表:

RelationshipId(PK),詮釋

現在類似的部件添加簡單地得到到關係表:

RelationshipId,PartId

1,1

1,2

無論何時您relationshipId添加另一部分= 1它被認爲是類似於relationshipId任何部分= 1

添加關係

可能API的解決方案:

  • 爲每個類似零件清單建立新的關係。讓客戶端隨時加載,更改和更新整個列表。
  • 檢索類似對象的關係。按照一些標準過濾列表,以便只保留一個或讓客戶從現有關係中進行選擇。根據需要創建,刪除PartRelationship記錄。
  • 從關係表中檢索關係列表。讓客戶指定零件和關係。根據需要創建,刪除PartRelationship記錄。
+0

+1,儘管您可能想要添加一個額外的表來迎合'ReasonForSimilarity'字段,該字段很可能僅限於特定對(而不適用於關係中的所有部分)。 –

+0

@MarkBannister好點。我不確定所有的要求是什麼,但是這應該讓OP指向正確的方向。如果有任何需要,我會更新我的答案。 @Benjamin? – Goran

+0

+ 1,這看起來像一個有效的解決方案。我會做一些測試,並讓你知道這是怎麼回事。關於Id關係只是一件事;這是如何生成和維護的?大概我需要確保在建立部件之間的鏈接時使用正確的關係以確保其正常工作。 @MarkBannister我已經爲ReasonForSimilarity創建了一個單獨的表格,但是它不會影響我想要的內容。 –

2

添加CHECK約束,例如,

CHECK (PartID < SecondPartID); 
0

我知道這是舊的,但爲什麼不只是用你的原始模式做這個查詢?較少的表格和行。

SELECT SecondPartID 
FROM tblRelatedParts 
WHERE PartID = 'XYZ123' 
UNION 
SELECT PartID 
FROM tblRelatedParts 
WHERE SecondPartID = 'XYZ123' 

我正在處理類似的問題,看着這兩種方法,並想知道爲什麼你認爲與關係表的模式更好。看起來最初的問題仍然存在,因爲你仍然需要從兩個方向管理它們之間的關係。

+1

我原來的選擇有兩個表,而選定的答案只有一個。我同意第二個選項仍然存在一些問題(我仍然需要解決),但Gorans的回答是當時最好的,並且是朝着正確方向邁出的良好開端。 –

0

對於每個相似性有兩行如何。例如,如果你有對象A,B相似,你會在你的關係表

A B 
B A 

我知道你會加倍你的關係數據,但它們都是整數,所以它不會在殺你的數據庫。相反,你有一些收益:

  • 你不會使用聯合。聯盟在任何dbms中都會被殺死。特別是當你有訂單或按
  • 您可以實現更具體的關係:a與b有關,但b與a沒有關係。例如約翰可以代替戴夫,但戴夫不能代替約翰。