我正在尝试将 ~55K 记录从 mySQL 服务器迁移到 MongoDB。我无法通过任何易于访问的方法(例如 JSON/CSV 导入)来执行此操作,因为数据存储方法(其结构方式)将非常不同。因此,我在 php 中创建了一个脚本来执行此操作。
我遇到的问题是,在大型数据集上(即使较小的数据集包含问题条目,也无法使用较小的数据集重现),尽管条目存在,但查询偶尔会报告没有数据。它绝对存在,因为当 php 直接访问该特定条目或它包含在较小的数据集中时,它工作得很好。例如,在导入文本文件时,我只收到~42k/54k 记录。
在我通过调用 php 文件的 url 收到的回显中,我显示该查询被调用了正确的次数,但有许多记录显示为不存在,因此应答回显是空白的。代码如下:
//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;
}
}
}
我还尝试过一个查询,该查询将大量(全部、一半、四分之一等)结果提取到一个 block 中,而不是大量的单独查询。该实验的最终结果是,每次运行时都会更新可变数量的记录(通常是 400 到 4000 之间看似随机的数字)。有谁知道为什么会发生这种情况?如果没有,我是否应该编写自己的程序来迭代可以从 mySQL 导出的 CSV?
最佳答案
首先,替换您的查询$sql = "SELECT * FROM maintable ORDER BY ID DESC LIMIT 1";
使用此 $sql = "SELECT MAX(ID) as ID FROM maintable";
以获得更好的性能。
这里的问题是,您可能有一个返回 false 的查询,然后您的应用程序就会终止。例如,假设您的循环尝试查询 ID=3
,但数据库中没有具有此 ID 的行。然后下一行抛出一个您没有看到的异常。您可以在您的开发机器 php.ini
中使用 set 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;
....
关于php - 为什么 PHP 中的 mySQL 返回空结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37573895/