2009-06-17 62 views
22

数据库中的循环引用何时可以接受?循环引用是否可以在数据库中使用?

理论和实际,任何帮助表示赞赏。

+0

甚至不是一个问题! PLease供应更多的细节... – 2009-06-17 13:15:04

+0

你的问题又是什么? – Macarse 2009-06-17 13:16:37

+0

循环引用,没有。球形参考是可以的。你被鼓励去研究那个。 – fig 2009-06-17 13:33:35

回答

11

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

例如,如果您有用户和交易表,用户可能有一个指向他上次交易的指针。您需要先插入交易,然后将last_transaction_id更新为正确的值。虽然这两个记录都存在,但不能删除它们,因为user.last_transaction_id指向transaction.idtransaction.user_id指向user.id。这意味着没有交易的用户的空值为last_transaction_id。这也意味着您必须先删除该字段,然后才能删除该事务。

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

1

循环引用应该像瘟疫一样避免。有可能建立双向关系,甚至建立与自己的关系(如果你是一个表),但循环依赖只是在寻求麻烦。

1

我已经看到循环引用性能的原因。它看起来很丑陋,而且性能可能可以忽略不计。

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

这会创建一个圆圈,最后一个帖子的FK指向类别表,而类别表的FK指向最后一个帖子。

就像我说的,我并不喜欢它,但我已经看到它完成了。

0

很少我碰到一个1运行:1的关系是必要的,并规定一个循环关系

注意,在这种关系中的外键字段都必须为空,否则你永远无法从表中

删除行
0

我想这不是一个问题,如果您使用的是只写数据库。如果你打算使用CRUD的RUD部分,你很可能会遇到(通常是可以避免的)处理这些问题的复杂问题。

3

这在技术上是可行的,但是当它删除记录时会引起各种各样的问题,因为它会产生鸡与鸡的问题。这些问题通常需要采取激烈的行动,如手动放弃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 

然后删除记录可能会导致这样的鸡和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_detail战绩尚可辨认。

3

Oracle分层查询语法的最新版本之一 - NOCYCLE关键字 - 专门用于此目的 - 用于处理数据中的循环引用。我没有看到任何问题,而且之前不得不面对这种模式。这并不难,尤其是在支持延期约束的Oracle中。

20

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

CREATE TABLE city (
    city VARCHAR(32), 
    state VARCHAR(32), 
    PRIMARY KEY (city), 
    FOREIGN KEY (state) REFERENCES state (state) 
); 

CREATE TABLE state (
    state VARCHAR(32), 
    captial_city VARCHAR(32), 
    PRIMARY KEY (state), 
    FOREIGN KEY (captial_city) REFERENCES city (city) 
); 

第一个问题 - 您无法创建这些表格,如图所示。解决方案是在没有外键的情况下创建它们,然后添加外键。

第二个问题 - 无法将行插入到任何一个表中,因为每个插入操作都需要另一个表中的预先存在的行。解决方法是将其中一个外键列设置为NULL,并分两个阶段插入该数据。例如

INSERT INTO city (city, state) VALUES ('Miami', NULL); 
INSERT INTO state (state, capital_city) VALUES ('Florida', 'Miami'); 
UPDATE city SET state='Florida' WHERE city='Miami'; 
相关问题