在您向我显示重复项之前,请注意我在网站上搜索了一些一些示例,但对我的问题并不十分具体:)
在SQL中创建友谊表的最佳方法是什么,但要确保每一行都是唯一的,因为无论相同的UserID和FriendID属于哪一列,都不会被允许?
我有这个粗略的例子
CREATE TABLE [dbo].[Friendship](
[UserID] [uniqueidentifier] NOT NULL,
[FriendID] [uniqueidentifier] NOT NULL,
[FriendshipStatus] [int] NOT NULL
)
User表有2个外键,来自UserID和FriendID。
目前,我可以在用户两次之间插入友谊,从而创建副本。实施例
UserID FriendID FriendshipStatus
Guid 123 Guid 789 1
Guid 789 Guid 123 1
如何确保强制执行此完整性,可能 2 PK ?某种独特的指数?或者你会建议一起更好的桌子设计吗?另外,你会自动增量FriendshipID
吗?如果是这样,你能解释一下原因吗?
答案 0 :(得分:15)
使FRIENDSHIP
表的主键为:
...将确保您不能按顺序重复。这意味着,它将阻止您添加用户ID“123”和friendid“789”的重复项。如果包含状态列,则不再是这种情况,因为不同的状态值将允许重复用户ID和friendid列。
为了停止反向对 - userid“789”和friendid“123” - 您需要包含逻辑以检查存储过程,函数或触发器中的表中是否已存在该对。用户ID的CHECK约束<如果反向不存在,friendid将停止有效尝试添加用户ID“789”和friendid“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)
答案 1 :(得分:4)
Quassnoi撰写了一篇文章,解释了为什么您可能希望拥有每对两行的表格版本,以便于查询:http://explainextended.com/2009/03/07/selecting-friends/
(文章讨论了MySQL,但值得记住,作为任何SQL数据库的性能技术)
答案 2 :(得分:1)
我做了一个小小的更改来执行内部查询,并在最后完成括号时只返回存在的记录(双表)
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) )
答案 3 :(得分:0)
Table User: UserId
Table Friendship: FriendshipId
Table UserFriendships: UserId, FriendshipId, FriendshipStatus
您可以添加UNIQUE约束以防止用户两次加入友谊。
您拥有用户和友谊。用户可以通过在第三个表中创建记录来加入友谊(可以是0个或更多用户)。
答案 4 :(得分:0)
用户(用户ID) 友谊(User1ID,User2ID,FriendshipStatus)
检查约束:User1ID< User2ID
唯一约束:User1ID,User2ID