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表中两个条目之间的关联的主要内容,如果未能解决你的问题,请参考以下文章
Sequelize - 如何从一个表中获取未被另一表关联的条目