是否有一种优雅的方式来存储双重关系(即用户1和用户2是朋友)

Ted*_*Ted 5 database database-design bit-manipulation bitmask social-networking

我本月在两个不同的工作中遇到了同样的问题:

Version 1: User 1 & User 2 are friends
Version 2: Axis 1 & Axis 2 when graphed should have the quadrants colored...
Run Code Online (Sandbox Code Playgroud)

问题是,我没有看到使用RDBMS来存储和查询此信息的优雅方式.

有两种明显的方法:

方法1:

store the information twice (i.e. two db rows rows per relationship):
u1, u2, true 
u2, u1, true
u..n, u..i, true
u..i, u..n, true

have rules to always look for the inverse on updates: 
on read, no management needed
on create, create inverse
on delete, delete inverse
on update, update inverse

Advantage:    management logic is always the same.
Disadvantage: possibility of race conditions, extra storage (which is admittedly cheap, but feels wrong)
Run Code Online (Sandbox Code Playgroud)

方法2:

store the information once (i.e. one db row per relationship)
u1, u2, true
u..n, u..i, true

have rules to check for corollaries:
on read, if u1, u2 fails, check for u2, u1 
on create u1, u2: check for u2, u1, if it doesn't exist, create u1, u2
on delete, no management needed
on update, optionally redo same check as create

Advantage: Only store once
Disadvantage: Management requires different set of cleanup depending on the operation
Run Code Online (Sandbox Code Playgroud)

我想知道是否有第三种方法沿着"使用f(x,y)的关键线,其中f(x,y)对于每个x,y组合是唯一的,其中f(x,y)=== F(Y,X)"

我的直觉告诉我应该有一些可以满足这些要求的按位运算组合.类似于两列的东西:

key1 = x && y key2 = x + y

我希望那些在数学系花费更多时间的人,以及更少的社会学部门的时间已经看到了这种可能性或不可能性的证明,并且可以提供一个快速的"[你好白痴],它很容易被证明(im)可能,请看这个链接"(名字叫可选)

任何其他优雅的方法也将非常受欢迎.

谢谢

ype*_*eᵀᴹ 7

还有一种方法可以通过添加额外约束来使用第二种方法.检查u1 < u2:

CREATE TABLE User
( Name VARCHAR(10) NOT NULL
, PRIMARY KEY (Name)
) ;

CREATE TABLE MutualFriendship
( u1 VARCHAR(10) NOT NULL
, u2 VARCHAR(10) NOT NULL
, PRIMARY KEY (u1, u2)
, FOREIGN KEY (u1) 
    REFERENCES User(Name)
, FOREIGN KEY (u2) 
    REFERENCES User(Name)
, CHECK (u1 < u2) 
) ;
Run Code Online (Sandbox Code Playgroud)

读取,创建,插入或更新的规则必须使用(LEAST(u1,u2), GREATEST(u1,u2)).