Reputation: 8639
I see that most people just hate having a circular dependency in the database design. And since the support for this is "tricky" in most database engines, I was wondering if there's a way around this design:
I have a users table and a pictures table
Every picture has an userId (the user who inserted it) Every user has a profile picture
I might just create a ProfilePictures table, but it would cause issues in some other places (like picture comments).
I'm aware that there are some other questions related to this issue, but they're more related to partent-child relationships, which is not the case here.
So, is it ok to use a circular dependency here? or if not, how would you avoid it?
Upvotes: 6
Views: 12849
Reputation: 115590
Without circular references between tables:
User
------
userid NOT NULL
PRIMARY KEY (userid)
Picture
---------
pictureid NOT NULL
userid NOT NULL
PRIMARY KEY (pictureid)
UNIQUE KEY (userid, pictureid)
FOREIGN KEY (userid)
REFERENCES User(userid)
ProfilePicture
---------
userid NOT NULL
pictureid NOT NULL
PRIMARY KEY (userid)
FOREIGN KEY (userid, pictureid) --- if a user is allowed to use only a
REFERENCES Picture(userid, picture) --- picture of his own in his profile
FOREIGN KEY (pictureid) --- if a user is allowed to use any
REFERENCES Picture(picture) --- picture in his profile
The only difference with this design and your needs is that a user may not have a profile picture associated with him.
With circular references between tables:
User
------
userid NOT NULL
profilepictureid NULL --- Note the NULL here
PRIMARY KEY (userid)
FOREIGN KEY (userid, profilepictureid) --- if a user is allowed to use only a
REFERENCES Picture(userid, pictureid) --- picture of his own in his profile
FOREIGN KEY (profilepictureid) --- if a user is allowed to use any
REFERENCES Picture(pictureid) --- picture in his profile
Picture
---------
pictureid NOT NULL
userid NOT NULL
PRIMARY KEY (pictureid)
UNIQUE KEY (userid, pictureid)
FOREIGN KEY (userid)
REFERENCES User(userid)
The profilepictureid
can be set to NOT NULL
but then you have to deal with the chicken-and-egg problem when you want to insert into the two tables. This can be solved - in some DBMS, like PostgreSQL and Oracle - using deferred constraints.
Upvotes: 12
Reputation: 112482
If only a few pictures are stored per user, you could just have a flag in the pictures telling if a picture is the profile picture or not.
Upvotes: 2
Reputation: 20320
Users has UserID and ProfilePictureID
Pictures
Has a PictureID, a Picture and a UserID
Delete the user and their profile picture will/can be deleted by PictureID, and any other pictures by userid if desired.
Don't even consider this circular as such.
Upvotes: 0