6

我正在编写代码以将 MySQL 数据库备份到二进制文件中。我知道mysqldump但由于某些原因我不能使用琐碎的方法。我目前在做什么:

  1. 读取架构定义
  2. 按外键依赖对表进行排序
  3. 选择所有表中的行(每次 100 行)并将它们写入二进制文件

依赖关系的定义:一个表T1依赖于表的存在T2当且仅当至少有一个外键T1指向T2的键。

为每个表分配一个数值。此值指定表的顺序。对于没有依赖关系的表,这个值0对于其他表来说是当前表依赖的表的最大值;加一。如果-1依赖表的值集合中有 a,则当前表的值保持未定义(-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) 提供的示例数据库有很多这样的循环。我假设可以通过添加第三个表来删除所有循环 [?]

4

1 回答 1

8

循环依赖相当普遍。一些例子:

  • 实现“邻接列表”层次结构时,表引用自身。
  • 实现 1:1 *关系时,两个表相互引用。
  • 相互引用的两个表是 1:N 关系的可能实现之一(其中“N”侧的行之一是“特殊”)。
  • 此外,我见过多个表形成“环”的情况......

所以是的,拥有循环依赖是“可以的”。


*严格来说,真正的1:1 需要延迟约束来解决鸡和蛋问题(MySQL 不支持),否则只能有 1:0..1 或 0..1:0..1 . 但在所有这些情况下,您都有两个相互引用的表。

于 2013-02-09T22:42:41.147 回答