Reputation: 1999
I am designing database for social networking site with "followers" and "following" feature like twitter. There are some relations which are common to whole circle i.e to whom i am following and to my followers too.. I have a table Following with uid1 and uid2. Suppose A follows B and B follows A and C. It will have entries like
uid1 uid2
A B
B A
B C
Now i want a third field relationId in the same table which should be unique to a relation whether A follows B or B follows A like
uid1 uid2 relationId
A B 1
B A 1
B C 2
so that i can use relationId as foreign key in another table to store features common to whole circle of a user. One thing immediately comes to mind is if there can be a commutative formula to fetch a unique number( relationId) given two numbers(uid1 and uid2). But what it can be?
Edit
I also have one more doubt. Since username in my database is unique. So shall i use username as primary key in whole database or do we have a performance benefit by using a number as primary key as uid in my case with a table to resolve uid and username?
Upvotes: 0
Views: 79
Reputation: 285077
I would do it similar to the way you have it:
Follows
-------
follower followed
A B
B A
B C
This could obviously have information like followDate
which makes sense in both directions.
Then you can also have:
Connected
-----------------
relationId uid1 uid2
x 2 3
with relationId
an artificial key (could be INT AUTOINCREMENT, GUID, etc.)
However, Connected would have a constraint (whether you can enforce this in the db layer depends on your system) that uid1 < uid2
. Obviously, this also implies you'll never have it both ways.
This is relatively simple, easy to query, and should have decent performance with a good composite unique index on uid1
and uid2
. When searching for non-directional information about the relationship, you don't have to look at indices for both directions.
EDIT: I would recommend using an artificial key for users. Even if you don't allow username changes now, you may want to do so later.
EDIT 2: According to this, you can reject an insert in a trigger by setting a NOT NULL column to NULL. Both uids should be NOT NULL, so you can just set one to NULL if uid1 >= uid2
.
Upvotes: 3