2009-06-17 99 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'; 
相關問題