2016-06-01 8 views
0

〜55KレコードをmySQLサーバーからMongoDBに移行しようとしています。私はJSON/CSVインポートのような簡単にアクセス可能なメソッドを使ってこれを行うことはできません。なぜなら、データの格納方法(構造化されている方法)は非常に異なるからです。このため、私はこれを行うように設計されたPHPでスクリプトを作成しました。PHPでmySQLがnullの結果を返すのはなぜですか?

私がこれまで実行してきた問題は、小さなセットに問題のあるエントリが含まれていても、小さなデータセットを使って再現性のない大きなデータセットでは、エントリが存在してもデータが報告されないことがあります。 phpがその特定のエントリに直接アクセスするか、より小さいデータセットに含まれているときにうまく動作するので、絶対に存在します。例えば、テキストファイルへのインポートでは、私は42k/54kレコードしか受信しませんでした。

phpファイルが呼び出されたURLを介してエコーを受信して​​いますが、クエリが正しい回数だけ呼び出されていますが、存在しないと表示されているレコードが多いため、空白です。以下のコードは含まれています:私も1つのチャンクの代わりに、個々のクエリのトンで結果のかなりの数(すべて、半分、四半期、などを)引っ張るクエリでこれを試してみました

//Makes a connection to the database 
$conn = makeConnection(); 

$filename = '/home/dbserverdownload.txt'; 
$file = fopen($filename, 'a'); 

$sql = "SELECT * FROM maintable ORDER BY ID DESC LIMIT 1"; 
$resultID = mysqli_query($conn, $sql); 
$ID = mysqli_fetch_object($resultID); 
echo $ID->ID; 
//loops through the database and appends the data to the file as it goes 
for($var=2; $var <= $ID->ID; $var++){ 
    $sql1 = "SELECT * FROM servertable WHERE ID = '$var'"; 
    $result1 = mysqli_query($conn, $sql1); 
    $values = mysqli_fetch_object($result1); 

    $id = $values->ID; 
    $ip = $values->IP; 
    $port = $values->port; 
    $running = $values->running; 
    $afk = $values->afk; 
    $gamemode = $values->gamemode; 
    $maxplayers = $values->maxplayers; 
    $spawnprotection = $values->spawnprotection; 
    $whitelist = $values->whitelist; 
    $enablequery = $values->enablequery; 
    $enablercon = $values->enablercon; 
    $rconpassword = $values->rconpassword; 
    $motd = $values->motd; 
    $achievements = $values->announceplayerachievements; 
    $allowflight = $values->allowflight; 
    $spawnanimals = $values->spawnanimals; 
    $spawnmobs = $values->spawnmobs; 
    $forcegamemode = $values->forcegamemode; 
    $hardcore = $values->hardcore; 
    $pvp = $values->pvp; 
    $difficulty = $values->difficulty; 
    $generatorsettings = $values->generatorsettings; 
    $levelname = $values->levelname; 
    $levelseed = $values->levelseed; 
    $leveltype = $values->leveltype; 
    $autosave = $values->autosave; 

if($ip == "148.57.44.10"){ 
    //if the server is server1 
    $servername = "server1".$port; 
} else if ($ip == "165.108.22.199"){ 
    //if the server is server2 
    $servername = "server2".$port; 
} else{ 
    $servername = ""; 
} 



//Adds all content that was already gained to the JSON string 
$startingContent = "{\"_id\":\"$servername\", 
        \"ip\":\"$ip\", 
        \"port\":\"$port\", 
        \"running\":\"$running\", 
        \"afk\":\"$afk\", 
        \"gamemode\":\"$gamemode\", 
        \"maxplayers\":\"$maxplayers\", 
        \"spawnprotection\":\"$spawnprotection\", 
        \"whitelist\":\"$whitelist\", 
        \"enablequery\":\"$enablequery\", 
        \"enablercon\":\"$enablercon\", 
        \"rconpassword\":\"$rconpassword\", 
        \"motd\":\"$motd\", 
        \"announceplayerachievements\":\"$achievements\", 
        \"allowflight\":\"$allowflight\", 
        \"spawnanimals\":\"$spawnanimals\", 
        \"spawnmobs\":\"$spawnmobs\", 
        \"forcegamemode\":\"$forcegamemode\", 
        \"hardcore\":\"$hardcore\", 
        \"pvp\":\"$pvp\", 
        \"difficulty\":\"$difficulty\", 
        \"generatorsettings\":\"$generatorsettings\", 
        \"levelname\":\"$levelname\", 
        \"levelseed\":\"$levelseed\", 
        \"leveltype\":\"$leveltype\", 
        \"autosave\":\"$autosave\" 
        }"; 



echo $startingContent."<br/>"; 


//This is the JSON data that will be passed to mongo 

if(strlen($ip)>6){ 
    if (fwrite($file, $startingContent) === FALSE) { 
     echo "Cannot write to file ($filename) with $startingContent"; 
     exit; 
    } 
} 
} 

。その実験の最終結果は、実行されるたびに可変数のレコードが更新された(通常400〜4000の間の一見乱数)。なぜ誰かがこれが起こっているかもしれないという考えを持っていますか?そうでない場合は、私がmySQLからエクスポートできるCSVを反復する独自のプログラムを作成するだけですか?

+2

はあなたがインクリメント 'for'ループに個別' SELECT'文を実行するだけではなく、一度にすべてを照会するための具体的な理由を持っていますか:あなたは、フェッチする結果を持っている場合

これを使用してチェックしますループでフェッチしている間にそれらに作用するのでしょうか?あなたは 'display_errors'を有効にしていますか?あなたのスクリプト 'error_reporting(E_ALL)の先頭に。 ini_set( 'display_errors'、1); 'タイムアウトが発生している場合に備えて。最後に、JSON文字列を手動で構築するのではなく、連想配列で 'json_encode()'を使うことをお勧めします。それらはminecraft paramsのように見えますが、私は単純な文字列であると想定していますが、エスケープされていない引用符のようなものは問題を引き起こす可能性があります。 –

+0

あなたのコードは、 'servertable'のIDシーケンスにギャップがないと想定しているようです。ギャップを残すテーブルから行を削除したことがある場合。 – Barmar

+0

'maintable'のIDは' servertable'のIDと本当に相関していますか? – Barmar

答えて

0

まず、より良いパフォーマンスを得るために、$sql = "SELECT * FROM maintable ORDER BY ID DESC LIMIT 1"; $sql = "SELECT MAX(ID) as ID FROM maintable";に置き換えてください。

ここで問題になるのは、偽を返すクエリがあり、アプリケーションが終了するということです。たとえば、ループがID=3を照会しようとしましたが、このIDを持つデータベースに行がないとします。それから、次の行はあなたが見ていない例外をスローします。あなたはあなたのdevマシンphp.iniにセットdisplay_errors=Onを使うことができます。

.... 
for($var=2; $var <= $ID->ID; $var++){ 
    $sql1 = "SELECT * FROM servertable WHERE ID = '$var'"; 
    $result1 = mysqli_query($conn, $sql1); 

    if($result) { 
     $values = mysqli_fetch_object($result1); 

     $id = $values->ID; 
     $ip = $values->IP; 
     .... 
+0

これはレコードの損失を許しませんか? 2から52,000+までの数のレコードが(保証されて)記録されています。それらのいずれかに偽を返した場合、問題があり、それが完全に停止して理由を把握することができれば好きです。その代わりに、10kレコード近くをスキップしてもただちに進んでいます。 – KM529

+0

停止する必要がある場合は、最後に 'else'を追加して、それを行う方が良いと思うようにしてください。通知を送信し、' die( 'ここにギャップ'を入れてください。少なくとも、私のソリューションを試し、これがあなたの問題であるかどうかを確認してください。 –

関連する問題