Database 数据库中是否可以接受循环引用?

Database 数据库中是否可以接受循环引用?,database,oracle,circular-dependency,Database,Oracle,Circular Dependency,数据库中何时可以接受循环引用 无论是理论上还是实践上,我们都非常感谢您的帮助。应避免像瘟疫一样使用循环引用。可以设置双向关系,甚至可以设置与您自己的关系(如果您是一个表的话),但是循环依赖只是自找麻烦。我见过出于性能原因而进行的循环引用。但它看起来很难看,性能可能可以忽略不计 示例:一些公告栏(我认为phpBB会这样做)在类别表中有一个lastposted,它是线程中最后一篇文章的快捷方式 这将创建一个圆,其中最后一篇文章与类别表之间有一个FK,而类别表与最后一篇文章之间有一个FK 就像我说的,

数据库中何时可以接受循环引用


无论是理论上还是实践上,我们都非常感谢您的帮助。

应避免像瘟疫一样使用循环引用。可以设置双向关系,甚至可以设置与您自己的关系(如果您是一个表的话),但是循环依赖只是自找麻烦。

我见过出于性能原因而进行的循环引用。但它看起来很难看,性能可能可以忽略不计

示例:一些公告栏(我认为phpBB会这样做)在类别表中有一个lastposted,它是线程中最后一篇文章的快捷方式

这将创建一个圆,其中最后一篇文章与类别表之间有一个FK,而类别表与最后一篇文章之间有一个FK


就像我说的,我不太喜欢它,但我已经看到了它的实现。

我很少遇到必要的1:1关系,并强加了循环关系


请注意,这种关系中的外键字段必须可以为空,否则您永远无法从表中删除行

如果您使用的是只写数据库,我想这不是问题。如果您计划使用CRUD的RUD部分,您可能会在处理它们时遇到(通常是可以避免的)复杂问题。

这在技术上是可行的,但在删除记录时可能会导致各种问题,因为它会产生鸡和蛋的问题。这些问题通常会采取激烈的行动,如手动删除FK并删除有问题的项目以解决

如果你有这样的关系:

create table foo_master (
       foo_master_id int not null primary key
      ,current_foo_id int
)


create table foo_detail (
       foo_detail_id int not null primary key
       foo_master_id int not null
)

alter table foo_master
  add constraint fk_foo_current_detail
      foreign key (current_foo_id)
      references foo_detail

alter table foo_detail
  add constraint fk_foo_master
      foreign key (foo_master_id)
      references foo_master
然后,由于循环依赖关系,删除记录可能会导致这样的chicken和agg问题

更好的模式如下所示:

create table foo_master (
       foo_master_id int not null primary key
)


create table foo_detail (
       foo_detail_id int not null primary key
       foo_master_id int not null
       is_current char (1)
)

alter table foo_detail
  add constraint fk_foo_master
      foreign key (foo_master_id)
      references foo_master

这意味着关系是非循环的,“当前”foo_详细信息记录仍然可以识别。

指向其他记录的记录在数据库中很有用。有时这些记录形成一个循环。这可能仍然有用。在实践中唯一真正令人烦恼的是避免违反约束

例如,如果您有一个用户和事务表,则该用户可能有一个指向其上一个事务的指针。您需要先插入事务,然后将
last\u transaction\u id
更新为正确的值。当这两个记录都存在时,您不能删除它们,因为
user.last\u transaction\u id
指向
transaction.id
,而
transaction.user\u id
指向
user.id
。这意味着没有事务的用户具有空的
last\u transaction\u id
。这还意味着您必须先将该字段设置为空,然后才能删除事务


管理这些外键约束是一件痛苦的事情,但这当然是可能的。如果稍后向数据库添加约束,从而引入新的循环依赖项,则可能会出现问题。在这种情况下你必须小心。但是,只要循环中的一条记录具有可为空的外键字段,就可以中断循环并删除记录。只要您按正确的顺序插入记录,更新通常不是问题。

Oracle分层查询语法的最新添加之一--
NOCYCLE
关键字--就是专门为此目的而添加的,用于处理数据中的循环引用。我看不出它有什么问题,以前也不得不处理这种模型。这并不太难,尤其是在支持延迟约束的Oracle中。

考虑城市和州。每个城市都存在于一个州内。每个州都有一个首都

创建表格城市(
城市瓦查尔(32),
state VARCHAR(32)不为空,
主键(城市),
外键(状态)引用状态(状态)
);
创建表状态(
州瓦查尔(32),
首都瓦查尔(32),
主键(状态),
外键(首府城市)引用城市(城市)
);
第一个问题-您无法如图所示创建这些表,因为外键不能引用表中不存在的列。解决方案是在不使用外键的情况下创建它们,然后再添加外键

第二个问题-无法将行插入任一表,因为每次插入都需要另一个表中预先存在的行。解决方案是设置一个 外键列必须为NULL,并分两个阶段插入该数据。e、 g

——创建状态记录
插入州(州、首府和城市)值('Florida',NULL);
--创造各种城市记录
插入城市(城市、州)值(“迈阿密”、“佛罗里达”);
插入城市(城市、州)值(“塔拉哈西”、“佛罗里达”);
插入城市(城市、州)值(“奥兰多”、“佛罗里达”);
--把其中一个城市定为首都
更新州集capital_city='Tallahassee',其中州='Florida';

根本不可能成为一个问题!请提供更多细节…圆形参考,不。球形参考是可以的。我们鼓励你去研究这一点。你为什么首先要这样做?在这里查看答案:这是一个伟大的深入研究循环引用的例子。你所说的双向关系是什么意思?将A点记录到B点和C点?相对于A指向B和B指向A?第二个肯定是圆形的。谢谢。很好的例子。SQL server对此循环引用给出错误-或注册表项“FK__城市__州__007;eabc”引用了无效的表“状态”。无法创建约束。请参阅前面的错误。在不允许空值的情况下插入行的其他可能性:1。全部插入,2。可推迟的限制。删除时也应这样做:3。德莱泽CASCADE@Falco请您举出一个将全部插入与循环FK一起使用的(工作)示例。为什么不可能在一个事务中使用两个插入?我的假设是,只应在事务结束时检查约束,但显然不是这样。某些数据库(例如postgresql)允许您