SQL - Best practice for a Friendship table

后端 未结 5 1410
青春惊慌失措
青春惊慌失措 2020-12-14 03:58

Before you show me duplicates, please note that I\'ve searched through the site an have found some examples but not quite specific to my prob

相关标签:
5条回答
  • 2020-12-14 04:20
    Table User: UserId
    Table Friendship: FriendshipId
    Table UserFriendships: UserId, FriendshipId, FriendshipStatus
    

    You can add a UNIQUE constraint to prevent a User from being in a Friendship twice.


    You have Users and Friendships. Users can join Friendships (which can be 0 or more Users) by creating a record in the third table.

    0 讨论(0)
  • 2020-12-14 04:23

    Making the primary key for the FRIENDSHIP table to be:

    • userid
    • friendid

    ...will ensure that you can't have duplicates in order. Meaning, it will stop you from adding duplicates of userid "123" and friendid "789". If you include the status column, that's no longer the case, because a different status value will allow for duplicates of the userid and friendid column.

    Stopping Reverse Pairs

    In order to stop reverse pairs -- userid "789" and friendid "123" -- you need to either include the logic to check if the pair already exists in the table in a stored procedure, function, or trigger. A CHECK constraint of userid < friendid would stop a valid attempt to add userid "789" and friendid "123" if the reverse doesn't already exist.

    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)
    
    0 讨论(0)
  • 2020-12-14 04:26

    Quassnoi wrote an article explaining why you might want to have a version of the table with two rows per pair, to make queries easier: http://explainextended.com/2009/03/07/selecting-friends/

    (the article talks about MySQL but it is worth bearing in mind as a performance technique for any SQL database)

    0 讨论(0)
  • 2020-12-14 04:35

    I did a small change to perform the internal query and returns only a record when exists (dual table) at the end finish parentheses

    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) )
    
    0 讨论(0)
  • 2020-12-14 04:36

    User(UserID) Friendship(User1ID, User2ID, FriendshipStatus)

    Check constraint: User1ID < User2ID

    Unique constraint: User1ID, User2ID

    0 讨论(0)
提交回复
热议问题