6

MySQLデータベースをバイナリファイルにバックアップするコードを書いています。私は知ってmysqldumpいますが、いくつかの理由で簡単な方法を使用できません。私が現在していること:

  1. スキーマ定義を読む
  2. 外部キーの依存関係でテーブルを並べ替える
  3. すべてのテーブルの行を選択し(毎回100行)、バイナリファイルに書き込みます

依存関係の定義:テーブルは、のキーを指す外部キーが少なくとも1つある場合にのみT1、テーブルの存在に依存します。T2T1T2

各テーブルには数値が割り当てられます。この値は、テーブルの順序を指定します。依存関係のないテーブルの場合、この値は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());
    }
}

テーブルの依存関係グラフにサイクルがある場合、このアルゴリズムは終了しません。

通常、これはテーブルのそのようなデザインを持っていても大丈夫ですか?たとえば、相互に外部キーを持つ2つのテーブル。驚いたことに、Oracle for MySQL()が提供するサンプルデータベースにはsakila、このようなサイクルがたくさんあることがわかりました。3番目のテーブルを追加することで、そのすべてのサイクルを削除できると思います[?]

4

1 に答える 1

8

循環依存関係はかなり一般的です。いくつかの例:

  • 「隣接リスト」階層を実装する場合、テーブルはそれ自体を参照します。
  • 1:1 *関係を実装する場合、2 つのテーブルは相互に参照します。
  • 相互に参照する 2 つのテーブルは、1:N 関係 ("N" 側の行の 1 つが "特別" である場合) の可能な実装の 1 つです。
  • さらに、複数のテーブルが「リング」を形成している状況を見てきました...

そうです、循環依存関係があっても「OK」です。


*厳密には、真の1:1 には、ニワトリが先か卵が先か (MySQL ではサポートされていません) を解決するために遅延制約が必要です。 . しかし、これらすべてのケースで、互いに参照している 2 つのテーブルがあります。

于 2013-02-09T22:42:41.147 に答える