【问题标题】:SQL - Best practice for a Friendship tableSQL - 友谊表的最佳实践
【发布时间】:2011-05-12 07:45:01
【问题描述】:

在您向我展示重复内容之前,请注意,我已经通过该网站进行了搜索,发现了 一些 示例,但并不完全针对我的问题 :)

在 SQL 中创建 Friendship 表的最佳方法是什么,但要确保每一行都是唯一的,因为无论它们属于哪一列,都不会允许使用相同的 UserID 和 FriendID ?

我有这个粗略的例子

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

Users 表有 2 个外键,分别来自 UserID 和 FriendID。

目前,我可以在用户之间两次插入友谊,从而创建一个副本。示例

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

我如何确保这种完整性得到执行,也许 2 PKs?某种唯一索引?或者你会建议一个更好的桌子设计吗?另外,你会放一个自动递增的FriendshipID吗?如果有,你能解释一下原因吗?

【问题讨论】:

    标签: sql sql-server tsql database-design data-modeling


    【解决方案1】:

    FRIENDSHIP 表的主键设为:

    • 用户名
    • 朋友ID

    ...将确保您不能按顺序重复。这意味着,它将阻止您添加用户 ID“123”和朋友 ID“789”的重复项。如果包含状态列,则不再是这种情况,因为不同的状态值将允许用户 ID 和朋友 ID 列的重复。

    停止反向对

    为了停止反向配对——用户ID“789”和朋友ID“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)
    

    【讨论】:

      【解决方案2】:

      Quassnoi 写了一篇文章解释了为什么您可能希望拥有一个每对两行的表版本,以使查询更容易:http://explainextended.com/2009/03/07/selecting-friends/

      (这篇文章讨论了 MySQL,但作为任何 SQL 数据库的性能技术都值得牢记)

      【讨论】:

        【解决方案3】:

        我做了一个小改动来执行内部查询,并在末尾括号中存在(双表)时只返回一条记录

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

        【讨论】:

          【解决方案4】:
          Table User: UserId
          Table Friendship: FriendshipId
          Table UserFriendships: UserId, FriendshipId, FriendshipStatus
          

          您可以添加一个 UNIQUE 约束来防止用户两次成为好友。


          你有用户和友谊。用户可以通过在第三个表中创建记录来加入 Friendships(可以是 0 个或多个 Users)。

          【讨论】:

          • 谢谢@David,你能详细说明一下吗?我不太明白第三张桌子的必要性。
          【解决方案5】:

          用户(用户 ID) 友谊(User1ID, User2ID, FriendshipStatus)

          检查约束:User1ID

          唯一约束:User1ID、User2ID

          【讨论】:

            猜你喜欢
            • 2013-10-20
            • 2017-12-11
            • 2012-01-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-08-29
            • 2015-08-21
            • 2010-11-19
            相关资源
            最近更新 更多