2012-01-21 226 views
4

我看到大多数人只是讨厌在数据库设计中存在循环依赖。而且,由于这种支持是大多数数据库引擎“猫腻”,我想知道是否有解决这个设计的方式:SQL:避免循环依赖

我有一个用户表和图片表

每张照片都有一个用户ID(在插入它的用户) 每个用户都有一个配置文件图片

我可能只是创建一个ProfilePictures表格,但它会在一些其他地方(如图片评论)导致问题。

我知道还有一些与此问题有关的其他问题,但它们更多地与partent-child关系有关,在这里不是这种情况。

那么,在这里使用循环依赖可以吗?或者如果不是,你会如何避免它?

+0

因此,用户可能会插入许多图片。一张图片由一个用户插入。用户(可能)有一个配置文件图片(或没有)。正确? –

+0

我不会使用循环依赖,除非绝对没有其他方式来做到这一点。在25年以上的数据库工作中,我从未见过没有替代品的情况。大多数人不会考虑的一个问题是,循环依赖会破坏很多第三方工具,如CASE,图表和逆向工程工具。 –

回答

7

没有表之间的循环引用:

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 

这种设计和需求的唯一区别是,用户可能没有与他相关的资料图片。


随着表之间的循环引用:

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) 

profilepictureid可以设置为NOT NULL但你必须要处理的鸡和蛋的问题,当你要插入到两个表。这可以通过使用延迟约束来解决 - 在某些DBMS中,如PostgreSQL和Oracle。

+0

谢谢,其实第二个是我现在的设计。我可以添加ProfilePictures表,但这不会解决循环依赖问题(即,我不能删除用户而不删除图片,并且我不能删除图片而不删除用户,所以它基本上与具有相同两个表,并允许用户中的profilepictureid为空) – willvv

+0

我的第一种方法没有循环依赖关系。 –

+0

在第二个系统中,如果图片(PictureID)是主键,则图片(用户ID,图片ID)的组合不可能是唯一的。你似乎坚持要求用户不能插入他们没有插入的个人资料图片 - 这可能是其意图。 –

0

用户拥有的用户ID和ProfilePictureID

图片

拥有PictureID,图片和用户名

删除用户和他们的个人资料图片/可以通过PictureID被删除,以及任何其它图片如果需要,可以用用户名。

甚至不要考虑这个通告。

+1

你是什么意思“不考虑这个通告”?我的问题是我不能删除用户而不删除图片,并且我不能删除图片而不删除用户。 – willvv

+0

那么如果你在我回答时发布了你的模式,我就会看到你的模式。不是我所做的设计决定,它会导致你看到的问题。 :) –

2

如果每个用户只存储少量图片,那么您可以在图片中添加一个标志,告诉图片是否为个人资料图片。