繁体   English   中英

SQL-友谊表的最佳做法

[英]SQL - Best practice for a Friendship table

在向您显示重复项之前,请注意,我已经在网站上搜索了一些示例,但并非完全针对我的问题:)

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

我有这个粗略的例子

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

并且有两个外键,分别来自UserID和FriendID。

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

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

如何确保执行此完整性(也许2个PK) 某种独特的索引 还是您会建议一个更好的餐桌设计? 另外,您是否会添加一个自动递增的FriendshipID 如果是这样,您能解释为什么吗?

使FRIENDSHIP表的主键为:

  • 用户身份
  • 友情

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

停止反向对

为了停止反向对-用户标识“ 789”和友好标识“ 123”,您需要包含逻辑以检查该对在存储过程,函数或触发器中是否已存在于表中。 如果还不存在相反的条件,则userid <friendid的CHECK约束将停止添加userid“ 789”和友好“ 123”的有效尝试。

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

您可以添加UNIQUE约束,以防止用户两次处于友谊状态。


您有用户和友谊。 用户可以通过在第三个表中创建一条记录来加入“友谊”(可以是0个或更多用户)。

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

检查约束:User1ID <User2ID

唯一约束:User1ID,User2ID

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM