6

我的應用程序將大量來自數據庫的數據加載到複雜的數據結構中。在內存中的數據結構ressembles的數據庫的結構,這意味着,如果該數據庫包含以下表:外鍵的循環依賴:使用它還是避免它?

  • 表A,關鍵是A1
  • 表B,關鍵是B1,其中一列是一個外鍵表[中的關鍵]甲
  • 表C,關鍵是C1,列中的一個是外鍵[關鍵表B

然後,我有類A, B和C,以及:

  • B(B :: M_A)的數據成員是一個指向
  • Ç(C :: M_B)的數據成員是一個指針到B

這意味着,如果我負荷數據庫,我必須以正確的順序加載它。如果我第一次加載C,那麼它會抱怨它不能設置值C :: m_b,因爲它指向的實例沒有加載。

問題是,當有語言中也有一列是一個外鍵的其他表之一,讓我們說C.

我可以通過加載所有外鍵作爲字符串解決問題,然後執行在所有數據加載完畢後進行查找,但由於我有時需要加載數百萬條記錄,所以我無法承擔在這些(儘管是臨時)字符串上的內存消耗。

在閱讀過有關優秀設計(例如「大規模C++軟件設計」一書)的文章之後,我認爲根本不需要循環引用。 例如如果文件X.H包含Y.H,但是Y.H也包含X.H,則可能是設計不好;如果X類依賴於Y類,反之亦然,你可能會有一個糟糕的設計,應該通過提取這個依賴關係並引入一個依賴於X和Y的第三類Z來解決(X和Y不再依賴於對方) 。

將此設計規則擴展到數據庫設計是一個好主意嗎?換句話說:防止外鍵中的循環引用。

回答

3

您應該只需要一個循環引用的時候就是在創建分層結構時,比如組織樹。

Table Employees 
    EmployeeID <----------| 
    SupervisorEmployeeID ---| 
2

是的,數據庫中的週期性依賴關係是重新考慮設計的良好藉口。

+0

爲什麼?你沒有爲你的斷言提供理由。 – cdmckay 2017-09-26 01:58:43

4

從數據建模的角度來看,circualr依賴關係沒有什麼根本的「錯誤」。這並不意味着該模型是錯誤的。

不幸的是,大多數SQL DBMS不能有效地實現這樣的約束,因爲它們不支持多表更新。通常,解決這個問題的唯一方法是暫時暫停一個或多個約束(例如使用「可推遲的」外鍵或類似功能),或者通過更改模型使約束的某些部分可選(將其中一個引用列放入新表)。這只是SQL的討厭限制的一個解決方法,但是,這並不意味着你開始時做了任何錯誤。

2

您必須對您擁有的數據建模。如果數據中存在循環關係(例如,每張照片屬於一個文件夾;但每個文件夾都有一張封面照片),那麼將其建模爲數據庫中的循環關係是正確的。

我在使用Oracle時只有這種情況,所以我沒有機會查看如何在其他數據庫上實現這種關係。但對於Oracle,您可以在這裏閱讀我的文章:

http://www.databasesandlife.com/circular-dependencies-on-foreign-key-constraints-oracle/