← Назад к вопросам
Как избавиться от ненужных данных в БД
2.3 Middle🔥 111 комментариев
#Базы данных и SQL
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Очистка ненужных данных из БД
Это важная часть операционной работы с базами данных. Есть несколько подходов в зависимости от объёма и критичности данных.
1. DELETE с условиями
Для небольших объёмов данных используй простой DELETE:
// JDBC подход
public void deleteOldRecords(Connection conn, int daysOld) throws SQLException {
String sql = "DELETE FROM events WHERE created_at < DATE_SUB(NOW(), INTERVAL ? DAY)";
try (PreparedStatement stmt = conn.prepareStatement(sql)) {
stmt.setInt(1, daysOld);
int deleted = stmt.executeUpdate();
System.out.println("Удалено записей: " + deleted);
}
}
2. Пакетное удаление для больших объёмов
Для миллионов записей удаляй партиями, чтобы не заблокировать БД:
public void batchDeleteOldData(DataSource ds, int batchSize) throws SQLException {
String selectSql = "SELECT id FROM events WHERE created_at < DATE_SUB(NOW(), INTERVAL 90 DAY) LIMIT ?";
String deleteSql = "DELETE FROM events WHERE id = ?";
try (Connection conn = ds.getConnection()) {
boolean hasMore = true;
while (hasMore) {
try (PreparedStatement stmt = conn.prepareStatement(selectSql)) {
stmt.setInt(1, batchSize);
List<Long> ids = new ArrayList<>();
try (ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
ids.add(rs.getLong("id"));
}
}
if (ids.isEmpty()) {
hasMore = false;
} else {
try (PreparedStatement delStmt = conn.prepareStatement(deleteSql)) {
for (Long id : ids) {
delStmt.setLong(1, id);
delStmt.addBatch();
}
delStmt.executeBatch();
System.out.println("Удалено " + ids.size() + " записей");
}
}
}
}
}
}
3. Архивирование перед удалением
Для исторических данных сначала архивируй, потом удаляй:
public void archiveAndDelete(DataSource ds, LocalDateTime before) throws SQLException {
try (Connection conn = ds.getConnection()) {
// Архивируем
String archiveSql = "INSERT INTO events_archive SELECT * FROM events WHERE created_at < ?";
try (PreparedStatement stmt = conn.prepareStatement(archiveSql)) {
stmt.setTimestamp(1, Timestamp.valueOf(before));
stmt.executeUpdate();
}
// Удаляем из основной таблицы
String deleteSql = "DELETE FROM events WHERE created_at < ?";
try (PreparedStatement stmt = conn.prepareStatement(deleteSql)) {
stmt.setTimestamp(1, Timestamp.valueOf(before));
int deleted = stmt.executeUpdate();
System.out.println("Удалено " + deleted + " записей");
}
}
}
4. Использование TRUNCATE для полной очистки
Если нужно очистить всю таблицу целиком:
public void truncateTable(DataSource ds, String tableName) throws SQLException {
try (Connection conn = ds.getConnection()) {
try (Statement stmt = conn.createStatement()) {
stmt.execute("TRUNCATE TABLE " + tableName);
System.out.println("Таблица " + tableName + " очищена");
}
}
}
Важные моменты:
- Индексы: DELETE быстрее работает на индексированных полях
- Locks: Большие DELETE блокируют таблицу — используй партии
- Backup: Всегда делай бэкап перед массовым удалением
- FOREIGN_KEY: Учти constraint'ы при удалении
- Логирование: Записывай что и сколько удалил
- Транзакции: Оборачивай операции в транзакции для консистентности
Это стандартный подход в production-системах для управления жизненным циклом данных.