想象一下,您有一个存储人员列表的数据库表。你想在人与人之间建立一种关系,即我与人J的朋友。
我想在这种情况下,需要第二个表来存储人员关联。该表包含两个字段(person1,person2),每个条目对应两个人之间的一对一关系。
这是对的还是有更聪明的方法呢?此方法使关联表像n_users ^ 2一样缩放。
答案 0 :(得分:7)
e.g。表UserInfo(用于用户的个人信息)和表UserCredential(用于用户的登录信息)。这是表分割,以减少一条记录的大小。
为每个表指定相同的主键,并从一个(辅助表)到另一个(主表)创建外键:
UserInfo(#UserID);
UserCredential(#UserID)
FOREIGN KEY (UserID) REFERENCES UserInfo(UserID);
带有前缀“#”的列是表的主键。
e.g。表员工和表部门。每个员工只属于一个部门,但部门可能有零到多个员工。
将表Department的主键列添加到Employee表中,并从Emp到Dep创建一个FK:
Department(#DepartmentID);
Employee(#EmployeeID, DepartmentID)
FOREIGN KEY (DepartmentID) REFERENCES Department(DepartmentID);
如果您经常需要使用Employee.DepartmentID列进行查询,则可以在其上创建索引:
CREATE INDEX IX_Employee_DepartmentID ON Employee(DepartmentID);
e.g。表用户和自己。用户可以与另一个用户成为朋友,友谊是双向的(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都使用组合主键(有两列或更多列)。
表Friendship中的check-constraint禁止记录,如:
表格中的check-constraint仅限于禁止(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);
答案 1 :(得分:5)
是的,如果您想建立多对多关系,这是正确的。这就是所有人都可以有很多朋友。
如果你有一对多的关系,就像所有人都有一个老板(或没有老板)你不需要额外的表,那么你只需要在人员表中有一个BossId列。
答案 2 :(得分:0)
您可能还想建立关联类型。在这种情况下,您最好使用2个表,RelationshipTypes和Relationships。唯一键可以在所有3个关系字段中。
Relationships
PersonId
RelatedPersonId
RelationshipTypeId
RelationsShipTypes
Id
Name