Skip to content

12.6 删除数据 delete

DELETE 语句基础

DELETE 语句用于从数据库表中删除记录,是数据库操作中常用的操作之一。

基本语法

sql
DELETE FROM table_name WHERE condition;

基本删除

1. 删除单条记录

php
<?php
require_once 'db.php';
$conn = getDbConnection();

// 删除单条记录
$sql = "DELETE FROM users WHERE id = 5";

if ($conn->query($sql) === TRUE) {
    echo "记录删除成功,影响行数: " . $conn->affected_rows;
} else {
    echo "删除失败: " . $conn->error;
}

$conn->close();
?>

2. 删除多条记录

php
<?php
require_once 'db.php';
$conn = getDbConnection();

// 删除多条记录
$sql = "DELETE FROM users WHERE age < 18";

if ($conn->query($sql) === TRUE) {
    echo "记录删除成功,影响行数: " . $conn->affected_rows;
} else {
    echo "删除失败: " . $conn->error;
}

$conn->close();
?>

3. 删除所有记录

php
<?php
require_once 'db.php';
$conn = getDbConnection();

// 删除所有记录(谨慎使用)
$sql = "DELETE FROM users";

if ($conn->query($sql) === TRUE) {
    echo "所有记录删除成功,影响行数: " . $conn->affected_rows;
} else {
    echo "删除失败: " . $conn->error;
}

$conn->close();
?>

使用预处理语句

预处理语句可以防止 SQL 注入攻击,同时提高执行效率。

1. 删除单条记录

php
<?php
require_once 'db.php';
$conn = getDbConnection();

// 准备语句
$stmt = $conn->prepare("DELETE FROM users WHERE id = ?");
$stmt->bind_param("i", $id);

// 设置参数并执行
$id = 6;

if ($stmt->execute()) {
    echo "记录删除成功,影响行数: " . $stmt->affected_rows;
} else {
    echo "删除失败: " . $stmt->error;
}

$stmt->close();
$conn->close();
?>

2. 批量删除

php
<?php
require_once 'db.php';
$conn = getDbConnection();

// 准备语句
$stmt = $conn->prepare("DELETE FROM users WHERE id = ?");
$stmt->bind_param("i", $id);

// 要删除的ID列表
$ids = [7, 8, 9];

// 执行多次删除
$successCount = 0;
foreach ($ids as $id) {
    if ($stmt->execute()) {
        $successCount++;
    }
}

echo "成功删除 $successCount 条记录";

$stmt->close();
$conn->close();
?>

删除数据与表单结合

1. 基本删除功能

php
<?php
require_once 'db.php';
$conn = getDbConnection();

$success = false;
$error = '';

if (isset($_GET['id'])) {
    $id = (int)$_GET['id'];
    
    // 准备语句
    $stmt = $conn->prepare("DELETE FROM users WHERE id = ?");
    $stmt->bind_param("i", $id);
    
    if ($stmt->execute()) {
        $success = true;
    } else {
        $error = '删除失败: ' . $stmt->error;
    }
    
    $stmt->close();
}

$conn->close();
?>

<!DOCTYPE html>
<html>
<head>
    <title>删除用户</title>
    <style>
        body { font-family: Arial, sans-serif; max-width: 400px; margin: 0 auto; padding: 20px; }
        .error { color: red; }
        .success { color: green; }
        .confirm { background-color: #f9f9f9; padding: 20px; border: 1px solid #ddd; border-radius: 5px; }
        .button { padding: 10px 20px; margin: 5px; text-decoration: none; border-radius: 4px; }
        .delete { background-color: #f44336; color: white; }
        .cancel { background-color: #9e9e9e; color: white; }
    </style>
</head>
<body>
    <h2>删除用户</h2>
    
    <?php if ($error): ?>
        <div class="error">
            <?php echo $error; ?>
        </div>
    <?php endif; ?>
    
    <?php if ($success): ?>
        <div class="success">
            用户删除成功!
        </div>
        <a href="user_list.php" class="button cancel">返回用户列表</a>
    <?php else: ?>
        <div class="confirm">
            <p>确定要删除这个用户吗?此操作不可恢复。</p>
            <a href="?id=<?php echo $_GET['id']; ?>" class="button delete">确认删除</a>
            <a href="user_list.php" class="button cancel">取消</a>
        </div>
    <?php endif; ?>
</body>
</html>

删除数据时的注意事项

1. WHERE 子句

非常重要:如果省略 WHERE 子句,DELETE 语句将删除表中的所有记录!

php
// 危险!会删除所有记录
$sql = "DELETE FROM users";

// 安全:只删除指定记录
$sql = "DELETE FROM users WHERE id = 1";

2. 外键约束

如果表之间存在外键关系,删除记录时需要考虑外键约束:

  • CASCADE:删除主表记录时,自动删除从表相关记录
  • SET NULL:删除主表记录时,将从表相关字段设为 NULL
  • RESTRICT:如果存在从表相关记录,不允许删除主表记录
  • NO ACTION:同 RESTRICT

3. 事务处理

对于需要删除多条相关记录的情况,使用事务确保数据一致性:

php
<?php
require_once 'db.php';
$conn = getDbConnection();

// 开始事务
$conn->begin_transaction();

try {
    $userId = 10;
    
    // 删除用户的订单
    $stmt = $conn->prepare("DELETE FROM orders WHERE user_id = ?");
    $stmt->bind_param("i", $userId);
    $stmt->execute();
    
    // 删除用户的资料
    $stmt = $conn->prepare("DELETE FROM user_profiles WHERE user_id = ?");
    $stmt->bind_param("i", $userId);
    $stmt->execute();
    
    // 删除用户
    $stmt = $conn->prepare("DELETE FROM users WHERE id = ?");
    $stmt->bind_param("i", $userId);
    $stmt->execute();
    
    // 提交事务
    $conn->commit();
    echo "用户及相关数据删除成功";
} catch (mysqli_sql_exception $e) {
    // 回滚事务
    $conn->rollback();
    echo "删除失败: " . $e->getMessage();
}

$stmt->close();
$conn->close();
?>

4. 性能考虑

  • 批量删除:对于大量数据,使用批量删除比逐条删除更高效
  • 索引:确保 WHERE 子句中的字段有索引,提高删除速度
  • 限制删除:使用 LIMIT 子句限制删除的记录数
php
// 限制删除10条记录
$sql = "DELETE FROM users WHERE age < 18 LIMIT 10";

软删除

在实际应用中,通常不直接删除数据,而是使用软删除(标记删除):

1. 添加删除标记字段

sql
ALTER TABLE users ADD COLUMN deleted_at TIMESTAMP NULL;

2. 软删除实现

php
<?php
require_once 'db.php';
$conn = getDbConnection();

// 软删除
$id = 11;
$stmt = $conn->prepare("UPDATE users SET deleted_at = NOW() WHERE id = ?");
$stmt->bind_param("i", $id);

if ($stmt->execute()) {
    echo "用户软删除成功";
} else {
    echo "删除失败: " . $stmt->error;
}

$stmt->close();
$conn->close();
?>

3. 查询未删除的记录

php
<?php
require_once 'db.php';
$conn = getDbConnection();

// 查询未删除的记录
$sql = "SELECT * FROM users WHERE deleted_at IS NULL";
$result = $conn->query($sql);

if ($result->num_rows > 0) {
    while ($row = $result->fetch_assoc()) {
        echo "id: " . $row["id"] . " - 用户名: " . $row["username"] . "<br>";
    }
} else {
    echo "0 结果";
}

$result->free();
$conn->close();
?>

最佳实践

  1. 使用 WHERE 子句:始终指定 WHERE 子句,避免删除所有记录
  2. 使用预处理语句:防止 SQL 注入攻击
  3. 事务处理:对于相关操作使用事务
  4. 软删除:考虑使用软删除替代物理删除
  5. 备份:在删除重要数据前进行备份
  6. 权限控制:限制删除操作的权限
  7. 确认机制:在删除前添加确认步骤
  8. 日志记录:记录删除操作的日志

练习

  1. 删除单条用户记录
  2. 删除多条用户记录
  3. 使用预处理语句删除数据
  4. 实现软删除功能
  5. 使用事务删除相关数据
  6. 实现带确认的删除功能

© 2026 编程马·菜鸟教程 版权所有