假设我有一个名为USER的实体,并且两个USER之间存在关系FRIENDSHIP 因此,我有一个表'USER'和一个关系表'FRIENDSHIP'
USER id firstName LastName 1 taher chhabrawala 2 john Dsouza 3 rahul singh 4 deepak patel
Friendship id id 1 2 1 3 1 4 4 1 4 3
在上表中,我存储了两次相同的信息,即“taher是deepak的朋友,而deepak是taher的朋友”
有没有办法减少这种冗余?
答案 0 :(得分:8)
嗯,你当然可以假设所有友谊都是对称的并且只存储一次友谊,但这意味着当你想要查询所有Taher的朋友时,你必须在任一列中寻找他的ID。 / p>
或者,您可以拥有一个单独的关系ID表,然后是一个与用户关系的一对多表。这样做的好处是,如果有一天你想要它,它将允许多人关系,并允许你添加关于关系的元数据(当它开始时,谁建议它,无论如何)。
User
Id Name
1 Taher
2 Deepak
Relationship
Id StartDate
1 2010-08-23
UserRelationship
RelationshipId UserId
1 1
1 2
另一方面,在Facebook上,例如,我可以“交朋友”,他们可以决定不与我交朋友。如果你没有现在正在使用的“冗余”方法,你将如何表现这种尚未互惠的友谊?
答案 1 :(得分:3)
制定一个规则,例如“第一个ID值始终低于第二个ID值”,这样就可以确保没有重复项。
在这种情况下,对(4,1)无效,对(4,3)将存储为(3,4)。
答案 2 :(得分:1)
显而易见的解决方案是每对朋友只存储1条记录。但是,保持独特性变得更加困难;与“冗余”解决方案相比,获取/更新/删除朋友关系的所有查询都变得更加复杂。此外,具有2条记录的解决方案允许您维护朋友请求(例如,UserA要求UserB成为朋友.UserB可以确认或拒绝此请求)。所以我认为在这种情况下冗余是完全有效的。
答案 3 :(得分:0)
如果您决定使用对称设计,那么确保每个友谊始终是双向的可能是有用的。你可以试试这个:
CREATE TABLE Friendship
(UserId1 INT NOT NULL REFERENCES Users (UserId),
UserId2 INT NOT NULL,
PRIMARY KEY (UserId1, UserId2),
FOREIGN KEY (UserId2, UserId1) REFERENCES Friendship (UserId1, UserId2));
INSERT INTO Friendship (UserId1, UserId2)
VALUES (1,2),(2,1);
答案 4 :(得分:0)
如果存储这两行,则需要强制执行完整性规则,以确保友谊始终成对出现。
只在表格中存储一行(例如,FR),并创建一个SYMFR视图
SELECT x,y FROM FR 联盟 选择x为y,y为x FROM FR