SQL-Лучшая практика для таблицы Дружбы

прежде чем вы покажете мне дубликаты, обратите внимание, что я искал через сайт и нашел некоторые примеры, но не совсем конкретно к моей проблеме :)

каков наилучший способ создать Дружба таблица в SQL, но убедитесь, что каждая строка уникальна в том смысле, что один и тот же UserID и FriendID никогда не будут alowed независимо от того, к какому столбцу они принадлежат?

у меня это грубо пример

CREATE TABLE [dbo].[Friendship](
    [UserID] [uniqueidentifier] NOT NULL,
    [FriendID] [uniqueidentifier] NOT NULL,
    [FriendshipStatus] [int] NOT NULL
)

и есть 2 внешних ключа к таблице пользователей, как от UserID, так и от FriendID.

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

UserID    FriendID    FriendshipStatus
Guid 123   Guid 789    1
Guid 789   Guid 123    1

как я могу гарантировать, что эта целостность соблюдается, возможно 2 PKs? Что-то вроде уникальный индекс? Или вы предложили бы лучший дизайн стола все вместе? Кроме того, вы бы поставили autoincrementing FriendshipID? Если да, то можете объяснить почему?

5 ответов


создание первичного ключа для FRIENDSHIP таблицы:

  • userid
  • friendid

...гарантирует, что у вас не может быть дубликатов в порядке. Это означает, что это остановит вас от добавления дубликатов userid " 123 "и friendid"789". Если вы включаете столбец status, это больше не так, потому что другое значение status позволит дублировать столбец userid и friendid.

Остановка Обратного Пары

чтобы остановить обратные пары -- userid " 789 "и friendid" 123 " -- вам нужно либо включить логику, чтобы проверить, существует ли пара в таблице в хранимой процедуре, функции или триггере. Ограничение проверки userid

INSERT INTO FRIENDSHIP
SELECT @userid, @friendid, 1
  FROM FRIENDSHIP f
 WHERE NOT EXISTS(SELECT NULL
                    FROM FRIENDSHIP t
                   WHERE (t.userid = @friendid AND t.friendid = @userid)
                      OR (t.userid = @userid AND t.friendid = @friendid)

Quassnoi написал статью, объясняющую, почему вы можете захотеть иметь версию таблицы с двумя строками на пару, чтобы упростить запросы:http://explainextended.com/2009/03/07/selecting-friends/

(в статье говорится о MySQL, но стоит иметь в виду, как метод производительности для любой базы данных SQL)


Я сделал небольшое изменение для выполнения внутреннего запроса и возвращает только запись, когда существует (двойная таблица) в конце круглых скобок

INSERT INTO FRIENDSHIP
SELECT @userid, @friendid, 1
  FROM DUAL f
 WHERE NOT EXISTS(SELECT NULL
                FROM FRIENDSHIP t
               WHERE (t.userid = @friendid AND t.friendid = @userid)
                  OR (t.userid = @userid AND t.friendid = @friendid) )

Table User: UserId
Table Friendship: FriendshipId
Table UserFriendships: UserId, FriendshipId, FriendshipStatus

вы можете добавить уникальное ограничение, чтобы пользователь не был в дружбе дважды.


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


Пользователь (UserID) Дружба (User1ID, User2ID, FriendshipStatus)

проверить ограничение: User1ID

уникальное ограничение: User1ID, User2ID