Database 数据库:项目可以有备选方案,如何在数据库中链接?

Database 数据库:项目可以有备选方案,如何在数据库中链接?,database,database-design,Database,Database Design,我有一个数据库,我想存储多个项目,每个项目将是唯一的,但他们可以从其他制造商的替代品。因此,项目之间可能存在M:M关系 例如,项目A可以有3个备选方案。如果我添加了项目B,那么替代项目的链接也应该颠倒,这样当我搜索项目B时,我会找到项目A作为替代项目。当我添加C项时,它应该被添加为A项和B项的备选方案,C项应该具有A项和B项的备选方案 如何在同类类之间建立这种关系的最佳/最聪明的方法是什么 我的想法是,在两个被调用的可选项之间创建一个表,每个新项都有一个唯一的ID,如果添加了一个可选项,那么它将

我有一个数据库,我想存储多个项目,每个项目将是唯一的,但他们可以从其他制造商的替代品。因此,项目之间可能存在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?
}
公共部分类项:实体
{
公共项目()
{
Id=GuidComb.GenerateComb();
}
公共Guid Id{get;set;}
公共字符串ItemName{get;set;}
公共字符串MakerRef{get;set;}
公共字符串说明{get;set;}
公共虚拟生成器{get;set;}
公共虚拟IList提供{get;set;}
//就这样被困在这里,用一种聪明的方式与自己建立关系?
}
欢迎任何建议!
提前谢谢

我正在考虑的建议可能与您的建议类似,但我将尝试用数据库术语来表述它

据我所知,您的需求,您的替代关系将是完全可传递的。这意味着您的项目集在包含相互替换的项目的子集的等价类中进行分区。(如果项目还没有备选方案,则子集仅由该项目组成。)

如果这是真的,那么表示这一点的最优雅和无冗余的方式就是选择一个项目,例如子集,作为整个子集的代表。下表设计反映了这一点:

item(id, equivalence_id, other attributes, ...)
其中,
equivalence\u id
是代表的外键。每个项都会生成一个空的等价id。如果它与另一个项目等效

  • 如果已经存在的项目的等效id为null,则将该代表的id分配给两个项目的等效id

  • 如果已经存在的项具有非空的等价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
如果应存储与整个等价类相关的某些信息,则应仅为等价类创建一个单独的表