SQL:避免循环依赖

标签 sql database-design circular-dependency

我看到大多数人只是讨厌在数据库设计中存在循环依赖。由于在大多数数据库引擎中对此的支持是“棘手的”,我想知道是否有办法绕过这种设计:

我有一个用户表和一个图片表

每张图片都有一个 userId(插入它的用户)
每个用户都有一张个人资料图片

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

我知道还有其他一些与此问题相关的问题,但它们更多地与父子关系有关,而这里的情况并非如此。

那么,在这里使用循环依赖可以吗?如果没有,你将如何避免它?

最佳答案

表之间没有循环引用:

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 - 使用延迟约束。

关于SQL:避免循环依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8954321/

相关文章:

c++ - 循环依赖...怎么解决?

java - JDBC:将日期值插入 MySQL

SQL-Server 时间数据类型

sql - Oracle 复制数据到另一个表

java - 使用 LIKE 时在 Java 中清理 SQL 输入

postgresql - JSONB 空字段的唯一约束

mysql - SQL查询在内部连接到右表后从左表中选择不同的行

php - drupal 7 将实际内容存储在数据库中的什么位置?

javascript - ES6 模块和循环依赖

java - JPA 和 Lombok 在循环依赖中导致 StackOverflowError