← Назад к вопросам

Как удалить элемент из БД?

1.0 Junior🔥 241 комментариев
#Базы данных и SQL

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Удаление элементов из базы данных: полный гайд

Удаление данных — критическая операция в работе с БД. Нужно учитывать целостность данных, транзакции, каскадные удаления и логирование.

Базовое удаление

Простой DELETE запрос:

const pool = require("./db");

async function deleteCarById(carId) {
  const query = "DELETE FROM cars WHERE id = $1";
  const result = await pool.query(query, [carId]);
  return result.rowCount;
}

Удаление с проверкой существования

Безопасное удаление с валидацией:

async function safeDeleteCar(carId) {
  const client = await pool.connect();
  
  try {
    await client.query("BEGIN");
    
    const checkResult = await client.query(
      "SELECT id FROM cars WHERE id = $1 FOR UPDATE",
      [carId]
    );
    
    if (checkResult.rows.length === 0) {
      throw new Error(`Автомобиль с ID ${carId} не найден`);
    }
    
    const deleteResult = await client.query(
      "DELETE FROM cars WHERE id = $1",
      [carId]
    );
    
    await client.query("COMMIT");
    return { success: true, deletedRows: deleteResult.rowCount };
  } catch (error) {
    await client.query("ROLLBACK");
    throw error;
  } finally {
    client.release();
  }
}

Каскадное удаление

Удаление с зависимостями:

CREATE TABLE cars (
  id SERIAL PRIMARY KEY,
  owner_id INT NOT NULL,
  FOREIGN KEY (owner_id) REFERENCES owners(id) ON DELETE CASCADE
);

DELETE FROM owners WHERE id = $1;

В коде:

async function deleteOwnerWithCars(ownerId) {
  const client = await pool.connect();
  
  try {
    await client.query("BEGIN");
    await client.query("DELETE FROM cars WHERE owner_id = $1", [ownerId]);
    const result = await client.query("DELETE FROM owners WHERE id = $1", [ownerId]);
    await client.query("COMMIT");
    return result.rowCount;
  } catch (error) {
    await client.query("ROLLBACK");
    throw error;
  } finally {
    client.release();
  }
}

Мягкое удаление (Soft Delete)

Часто вместо физического удаления используют флаг:

CREATE TABLE cars (
  id SERIAL PRIMARY KEY,
  model VARCHAR(100),
  deleted_at TIMESTAMP NULL
);
async function softDeleteCar(carId) {
  const query = "UPDATE cars SET deleted_at = NOW() WHERE id = $1";
  await pool.query(query, [carId]);
}

async function getActiveCars() {
  const query = "SELECT * FROM cars WHERE deleted_at IS NULL";
  return pool.query(query);
}

async function restoreCar(carId) {
  const query = "UPDATE cars SET deleted_at = NULL WHERE id = $1";
  await pool.query(query, [carId]);
}

Пакетное удаление

Удаление нескольких элементов эффективно:

async function deleteCarsByIds(carIds) {
  if (carIds.length === 0) return 0;
  
  const placeholders = carIds.map((_, i) => `$${i + 1}`).join(",");
  const query = `DELETE FROM cars WHERE id IN (${placeholders})`;
  const result = await pool.query(query, carIds);
  return result.rowCount;
}

Логирование удалений

Важно логировать критические операции:

async function deleteCarWithAudit(carId, userId) {
  const client = await pool.connect();
  
  try {
    await client.query("BEGIN");
    
    const carResult = await client.query(
      "SELECT * FROM cars WHERE id = $1",
      [carId]
    );
    
    if (carResult.rows.length === 0) {
      throw new Error("Машина не найдена");
    }
    
    const car = carResult.rows[0];
    
    await client.query(
      "INSERT INTO audit_log (action, entity_type, entity_id, old_data, user_id, created_at) VALUES ($1, $2, $3, $4, $5, NOW())",
      ["DELETE", "cars", carId, JSON.stringify(car), userId]
    );
    
    await client.query("DELETE FROM cars WHERE id = $1", [carId]);
    await client.query("COMMIT");
  } catch (error) {
    await client.query("ROLLBACK");
    throw error;
  } finally {
    client.release();
  }
}

Лучшие практики

  • Используй транзакции для сложных удалений
  • Проверяй существование перед удалением
  • Рассмотри мягкое удаление для критичных данных
  • Логируй удаления для аудита
  • Настрой CASCADE/RESTRICT правильно в констрейнтах
  • Используй FOR UPDATE при конкурентном доступе

Правильное удаление — это не просто DELETE, а целая стратегия безопасности данных.

Как удалить элемент из БД? | PrepBro