SQL表中两个条目之间的关联

Posted

技术标签:

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

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

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

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

【问题讨论】:

【参考方案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

【讨论】:

以上是关于SQL表中两个条目之间的关联的主要内容,如果未能解决你的问题,请参考以下文章

SQL:选择另一个表中没有复合主键的条目

Sequelize - 如何从一个表中获取未被另一表关联的条目

将 SQL 表中的值与文本框中的条目进行比较

SQL 从表中选择条目,其中属性等于参数,否则选择 * 条目

SQL:从最近的子表条目中选择列

在多对多连接表中,如何计算两个“所有者”共享的条目数?