уникальная пара в базе данных "дружбы" - PullRequest
6 голосов
/ 30 августа 2010

Я публикую этот вопрос, который является кратким изложением моего другого вопроса .

У меня две базы данных :
1) db_users.
2) db_friends.

Подчеркну, что они хранятся в отдельных базах данных на разных серверах и поэтому не могут использоваться внешние ключи.

В 'db_friends'У меня есть таблица 'tbl_friends', которая имеет следующие столбцы:
- id_user
- id_friend

Теперь как мне убедиться, что каждая пара уникальна в этой таблице ('tbl_friends')?
Я бы хотел добавить это на уровне таблицы, а не с помощью запроса.

Например, это недопустимые строки :
1 -2
2 - 1

Я бы хотел, чтобы это было невозможно добавить.

Дополнительно - как бы я мог найти всех друзей пользователя 713 , пока он могупоминаться , в некоторых строках дружбы, во втором столбце ('id_friend')?

Ответы [ 4 ]

6 голосов
/ 30 августа 2010

Вы, вероятно, не сможете сделать это на уровне базы данных - код вашего приложения должен будет это сделать.Если вы убедитесь, что ваши записи tbl_friends всегда содержат (lowId, highId), то типичный PK / Unique Index решит проблему дублирования.На самом деле, я бы зашел так далеко, чтобы переименовать столбцы в ваших tbl_friends в (id_low, id_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).

Если вы должны сделайте это на уровне БД, тогда будет работать хранимая процедура для обмена аргументами (низкий, высокий) перед вставкой.

3 голосов
/ 30 августа 2010

Вы должны использовать триггер для принудительного применения этого бизнес-правила.
Если сделать два столбца в tbl_friends первичным ключом (уникальное ограничение не будет выполнено), то только будет гарантировать, что не может быть дубликатов одного и того же набора.: 1, 2 может появиться только один раз, но 2, 1 будет действительным.

как бы я искал всех друзей пользователя 713, в то время как его можно было бы упомянуть в некоторых строках дружбы навторой столбец ('id_friend')?

Вы можете использовать IN:

WHERE 713 IN (id_user, id_friend)

.. или UNION:

JOIN (SELECT id_user AS user
        FROM TBL_FRIENDS
      UNION ALL
      SELECT id_friend
        FROM TBL_FRIENDS) x ON x.user = u.user
1 голос
/ 30 августа 2010

Что ж, уникальное ограничение на пару столбцов приведет вас на полпути туда.Я думаю, что самый простой способ убедиться, что вы не получите обратную версию, - это добавить ограничение, обеспечивающее id_user

Что касается второго вопроса, найдите всех друзей по идентификатору= 1 вы можете выбрать id_user, id_friend из tbl_friend, где id_user = 1 или id_friend = 1, а затем в своем клиентском коде выбросить все 1 независимо от столбца.

0 голосов
/ 30 августа 2010

Один из способов сделать это - поместить двух друзей в два ряда:

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);

Видите?Не имеет значения, в каком порядке вы их вставляете, потому что оба друга попадают в столбец friend_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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...