2016-05-03 16 views
0

私の現在のプロジェクトでは、毎日1時間ごとにサーバーにpingを実行しています。時間がたつにつれて、これは大量のデータであり、管理者(PHP)は日付を選択してその日の前にすべてのデータを削除したいと思います。MySQL:日付ごとに1つのデータを選択してください

など。選択された日付が2/4/16だった場合、日付の2/4/16より前から1日あたり1レコードを削除します。

問題のデータベーステーブルの構造は次のとおりです。

server_status: 
id int(11) 
server_id int(11) 
time_checked datetime 
status char(1) 

私は、MySQLの文が、私はこれを達成する必要があるだろうかと思った - 私は、Web周りを見て持っていた、と私はそのI見ることができます新しいテーブルを作成し、テーブルを削除して置き換える必要があるかもしれませんが、DBを長時間ブロックするような応答があるようです。それは私が混乱している選択ステートメントの詳細です - 私は前の日付からデータを選択する方法を理解していますが、1)1日1データのみを選択し、2)残りを削除する方法を知らない。

ありがとうございました!

+0

1日に1つのレコードを保存するための要件はありますか? –

+0

どのレコードが(私に与えられた要求に従って)保管されているかは関係ありません。私が知っている限り、その日の最初/最後のレコードと同じくらいシンプルなものかもしれません。 – dplatt

+0

あなたはどのように達成するかは関係ありません。 1つのクエリで削除するか、1つのクエリ以外の各行を選択して削除します。どちらの場合も、削除のたびに遅延が発生するまでテーブルはロックされますが、これはあなたのケースでは実行できません。 –

答えて

0

次のクエリを使用してこれを達成できるはずです。

SET @date_param = '2016-04-02'; 

DELETE FROM server_status WHERE time_checked < @date_param AND id NOT IN (
    SELECT id FROM (
     SELECT MIN(id) AS id 
     FROM server_status 
     WHERE time_checked < @date_param 
     GROUP BY DATE(time_checked) 
    ) AS ids_to_keep 
) 

もちろん、sql変数/パラメータをphp/boundに置き換えることもできます。

サブクエリが特別な選択でラップされる理由は、MySQLではSELECT部分​​で使用するのと同じテーブルを変更できないためです。余分な選択をラップすると、暗黙的な一時テーブルが作成されますが、最も簡単できれいなアプローチです。

+0

代わりに、1日あたり各server_idの1つを保持したいとします(つまり、11台のサーバがあるため、1日にserver_statusテーブルに11のレコードがあります)。 – dplatt

関連する問題