MySQL 的 `DELETE` 語句用于從數據庫表中刪除記錄。這是一項非常強大且**危險**的操作,因為一旦執行,數據通常無法恢復。理解其語法和安全實踐至關重要。
`DELETE` 語句用于刪除表中的一行或多行記錄。
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROM table_name
* **`DELETE FROM table_name`**: 指定要從哪個表刪除數據。
* **`WHERE`**: **極其重要!** 指定哪些記錄需要被刪除。**如果省略 `WHERE` 子句,將刪除表中的所有記錄!**
* **`ORDER BY`**: 與 `LIMIT` 配合使用,指定先按什么順序排序,再刪除。
* **`LIMIT`**: 限制要刪除的記錄數量。
| id | username | email | status |
| :--- | :--- | :--- | :--- |
| 1 | alice | alice@example.com | inactive |
| 2 | bob | bob@example.com | active |
| 3 | charlie | charlie@example.com | inactive |
| 4 | david | david@example.com | active |
WHERE username = 'charlie';
**最佳實踐**:盡量使用唯一性強的條件(如主鍵 `id`)來精準定位要刪除的行,避免誤刪。
**警告**:這條語句會清空整個表,但表結構(列、索引等)依然存在。執行前必須**萬分謹慎**。
刪除最早注冊的 1 個狀態為 `inactive` 的用戶。
WHERE status = 'inactive'
ORDER BY id ASC -- 按ID升序(假設ID越小注冊越早)
三、 清空表:DELETE vs TRUNCATE
除了 `DELETE`,MySQL 還提供了 `TRUNCATE TABLE` 語句來清空整個表。兩者有重要區別:
| 特性 | `DELETE` | `TRUNCATE TABLE` |
| **本質** | DML**操作**(數據操作語言) | DDL**操作**(數據定義語言) |
| **速度** | **較慢**。逐行刪除,并在事務日志中記錄每一行。 | **極快**。直接釋放存儲表數據的數據頁。 |
| **事務** | 支持。刪除操作可以被 **`ROLLBACK`** 回滾。 | 在大多數情況下(取決于存儲引擎),**無法回滾**。 |
| **自增列** | 不會重置自增計數器(AUTO_INCREMENT)。下次插入的ID會繼續增長。 | **會重置**自增計數器為初始值。下次插入的ID從 1 開始。 |
| **WHERE 條件** | **支持**使用 `WHERE` 條件刪除部分數據。 | **不支持**任何條件,只能清空整個表。 |
* 需要**刪除特定記錄**時,必須使用 `DELETE ... WHERE ...`。
* 需要**快速清空整個表**且不需要回滾時,使用 `TRUNCATE TABLE`。
* 需要清空整個表但**可能需要回滾**時,使用 `DELETE FROM table_name`。
TRUNCATE [TABLE] table_name;
四、 多表刪除 (DELETE with JOIN)
你可以使用 `JOIN` 語法基于另一個表的條件來刪除本表的數據。這在處理有關聯的表時非常有用。
**語法 1 (使用 DELETE ... JOIN):**
JOIN table2 t2 ON t1.id = t2.foreign_key_id
WHERE id IN (SELECT foreign_key_id FROM table2 WHERE some_condition);
假設還有一個 `orders` 表,存儲用戶的訂單,F在要刪除所有從未下過訂單的用戶。
-- 方法 1: 使用 LEFT JOIN 找到不存在的關聯
LEFT JOIN orders o ON u.id = o.user_id
WHERE id NOT IN (SELECT DISTINCT user_id FROM orders);
1. **備份先行 (Backup First)**
在執行任何刪除操作,尤其是會影響大量數據的操作之前,務必進行數據備份。
mysqldump -u username -p database_name table_name > backup.sql
這是一個**黃金法則**。先用 `SELECT` 語句驗證 `WHERE` 條件是否正確匹配到了你**想要刪除**的數據。
SELECT * FROM users WHERE status = 'inactive';
-- 2. 確認結果無誤后,將 SELECT * 替換為 DELETE
DELETE FROM users WHERE status = 'inactive';
3. **使用事務 (Transaction)**
對于重要的刪除操作,最好在事務中執行。這樣如果發生錯誤,你可以回滾整個操作。
START TRANSACTION; -- 開始事務
DELETE FROM orders WHERE date < '2020-01-01';
DELETE FROM users WHERE status = 'expired';
SELECT * FROM users WHERE ...;
ROLLBACK; -- 如果發現刪錯了,回滾,所有刪除操作取消
-- COMMIT; -- 如果確認無誤,提交事務,使刪除生效
在生產數據庫中,嚴格限制擁有 `DELETE` 權限的用戶數量。永遠不要給應用程序賬戶過高的權限。
另外搭配便捷的MYSQL備份工具,可定時備份、異地備份,MYSQL導出導入?杀镜剡B接LINUX里的MYSQL,簡單便捷?梢源蟠蟮靥岣吖ぷ餍枢浮