判斷資料庫中記錄是否存在是 Web 開發的高頻操作。本文從歷史代碼重構角度,對比不同時代的實現方式,推薦現代最佳實踐。
<?php
$sql = "select * from checklist where game_id=$gid and task='$task' and status='$status'";
$result = mysql_query($sql);
$row = mysql_fetch_array($result, MYSQL_ASSOC);
if (!mysql_num_rows($result)) {
echo "record doesn't exist~~~~~!!!!!!";
} else {
echo $row['game_id'];
echo $row['task'];
}
?>
嚴重問題:
mysql_* 擴展(PHP 7.0+ 完全移除)SELECT * 浪費頻寬與記憶體<?php
// 建議:建立資料庫連線單例或使用依賴注入
$pdo = new PDO("mysql:host=localhost;dbname=test;charset=utf8mb4", $user, $pass, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false, // 使用真實預處理
]);
function recordExists(PDO $pdo, int $gameId, string $task, string $status): bool {
$sql = "SELECT 1 FROM checklist WHERE game_id = ? AND task = ? AND status = ? LIMIT 1";
$stmt = $pdo->prepare($sql);
$stmt->execute([$gameId, $task, $status]);
return $stmt->fetchColumn() !== false;
}
// 使用示例
if (recordExists($pdo, $gid, $task, $status)) {
// 記錄存在,執行業務邏輯
} else {
// 記錄不存在
}
| 場景 | 推薦寫法 | 說明 |
|---|---|---|
| 僅需判斷存在性 | SELECT 1 ... LIMIT 1 | 避免傳輸完整行數據,極致效能 |
| 後續需使用數據 | SELECT id, col1, col2 ... LIMIT 1 | 按需選列,避免 SELECT * |
| 高併發檢查 | 添加唯一索引 + INSERT IGNORE / ON DUPLICATE KEY | 資料庫層面保證原子性 |
| 大量批量檢查 | WHERE (col1, col2) IN ((?,?),...) | 單次查詢完成批量判斷 |
mysql_num_rows() 或 PDOStatement::rowCount() 可靠fetchColumn() 或 fetch() 判斷COUNT(*) 效能最好EXISTS / LIMIT 1 通常更快,尤其有索引時mysql_* 替換為 PDOPDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTIONcharset=utf8mb4 確保完整 Unicode 支援addslashes() 等轉義代碼採用現代 PDO 寫法不僅修復安全漏洞,更能獲得更好的效能、可維護性與未來相容性。