如何构建“友谊”

时间:2014-08-03 13:59:29

标签: ms-access

我完全是新手。请不要介意拼写错误或术语错误。我会尽力解释一下。

我有一个“人员”表,包括具有唯一ID的人。我们假设有person1,person2,person3和person4。

我想创建一个结构,其中每个人都可以成为彼此的朋友。

例如,person1的朋友是person3和person4。这个条件应该同时使person3的朋友,person1。

我不确定如何将这样的表关联起来,或者我如何在表中设置关系以便给我这样做。

任何想法都表示赞赏。

1 个答案:

答案 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次操作,Friend1Friend2不重要:

    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条记录,则会在查询中获得重复结果。

  • 查询可能变得非常复杂,因为您始终必须考虑所查找的数据可能位于任一列中:每个查询必须具有某种对称性。