2013-02-09 101 views
3

我在寫代碼來將MySQL數據庫備份到二進制文件中。我知道mysqldump,但由於某些原因,我不能使用微不足道的方法。什麼我目前做:可以在關係數據庫中使用循環外鍵依賴關係嗎?

  1. 讀取架構定義的外鍵依賴
  2. 排序表
  3. 所有表中選擇行(每次100行),並在二進制文件中寫

相關性的定義:表T1取決於表T2的存在當且僅當至少在指向T2的密鑰的T1中有一個外鍵。

將數值分配給每個表。該值指定表格的順序。對於不依賴的表格,這個值爲0,對於其他表格,當前表格取決於表格的最大值;加一。如果在依賴表的值集合中存在-1,則當前表的值仍未定義(-1)。最初所有表的值是-1,這意味着未指定。

這是C++代碼:

// tablesQueue: Queue of all tables 
// orderedQueue: Resulting order 

while(! tablesQueue.isEmpty()) 
{ 
    bool satisfied = true; 
    foreach(TableNode* parent, tablesQueue.head()->referencedTables) 
    { 
     if(parent->degreeOfFreedom == -1) 
     { 
      satisfied = false; 
      break; 
     } 
     else 
      // handle error blah blah ... 
    } 
    if(satisfied) 
    { 
     int max =0; 
     foreach(TableNode* parent, tablesQueue.head()->referencedTables) 
     max = (max < parent->degreeOfFreedom+1) ? 
        parent->degreeOfFreedom+1 : max; 
     tablesQueue.head()->degreeOfFreedom = max; 
     orderedQueue.enqueue(tablesQueue.dequeue()); 
    } 
    else 
    { 
     tablesQueue.enqueue(tablesQueue.dequeue()); 
    } 
} 

如果在表中的依賴圖一個週期,該算法不會終止。

通常情況下可以有這樣的表格設計嗎?例如兩個表彼此具有外鍵。令人驚訝的是,我發現Oracle爲MySQL提供的示例數據庫(sakila)有很多這樣的週期。我假設可以通過添加第三個表來刪除所有的循環[?]

+0

只要循環中至少有一個允許爲空的鏈接(即_not_聲明爲「NOT NULL」),我就不會看到循環外鍵依賴性的問題。 – 2013-02-09 20:39:35

+0

@IanRoberts當您嘗試將所有數據寫入文件並再次恢復時,會出現問題。假設你正在讀取你行備份文件中'n'行的數據。它依賴於'B'中相應行的存在;說行號'm'。你需要在'A'的第n行之前寫下'm'行。但是,如果'm-i'行的'B'有一個指向'A'的第n + j個鍵的鍵,那麼你沒有有效的表順序來恢復你的數據庫。 – 2013-02-09 20:49:07

回答

3

循環依賴是相當普遍的。一些示例:

  • 表執行"adjacency list"層次結構時引用自己的表。
  • 兩個表在執行1:1的關係時相互參照。
  • 兩個相互引用的表是1:N關係(其中「N」一側的行之一是「特殊」)的可能實現之一。
  • 此外,我見過的情況下可形成一個「環」多個表...

所以,是的,它是「確定」,有循環依賴。


*嚴格地說,一個真正:1,需要延期的限制,解決了雞和蛋的問題(未在MySQL的支持),否則你只能有1:0 .. 1或0..1:0..1。但在所有這些情況下,您都有兩個相互引用的表格。

+1

在這種情況下,備份和恢復將無法正常工作。我將在恢復並重新啓用之前禁用外鍵檢查。 (兩個查詢'SET FOREIGN_KEY_CHECKS = 0;'和'SET FOREIGN_KEY_CHECKS = 1;') – 2013-02-10 08:25:07

+1

EXEC sp_msforeachtable「ALTER TABLE?NOCHECK CONSTRAINT all」 – Mzn 2014-05-05 15:25:59

+0

http://stackoverflow.com/questions/159038/can-foreign-key- constraints-be-temporarily-disabled-using-t-sql – Mzn 2014-05-05 15:27:23