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