我完全是新手。请不要介意拼写错误或术语错误。我会尽力解释一下。
我有一个“人员”表,包括具有唯一ID的人。我们假设有person1,person2,person3和person4。
我想创建一个结构,其中每个人都可以成为彼此的朋友。
例如,person1的朋友是person3和person4。这个条件应该同时使person3的朋友,person1。
我不确定如何将这样的表关联起来,或者我如何在表中设置关系以便给我这样做。
任何想法都表示赞赏。
答案 0 :(得分:1)
正如其他人所说,代表这些类型的对称关系并不是传统关系数据库的优势。
友谊关系只能使用一个简单的表来表示,但是你如何操纵数据会变得有点复杂。
你基本上有两种方式:
Friend table
PK Field 1 Field 2
--------------------------------
ID PersonID FriendWithPersonID
有了这个,如果Person Alice(Person.ID = 123
)是Bob的朋友(Person.ID = 456
),你需要输入2条记录:
Friend table
ID PersonID FriendWithPersonID
--------------------------------
1 123 456
2 456 123
维护此数据可能很困难:对于每个操作(添加,删除),您需要更改两个记录以确保它们保持同步。
添加友谊需要2个操作:
INSERT INTO Friend (PersonID, FriendWithPersonID) VALUES (123,456);
INSERT INTO Friend (PersonID, FriendWithPersonID) VALUES (456,123);
删除友谊可以在一个中完成:
DELETE FROM Friend
WHERE (PersonID=123 AND FriendWithPersonID=456)
OR (PersonID=456 AND FriendWithPersonID=123)
要更新关系,最简单的方法是将其删除并重新插入新关系。
现在,您可以轻松完成任何查询:
爱丽丝的朋友数量:
SELECT Count(*) WHERE PersonID=123
Bob所有朋友的名单:
SELECT People.*
FROM People
INNER JOIN Friend
ON Friend.FriendWithPersonID = People.ID
WHERE Friend.PersonID = 456
Alice和Bob有共同之处的朋友(我报告了ID,只是为了让查询更清晰):
SELECT FriendWithPersonID
FROM Friend
WHERE PersonID=123
AND FriendWithPersonID IN (SELECT FriendWithPersonID
FROM Friend
WHERE PersonID=456)
虽然这个系统并不完美:
实现友谊的另一种方式是用一条记录来描述每个友谊。
Friend table
PK Field 1 Field 2
--------------------------------
ID Person1ID Person2ID
有了这个,如果Person Alice(Person.ID = 123
)与Bob(Person.ID = 456
)成为朋友,则需要输入1条记录:
Friend table
ID PersonID Person2ID
--------------------------------
1 123 456
维持这种关系会带来另一个问题:我们不知道每个人的关系在哪一方。
创建和删除记录非常简单:
添加友谊需要1次操作,Friend1
或Friend2
不重要:
INSERT INTO Friend (Friend1ID, Friend2ID) VALUES (123,456);
删除友谊也相当容易,类似于我们之前的情况,因为我们需要测试删除单一友情记录的两种可能性:
DELETE FROM Friend
WHERE (Person1ID=123 AND Person2ID=456)
OR (Person1ID=456 AND Person2ID=123)
现在,在大多数情况下,我们必须使用UNION
语句重建对称性,以便我们可以在同一列中显示所有数据:
爱丽丝的朋友数量:
SELECT Count(*) WHERE Person1ID=123 or Person2=123
Bob所有朋友的名单:
SELECT People.*
FROM People
INNER JOIN (SELECT Person2ID AS FriendOfPersonID
FROM Friend
WHERE Person1ID=456
UNION ALL
SELECT Person1ID AS FriendOfPersonID
FROM Friend
WHERE Person2ID=456) AS F
ON F.FriendOfPersonID = People.ID
我将最后一个查询留作练习,您基本上也必须使用UNION
语句。
使用该系统,您可以将表格中的信息保持在最低限度,但还有其他权衡因素:
在添加新关系之前,请检查是否存在'已经是系统中的反向。如果您为同一关系添加2条记录,则会在查询中获得重复结果。
查询可能变得非常复杂,因为您始终必须考虑所查找的数据可能位于任一列中:每个查询必须具有某种对称性。