【问题标题】:Association between two entries in SQL tableSQL表中两个条目之间的关联
【发布时间】:2010-10-14 09:40:25
【问题描述】:

假设您有一个存储人员列表的数据库表。您想在人与人之间建立关系,即我与人 J 是朋友。

我想在这种情况下,需要第二张表来存储人们的关联。此表将包含两个字段(person1、person2),每个条目对应于两个人之间的一对一关系。

这是对的还是有更聪明的方法呢?这种方法使关联表像 n_users^2 一样缩放。

【问题讨论】:

    标签: sql database database-design


    【解决方案1】:

    1。对于一对一的关系:

    例如表 UserInfo(用于用户的个人信息)和表 UserCredential(用于用户的登录信息)。这是为了减少一条记录的大小而进行的表拆分。

    为每个表指定相同的主键,并创建一个从一个(辅助表)到另一个(主表)的外键:

    UserInfo(#UserID);
    UserCredential(#UserID)
        FOREIGN KEY (UserID) REFERENCES UserInfo(UserID);
    

    前缀为“#”的列是表的主键。

    2。对于多对一关系:

    例如表员工和表部门。每个员工只属于一个部门,但一个部门可能有零到多个员工。

    将Department表的主键列添加到Employee表中,并创建一个从Emp到Dep的外键:

    Department(#DepartmentID);
    Employee(#EmployeeID, DepartmentID)
        FOREIGN KEY (DepartmentID) REFERENCES Department(DepartmentID);
    

    如果你经常需要查询Employee.DepartmentID列,可以在上面创建索引:

    CREATE INDEX IX_Employee_DepartmentID ON Employee(DepartmentID);
    

    3。对于多对多关系:

    例如表用户和自身。一个用户可以和另一个用户成为朋友,并且友谊是双向的(A是B的朋友,所以B也是A的朋友)。并且一个用户可以跟随另一个用户,但是跟随是单向的(A跟随B但B可能不会同时跟随A)。在图论中,友谊是一个无向图,跟随是一个有向图。

    需要一个单独的表来表示多对多关系:

    User(#UserID);
    Friendship(#LeftUserID, #RightUserID)
        FOREIGN KEY (LeftUserID) REFERENCES User(UserID)
        FOREIGN KEY (RightUserID) REFERENCES User(UserID)
        CHECK (LeftUserID < RightUserID);
    Following(#LeftUserID, #RightUserID)
        FOREIGN KEY (LeftUserID) REFERENCES User(UserID)
        FOREIGN KEY (RightUserID) REFERENCES User(UserID)
        CHECK (LeftUserID <> RightUserID);
    

    Friendship 和Following 表都使用组合主键(具有两列或更多列)。

    友谊表中的检查约束禁止记录如下:

    • (A,A):不应该是自己的朋友。
    • (B,A):对于A和B之间的友谊,记录(A,B)就足够了。这是DRY原则的一个例子。

    表Following中的检查约束只禁止像(A,A)这样的记录。 (A,B) 表示 A 在 B 之后, (B,A) 表示 B 在 A 之后,这两个记录的含义不同,因此它们都是必要的。

    您可以创建额外的索引来优化第二列的查询(假设 PK 是聚集索引):

    CREATE UNIQUE INDEX IX_Friendship_Right_Left
        ON Friendship(RightUserID, LeftUserID);
    CREATE UNIQUE INDEX IX_Following_Right_Left
        ON Following(RightUserID, LeftUserID);
    

    【讨论】:

    • 嗨。在您的第一个多对多代码中,您说...“CHECK (LeftUserID RightUserID);”。第一个是“”可以吗?
    【解决方案2】:

    是的,如果您想为多对多关系建模,这是正确的。那就是所有人都可以有很多朋友。

    如果你有一个一对多的关系,就像所有人都有一个老板(或没有老板)你不需要额外的表,那么你只需要在 person 表中的 BossId 列。

    【讨论】:

      【解决方案3】:

      您可能还想确定关系的类型。在这种情况下,您最好使用 2 个表,RelationshipTypes 和Relationships。唯一键可以在所有 3 个关系字段上。

      Relationships
        PersonId
        RelatedPersonId
        RelationshipTypeId
      
      RelationsShipTypes
        Id
        Name
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-30
        • 1970-01-01
        • 2020-07-30
        • 2021-12-14
        • 2014-01-08
        • 2018-10-04
        • 1970-01-01
        相关资源
        最近更新 更多