2013-02-09 115 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