0

文字列と数値の確率で構成されるデータベースがあります (他の列はありますが、質問には関係ありません)。簡略化されたスキーマは

+-----------------------+----------------------+
| gopair                | P_high               |
+-----------------------+----------------------+
| GO:0000398_GO:0030540 |    0.275997567007171 |
| GO:0015198_GO:0016846 | 5.24489289777325e-06 |
| GO:0034649_GO:0072141 |  0.00338367340340417 |
| GO:0004303_GO:0031053 |    0.110417921058026 |
+-----------------------+----------------------+

私の仕事では、特定の GO ペアに関連付けられた値をデータベースに照会するスクリプトを実行します。私の結果が無作為に得られた結果と異なることを証明する必要があります。したがって、実行したいテストの 1 つは、P_high列をシャッフルしてからスクリプトを実行し、結果を分析することです。

入力ファイルをシャッフルしてデータベースをリロードしようとしましたが、問題の入力ファイルが 7GB のテキスト ファイルであり、3GB の RAM しか搭載されていないマシンでは扱いにくいため、これは複雑です。

では、残りを静的に保ちながら、データベース内の特定の列をランダム化する方法はありますか?

警告:

  • 問題のテーブルは LARGE (60,164,966 行) です。
  • 厳密な数学的ランダム性は必要ありません
  • 同じ周波数を維持する必要があります。N 個のペアが実際のデータベースでPの確率を持つ場合、ランダムなデータベースでPの確率を持つにはN 個のペアが必要です。
  • 永続的なソリューションが必要です。私のスクリプトでは、データベースに対して同じペアを複数回クエリする可能性があるため、単純にランダムなペアを選択するだけでは十分ではありません。
  • これらすべてを繰り返し実行する必要があるため、スクリプト可能な (できれば Perl) ソリューションが優先されます。
  • Ubuntu サーバーで、readline 6.1 を使用して debian-linux-gnu (x86_64) 用の mysql Ver 14.14 Distrib 5.1.41 を実行しています。
4

1 に答える 1

1

このテーブルの主キーはどのように見えますか? 整数の代理キーを使用している場合は、次のことができます: [4 バイトの整数を想定]

  1. すべてのキーのリストをダンプします。$list[][240MB ギブ・オア・テイク]
  2. リストを複製します。$shuf[][別の 240MB +/-]
  3. 重複リストをシャッフルします。[シャッフル関数はコピーを返す場合があり、その場合は #2 をスキップ]
  4. テーブルに別の列 [ie: shuffle_key] を追加し、当面はインデックスを作成しません。
  5. Perl の構文にはあまり詳しくありませんが、PHP に似ているので、次のように記述します。

    $cnt = count($list);
    for($i=0; $i<$cnt; $i++) {
        $query = sprintf(
            'UPDATE table SET shuffle_key = %d WHERE primary_key = %d',
            $shuf[$i], $list[$i] );
        $dbh->doQuery($query);
    }
    
  6. 新しい列に UNIQUE インデックスを作成します。

  7. これで、主キーとシャッフルされたキーでテーブルを自己結合し、一方から gopair を使用し、他方から P_high を使用できます。

    SELECT t1.gopair, t2.P_high
    FROM table t1 INNER JOIN table t2
      ON t1.primary_key = t2.shuffle_key
    

これに必要なメモリ量は、主キーのサイズ×行数の約 2 倍になりますが、より大きな側でも、数ギガバイト以上を占めることはありません。

注: 操作の途中で重複キーの警告が表示されないように、インデックスをシャッフルするたびに、shuffle_index 列のインデックスを削除する必要があります。その後、インデックスを再度追加します。

于 2013-01-23T18:34:05.550 に答える