truncate->これはテーブル全体をリセットします。truncateを介して特定のレコード/チェック条件をリセットする方法があります。
例:すべてのデータをリセットし、過去30日間をテーブル内に保持します。
ありがとう。
いいえ、TRUNCATE
はすべてまたはゼロです。 DELETE FROM <table> WHERE <conditions>
しかし、これはTRUNCATE
の速度の利点を失います。
簡単な答えはno:MySQLはnotを使用してWHERE
句をTRUNCATE
ステートメントに追加できます。 TRUNCATE
ステートメントに関する MySQLのドキュメント は次のとおりです。
しかし、良いニュースは、この制限を(ある程度)回避できることです。
DELETE
を使用した、シンプルで安全、クリーンだが遅いソリューション
まず、テーブルが十分に小さい場合は、単にDELETE
ステートメントを使用します(言及する必要がありました)。
1. LOCK TABLE my_table WRITE;
2. DELETE FROM my_table WHERE my_date<DATE_SUB(NOW(), INTERVAL 1 MONTH);
3. UNLOCK TABLES;
LOCK
およびUNLOCK
ステートメントは必須ではありませんが、速度を上げ、潜在的なデッドロックを回避します。
残念ながら、テーブルが大きい場合、これは非常に遅くなります。また、TRUNCATE
ステートメントの使用を検討しているので、テーブルが大きいためだと思います。
そこで、TRUNCATE
ステートメントを使用して問題を解決する1つの方法を次に示します。
TRUNCATE
を使用した、シンプルで高速、しかし安全でないソリューション
1. CREATE TABLE my_table_backup AS
SELECT * FROM my_table WHERE my_date>=DATE_SUB(NOW(), INTERVAL 1 MONTH);
2. TRUNCATE my_table;
3. LOCK TABLE my_table WRITE, my_table_backup WRITE;
4. INSERT INTO my_table SELECT * FROM my_table_backup;
5. UNLOCK TABLES;
6. DROP TABLE my_table_backup;
残念ながら、他のプロセスが同時にテーブルにレコードを挿入している場合、このソリューションは少し安全ではありません。
TRUNCATE
ステートメントは、AUTO-INCREMENT
カウンターをゼロにリセットします。したがって、ステップ2と3の間に挿入されたレコードは、古いIDよりも低いIDを持ち、ステップ4で挿入されたIDと競合することさえあります(AUTO-INCREMENT
カウンターは、ステップ後に適切な値に戻ります4)。残念ながら、テーブルをロックして切り捨てることはできません。しかし、(とにかく)thatRENAME
を使用して制限を回避できます。
TRUNCATE
を使用した半単純、高速、安全ですがノイズの多いソリューション
1. RENAME TABLE my_table TO my_table_work;
2. CREATE TABLE my_table_backup AS
SELECT * FROM my_table_work WHERE my_date>DATE_SUB(NOW(), INTERVAL 1 MONTH);
3. TRUNCATE my_table_work;
4. LOCK TABLE my_table_work WRITE, my_table_backup WRITE;
5. INSERT INTO my_table_work SELECT * FROM my_table_backup;
6. UNLOCK TABLES;
7. RENAME TABLE my_table_work TO my_table;
8. DROP TABLE my_table_backup;
これは完全に安全で非常に高速でなければなりません。唯一の問題は、他のプロセスがテーブルmy_table
を数秒間表示しないことです。これにより、どこでもログにエラーが表示される可能性があります。したがって、これは安全なソリューションですが、「うるさい」です。
免責事項:私はMySQLの専門家ではないので、これらのソリューションは実際には安っぽいかもしれません。私が提供できる唯一の保証は、彼らが私のためにうまく働くということです。これらのソリューションについて専門家がコメントできる場合は、感謝します。
あなたの質問への回答として:「すべてのデータをリセットし、過去30日間をテーブル内に保持したい」
イベントを作成できます。チェック https://dev.mysql.com/doc/refman/5.7/en/event-scheduler.html
例えば:
CREATE EVENT DeleteExpiredLog
ON SCHEDULE EVERY 1 DAY
DO
DELETE FROM log WHERE date < DATE_SUB(NOW(), INTERVAL 30 DAY);
テーブルで毎日クリーンアップを実行し、過去30日間のデータを利用可能にします
Datapumpを使用してクエリ句でテーブルをエクスポートし、table_exists_action = replace句でインポートして戻すことができます。テーブルが削除されてテーブルが再作成され、時間がかかりません。実装する前にそれについて読んでください。