我有一个用于跟踪零件的小型数据库。为了这个例子,表格如下所示:
PartID (PK),int
PartNumber ,Varchar(50),唯一
说明,Varchar(255)
我需要定义某些部分被分类为彼此相似。 为此,我设置了第二个表,如下所示:
PartID ,(PK),int
SecondPartID ,(PK),int
ReasonForSimilarity ,Varchar(255)
然后在两个表之间建立了多对多关系。
问题来自于我需要报告被认为相似的部分,因为这种关系是双向的。如果 XYZ123 部分类似于 ABC678 ,那么 ABC678 被认为与 XYZ123 类似。因此,如果我想列出与给定部分类似的所有部分,我需要确保在两个方向上设置关系(这是错误的,因为数据是重复的)或者需要有2个查询在两个方向上查看表。这些解决方案都不适合我。
那么,如何解决这个问题呢?这可以单独用SQL解决,还是我的设计需要改变以适应业务需求?
考虑以下部分:XYZ123,ABC123,ABC234,ABC345,ABC456& EFG456已进入上面输入的现有结构。您最终可能会看到这样的数据(省略此时无关的原因字段):
PartID , SecondPartID
XYZ123,ABC123
XYZ123,ABC234
XYZ123,ABC345
XYZ123,ABC456
EFG456,XYZ123
我的用户想知道“哪些部分与XYZ123类似”。这可以使用如下查询来完成:
SELECT SecondPartID
FROM tblRelatedParts
WHERE PartID = 'XYZ123'
这个问题是它不会挑选出与XYZ123相关的部分EFG456,尽管这些部件已经反过来了。根据用户当前正在使用哪个部分以及部件之间的关系总是是双向的,这是可行的。
我遇到的问题是,我现在需要检查当用户在两个部分之间建立关系时,它是否已经存在于另一个方向。
@Goran
我已经使用您的建议进行了一些初步测试,这就是我计划使用您的建议来解决问题的方法。
将上面列出的数据输入到新表中(请注意,我已将partID更改为部件号以使示例更清晰;但我的问题的语义没有改变)
表格如下所示:
RelationshipID , PartNumber
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')
我会进行更多测试,如果有效,我会反馈并接受答案。
答案 0 :(得分:7)
我通过设置关系表来处理这个问题。
部分表:
PartID (PK),int
PartNumber ,Varchar(50),唯一
说明,Varchar(255)
PartRelationship表:
RelationshipId (FK),int
PartID (FK),int
关系表:
RelationshipId (PK),int
现在类似的部分只是添加到关系表:
RelationshipId,PartId
1,1
1,2
每当你添加另一个具有relationshipId = 1的部分时,它被认为类似于具有relationshipId = 1的任何部分。
用于添加关系的可能的API解决方案:
答案 1 :(得分:2)
添加CHECK
约束,例如
CHECK (PartID < SecondPartID);
答案 2 :(得分:0)
我知道这是旧的,但为什么不用原始架构进行此查询?减少表格和行数。
SELECT SecondPartID
FROM tblRelatedParts
WHERE PartID = 'XYZ123'
UNION
SELECT PartID
FROM tblRelatedParts
WHERE SecondPartID = 'XYZ123'
我正在处理类似的问题并查看这两种方法,并想知道为什么你认为关系表的架构更好。从某种意义上说,原始问题仍然存在,你仍然需要从两个方向管理它们之间的关系。
答案 3 :(得分:0)
每个相似度有两行怎么样?例如,如果对象A,B与关系表中的对象相似
A B
B A
我知道你会将你的关系数据加倍,但它们是整数,所以它不会过度杀死你的数据库。相反,你有一些收获: