我已经实现了以下存储关系拓扑的方法:
1,总连接关系表

大多数SQL引擎通常无法在哪个连接上执行连接。
2.特定于关系的联结表

可以针对哪个连接执行连接。
3.在两个双向对象的text字段中存储相关对象的列表/字符串映射。

为了启用sql引擎的联接,有可能编写一个自定义模块,如果student_keys的内容只是[1,3],即与显式Student类型的关系,则该模块将变得更加容易。
在以下情况下的问题如下:
我看不到联结表的要点。例如,我看不到连接表声称缓解的以下参数确实存在任何问题:

  • 无法在逻辑上正确保存双向关系(例如
    没有双向关系中的数据孤立或任何
    keys字段的关系,因为一个递归保存并且一个可以强制执行
    其他操作(删除,更新)相当容易)
  • 无法有效加入

  • 我不是在征求您对最佳实践的个人意见,也不是在规范化方面发表任何类似邪教的言论。
    明确的问题如下:
  • 在哪些情况下需要查询通过查询拥有对象的keys字段未提供的联结表?
  • 在首选联结表的sql引擎提供的计算上下文中,什么是逻辑实现问题?
  • 关于junction tablekeys字段的唯一实现差异如下:

  • 搜索以下性质的查询时,您需要使用自定义索引实现或其他一些合理的实现来与keys字段进行匹配:

    与搜索联结表的索引列然后选择适当的类相反。
    我一直无法找到答案,为什么出于某种原因,联结表在逻辑上更可取。 我并不是在说这种情况,或者我以一种或另一种方式有宗教偏爱,这一点可以证明,我通过多种方式实现了这一目标。 我的问题是我不知道它们是什么。

    最佳答案

    我的看法是,您有多个实体

    CREATE TABLE StudentType
    (
        Id Int PRIMARY KEY,
        Name NVarChar(50)
    );
    
    INSERT StudentType VALUES
    (
        (1, 'Basic'),
        (2, 'Advanced'),
        (3, 'SomeOtherCategory')
    );
    
    CREATE TABLE Student
    (
        Id Int PRIMARY KEY,
        Name NVarChar(200),
        OtherAttributeCommonToAllStudents Int,
        Type Int,
        CONSTRAINT FK_Student_StudentType
            FOREIGN KEY (Type) REFERENCES StudentType(Id)
    )
    
    CREATE TABLE StudentAdvanced
    (
        Id Int PRIMARY KEY,
        AdvancedOnlyAttribute Int,
        CONSTRIANT FK_StudentAdvanced_Student
            FOREIGN KEY (Id) REFERENCES Student(Id)
    )
    
    CREATE TABLE StudentSomeOtherCategory
    (
        Id Int PRIMARY KEY,
        SomeOtherCategoryOnlyAttribute Int,
        CONSTRIANT FK_StudentSomeOtherCategory_Student
            FOREIGN KEY (Id) REFERENCES Student(Id)
    )
    
  • 所有学生共有的任何属性在Student表上都有列。
  • 将具有额外属性的学生类型添加到StudentType表中。
  • 每个额外的学生类型都有一个Student<TypeName>表来存储其特定属性。这些表与Student具有可选的一对一关系。

  • 我认为您的“稻草人”联结表是EAV反模式的部分实现,只有在您不知道需要建模哪些属性的情况下才有意义,即您的数据将完全是非结构化的。当这是真正的要求时,关系数据库开始显得不太理想。在那些情况下,请考虑使用NOSQL/Document数据库替代方案。

    联结表在以下情况下很有用。

    假设我们向模型添加了一个Class实体。
    CREATE TABLE Class
    (
        Id Int PRIMARY KEY,
        ...
    )
    

    我们想在学生和类(class)之间存储多对多关系,这是可以想象的。
    CREATE TABLE Registration
    (
        Id Int PRIMARY KEY,
        StudentId Int,
        ClassId Int,
        CONSTRAINT FK_Registration_Student
            FOREIGN KEY (StudentId) REFERENCES Student(Id),
        CONSTRAINT FK_Registration_Class
            FOREIGN KEY (ClassId) REFERENCES Class(Id)
    )
    

    该实体将是存储与学生注册类(class)特别相关的属性的正确位置,例如,可能是完成标志。其他数据自然会与此交汇处相关,也许是类(class)特定的出勤记录或成绩历史记录。

    如果您不以此方式关联ClassStudent,您将如何选择类(class)中的所有学生以及学生阅读的所有类(class)。在性能方面,可以通过键列上的索引轻松优化此操作。

    当存在不带任何属性的多对多房地产时,我从逻辑上同意,联结表不必存在。但是,在关系数据库中,联结表仍然是有用的物理方法,也许像这样,
    CREATE TABLE StudentClass
    (
        StudentId Int,
        ClassId Int,
        CONSTRAINT PK_StudentClass PRIMARY KEY (ClassId, StudentId),
        CONSTRAINT FK_Registration_Student
            FOREIGN KEY (StudentId) REFERENCES Student(Id),
        CONSTRAINT FK_Registration_Class
            FOREIGN KEY (ClassId) REFERENCES Class(Id)
    )
    

    这允许简单的查询,例如
    // students in a class?
    SELECT StudentId
    FROM StudentClass
    WHERE ClassId = @classId
    
    // classes read by a student?
    SELECT ClassId
    FROM StudentClass
    WHERE StudentId = @studentId
    

    另外,这提供了一种简单的方法来部分或完全从任一方面管理关系,这对于关系数据库开发人员来说是熟悉的,并且可以由查询优化器查询。

    09-25 20:56