代码之家  ›  专栏  ›  技术社区  ›  Poni

“友谊”数据库中的唯一对

  •  6
  • Poni  · 技术社区  · 14 年前

    我要发布这个问题,这是我的另一个问题的总结。 question .

    我有 两数据库 :
    1)数据库用户。
    2)

    我强调它们是储存在 单独的数据库 在不同的服务器上,因此不能使用外键。

    在“db_friends”中,我有表“tbl_friends”,其中包含以下列:
    - IDL用户
    -朋友

    现在 我如何确保每双都是独一无二的 在这张桌子上(“tbl_friends”)?
    我想在表级别强制执行,而不是通过查询。

    例如 这些是无效的行 :
    1—2
    2—1

    我希望这是不可能补充的。

    另外-我将如何为713用户的所有朋友搜索 虽然他可以被提及 在一些友谊的争吵中, 在第二列 (‘IDJ朋友’)?

    4 回复  |  直到 14 年前
        1
  •  6
  •   Rick O    14 年前

    您可能无法在数据库级别执行此操作——您的应用程序代码必须执行此操作。如果您确保您的tbl_朋友记录始终与(lowid,highid)一致,那么典型的pk/唯一索引将解决重复问题。事实上,为了加强这一点,我将把你的tbl_朋友中的列重命名为(i d_low,i d_high)。

    你对用户713的查询会是

    SELECT id_low AS friend FROM tbl_friends WHERE (id_high = ?)
    UNION ALL
    SELECT id_high AS friend FROM tbl_friends WHERE (id_low = ?)
    

    为了提高效率,您可能需要向前和向后索引它——这是由(id_user,id_friend)和(id_friend,id_user)进行的。

    如果你 必须 在DB级别执行此操作,然后在插入之前将参数交换为(低、高)的存储过程将起作用。

        2
  •  3
  •   OMG Ponies    14 年前

    您必须使用触发器来强制执行该业务规则。
    使两列 tbl_friends 主键(唯一约束失败)只能确保同一集合不能有重复项:1、2只能出现一次,但2、1有效。

    在第二列(“id_friend”)的友谊行中,当提到713用户的所有朋友时,我该如何称呼他?

    你可以用一个 IN :

    WHERE 713 IN (id_user, id_friend)
    

    …或工会:

    JOIN (SELECT id_user AS user
            FROM TBL_FRIENDS
          UNION ALL
          SELECT id_friend
            FROM TBL_FRIENDS) x ON x.user = u.user
    
        3
  •  1
  •   easel    14 年前

    好吧,这对列上的一个唯一约束将使您到达一半。我认为最简单的方法是添加一个约束以确保ID_用户<ID_朋友不会得到反向版本。您将需要在插入时补偿这个顺序,但它将使您获得所需的数据库级约束,而不需要复制数据或依赖外键。

    对于第二个问题,要查找id=1的所有朋友,可以选择id_user、id_friend from tbl_friend,其中id_user=1或id_friend=1,然后在客户端代码中抛出所有1,而不考虑列。

        4
  •  0
  •   Bill Karwin    14 年前

    一种方法是将两个朋友存储在两行中:

    CREATE TABLE FriendPairs (
      pair_id INT NOT NULL,
      friend_id INT NOT NULL,
      PRIMARY KEY (pair_id, friend_id)
    );
    
    INSERT INTO FriendPairs (pair_id, friend_id)
    VALUES (1234, 317), (1234, 713);
    

    看到了吗?插入它们的顺序无关紧要,因为两个朋友都进入了“朋友ID”列。因此,您可以轻松地强制执行唯一性。

    您还可以轻松查询713的朋友:

    SELECT f2.friend_id
    FROM FriendPairs AS f1
    JOIN FriendPairs AS f2 ON (f1.pair_id = f2.pair_id)
    WHERE f1.friend_id = 713