萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 網路程式設計 >> PHP 程式設計

PHP 定期清理 MySQL 只保留最新 N 筆資料:按 ID 降序刪除舊記錄

資料表持續寫入(如日誌、訊息),需定期只保留最新 1000 筆。以主鍵 id 降序為基準,刪除超出限制的舊記錄。

核心邏輯

  1. 查詢總筆數 $num
  2. 若 $num > $limit,查詢第 $limit 筆的 id(即最舊的保留記錄)
  3. 刪除 id < $threshold_id 的所有記錄

完整程式碼

<?php
mysql_connect("localhost", "root", "root");
mysql_select_db("test");

$limit = 1000;

// 取得總筆數
$query = "SELECT `id` FROM `news`";
$result = mysql_query($query);
$num = mysql_num_rows($result);

if ($num > $limit) {
    // 取得第 $limit 筆(最舊保留)的 id
    $query = "SELECT `id` FROM `news` ORDER BY `id` DESC LIMIT " . $limit;
    $result = mysql_query($query);
    mysql_data_seek($result, $limit - 1); // 移至最後一行(第 1000 筆)
    $row = mysql_fetch_array($result);
    $threshold_id = $row['id'];
    
    // 刪除比此 id 更小(更舊)的記錄
    $query = "DELETE FROM `news` WHERE `id` < '$threshold_id'";
    if (mysql_query($query)) {
        $deleted = $num - $limit;
        echo "原有 {$num} 筆,刪除 {$deleted} 筆,保留 {$limit} 筆。";
    }
} else {
    echo "資料不足 {$limit} 筆,無需刪除。";
}
?>

資料表結構

CREATE TABLE IF NOT EXISTS `news` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `title` varchar(256) NOT NULL,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=gb2312;

效能與安全優化

問題解決方案
大表 COUNT(*) 慢維護計數表、資訊_schema、觸發器更新計數、或估算值
LIMIT offset 大時效能差用 WHERE id < (SELECT id FROM news ORDER BY id DESC LIMIT 1 OFFSET 999) 子查詢
DELETE 大量資料鎖表久分批刪除:DELETE ... WHERE id < ? LIMIT 500 迴圈
自增 ID 耗盡用 BIGINT、定期重組、或 UUID/雪花演算法
SQL 注入風險使用參數化查詢(PDO/mysqli prepared statements)

現代化重寫

<?php
$pdo = new PDO("mysql:host=localhost;dbname=test;charset=utf8mb4", "root", "root");
$limit = 1000;

$stmt = $pdo->query("SELECT COUNT(*) FROM `news`");
$num = $stmt->fetchColumn();

if ($num > $limit) {
    $stmt = $pdo->query("SELECT `id` FROM `news` ORDER BY `id` DESC LIMIT 1 OFFSET " . ($limit - 1));
    $threshold = $stmt->fetchColumn();
    
    $deleted = $pdo->exec("DELETE FROM `news` WHERE `id` < ?", [$threshold]);
    echo "原有 {$num} 筆,刪除 {$deleted} 筆,保留 {$limit} 筆。";
} else {
    echo "資料不足 {$limit} 筆,無需刪除。";
}

排程部署

# crontab -e
# 每天凌晨 3 點執行
0 3 * * * /usr/bin/php /var/www/scripts/cleanup_news.php >> /var/log/cleanup_news.log 2>&1

定期清理舊資料能控制資料表體積、維持查詢效能、降低備份成本,是高寫入系統的必要維護任務。

copyright © 萬盛學電腦網 all rights reserved