5

テーブルに対称関係がある場合、それをエレガントに表現するにはどうすればよいでしょうか? たとえば、 というテーブルがあり、そこにはFriend2 人のユーザーのユーザー ID が含まれている必要があります。UID1このテーブルでandを使用UID2する場合、A_uid と B_uid がフレンドであるかどうかを調べたい場合は、使用する必要があります。

SELECT * FROM Friend WHERE (UID1 = A_uid AND UID2 = B_uid) OR (UID1 = B_uid AND UID2 = A_uid);

なぜならUID1、 とUID2は友情を表す点で同じだからです。このジレンマで最も重要なのは、UID1UID2が対称であることです。

これは醜いので、もっと良い方法があるかどうか知りたいと思います。

ありがとう!

4

1 に答える 1

6

私の頭の上のアイデア: UID タイプが完全な順序付けの対象である場合、次のようなことができます。

CREATE TABLE friends (
  uid1 uid REFERENCES users,
  uid2 uid REFERENCES users,
  PRIMARY KEY (uid1, uid2),
  CONSTRAINT uid1_above_uid2 CHECK(uid1 < uid2)
);

次に、クエリは下位のものを最初に配置する必要があります。しかし、それを保証するストアド プロシージャを使用して保護することができます。

CREATE FUNCTION friends_with(uid, uid) RETURNS SETOF friends AS $$
  SELECT * FROM friends WHERE uid1 = LESSER($1, $2) AND uid2 = GREATER($1, $2)
$$ LANGUAGE SQL;

もちろん、これは選択した RDBMS に変換する必要があります。

クエリは次のようになります。

SELECT * FROM friends_with(5001, 2393);
SELECT * FROM friends_with(2393, 5001);

そして、同じ結果を返します。

一方、CHECKそこに制約を置かずにプロシージャで保護することもできます。同じリレーションを誤って複数回挿入するのを防ぐのに便利だと思います。

于 2011-08-18T05:36:27.600 に答える