我有一个数据库,我想存储多个项目,每个项目都是唯一的,但他们可以有其他制造商的替代品。因此,项目之间可能存在潜在的M:M关系。
例如,项目A可以有3个替代方案。如果我添加项目B,替代项,替代项目的链接也应该颠倒,这样当我搜索项目B时,我会找到项目A作为替代。当我添加项目C时,它应作为项目A和项目B的替代项添加,而C应该具有项目A和项目B的替代项目。
如何在同类之间建立这种关系的最好/最聪明的方式?
我想的方法是在每个新项目之间使用唯一ID创建一个表格,如果添加了替代项,那么它将链接到该父项ID(替代ID)和因此,替代表中不会出现新的ID。如果稍后才确定这是替代方案,则删除其中一个的备用ID,并将该项添加到另一个备用ID。
public partial class Item : Entity
{
public Item()
{
Id = GuidComb.GenerateComb();
}
public Guid Id { get; set; }
public string ItemName { get; set; }
public string MakerRef { get; set; }
public string Description { get; set; }
public virtual Maker Maker { get; set; }
public virtual IList<Offer> Offers { get; set; }
//stuck here on the smart way to make the relationship with itself?
}
欢迎任何建议! 提前谢谢!
答案 0 :(得分:0)
我所考虑的建议可能与您提出的建议类似,但我会尝试用数据库术语来表达它。
据我了解您的要求,您的替代关系将完全传递。这意味着您的项集在包含相互替代项的子集的等价类中进行了分区。 (如果项目无法替代,则子集仅包含此项目。)
如果这是真的,那么表示这种情况的最优雅且无冗余的方式是选择诸如子集之类的项目之一作为整个子集的代表。这由以下表格设计反映出来:
item(id, equivalence_id, other attributes, ...)
其中equivalence_id
是代表的外键。每个项目的生成等价id为null。如果它等同于另一个项目,
如果已存在的项目的等效ID为null,则将此代表的ID分配给两个项目的等效项
如果已存在的项目具有非null等效ID,请将其分配给新项目的等价ID。
请注意,如果同一等价类中有多个项目,则无论使用哪个项目链接新项目,都可以使用。
示例:
id equivalence_id name
1 1 abc
2 def
3 1 ghi
4 4 jkl
5 4 mno
这意味着abc和ghi是等价的,以及jkl和mno,但def并不等同于任何东西。现在如果pqr出现并且应该等同于abc,它将得到等价id 1.效果与使其等效于ghi相同。
要查找与特定项目等效的所有项目,请查询
select *
from item
where equivalence_id = :my_equivalence_id
如果应存储与等价类有关的一些信息,则应仅创建等价类的单独表。