MySQL?實戰(zhàn)入門從"增刪改查"到"高效查詢"的操作
在數(shù)據(jù)驅(qū)動的時代,MySQL 作為全球最流行的開源關系型數(shù)據(jù)庫,是每一位后端開發(fā)者、數(shù)據(jù)分析師乃至全棧工程師的必修課。無論你的架構多么宏大,微服務多么復雜,最終數(shù)據(jù)的落地往往都回歸到最基礎的 CRUD(Create, Read, Update, Delete)操作。
很多初學者只會寫 SELECT *,卻在面對百萬級數(shù)據(jù)時束手無策;或者在更新數(shù)據(jù)時因忘記加 WHERE 條件而釀成“刪庫跑路”的慘劇。本文將帶你系統(tǒng)梳理 MySQL 的核心操作,不僅教你“怎么寫”,更教你“怎么寫得安全、高效”。
一、基石:數(shù)據(jù)的“增刪改查” (CRUD)
1.1 增 (Create):不僅僅是插入
插入數(shù)據(jù)看似簡單,但處理批量插入和默認值才是實戰(zhàn)關鍵。
單條插入:
INSERT INTO users (username, email, age, created_at)
VALUES ('alice', 'alice@example.com', 25, NOW());
批量插入(性能關鍵) : 不要在循環(huán)中執(zhí)行單條 INSERT!一次性插入多條數(shù)據(jù)能減少網(wǎng)絡交互和事務開銷,性能提升數(shù)倍。
INSERT INTO users (username, email, age, created_at)
VALUES
('bob', 'bob@example.com', 30, NOW()),
('charlie', 'charlie@example.com', 28, NOW()),
('david', 'david@example.com', 22, NOW());
忽略或更新: 如果主鍵沖突怎么辦?
INSERT INTO visits (ip, count) VALUES ('192.168.1.1', 1)
ON DUPLICATE KEY UPDATE count = count + 1;
INSERT IGNORE: 沖突則直接忽略,不報錯。ON DUPLICATE KEY UPDATE: 沖突則執(zhí)行更新操作(常用于統(tǒng)計計數(shù))。
1.2 刪 (Delete):高危操作,慎之又慎
鐵律:執(zhí)行 DELETE 前,必須先執(zhí)行對應的 SELECT 確認范圍!
條件刪除:
-- 先確認:SELECT * FROM users WHERE age < 18 AND status = 'inactive'; DELETE FROM users WHERE age < 18 AND status = 'inactive';
邏輯刪除 vs 物理刪除: 在生產(chǎn)環(huán)境中,嚴禁輕易使用物理刪除(DELETE)。通常會在表中增加 is_deleted 或 deleted_at 字段。
做法:UPDATE users SET is_deleted = 1, deleted_at = NOW() WHERE id = 100;
好處:數(shù)據(jù)可恢復,便于審計,避免外鍵約束報錯。
清空表: 如果要清空整張表,用 TRUNCATE TABLE users; 比 DELETE FROM users; 更快,且重置自增 ID,但它無法回滾(取決于事務隔離級別),且不會觸發(fā)刪除觸發(fā)器。
1.3 改 (Update):精準打擊
更新操作同樣需要 WHERE 條件的保護。
單字段與多字段更新:
UPDATE users SET age = 26, last_login = NOW() WHERE username = 'alice';
基于計算的更新:
-- 所有用戶積分加 10 UPDATE users SET score = score + 10;
多表關聯(lián)更新(MySQL 特色):
UPDATE users u JOIN orders o ON u.id = o.user_id SET u.vip_level = 'gold' WHERE o.total_amount > 10000;
1.4 查 (Select):靈魂所在
查詢是數(shù)據(jù)庫最高頻的操作,也是優(yōu)化空間最大的部分。
基礎查詢:
SELECT id, username, email FROM users WHERE age > 18 ORDER BY created_at DESC LIMIT 10;
模糊查詢:
-- 查找名字包含 "li" 的用戶 SELECT * FROM users WHERE username LIKE '%li%'; -- 注意:前綴通配符 '%li' 會導致索引失效,性能較差
去重與統(tǒng)計:
SELECT DISTINCT city FROM users; -- 去重 SELECT COUNT(*), AVG(age) FROM users; -- 聚合統(tǒng)計
二、進階:常用語句與核心功能
掌握了 CRUD 只是第一步,真正讓 MySQL 發(fā)揮威力的是以下高級特性。
2.1 多表連接 (JOIN)
關系型數(shù)據(jù)庫的核心在于“關系”。
INNER JOIN:只返回兩個表中匹配的行(交集)。
SELECT u.username, o.order_no FROM users u INNER JOIN orders o ON u.id = o.user_id;
LEFT JOIN:返回左表所有行,右表沒有匹配的填 NULL(常用于查“未下單的用戶”)。
SELECT u.username, o.order_no FROM users u LEFT JOIN orders o ON u.id = o.user_id WHERE o.order_no IS NULL; -- 找出從未下過單的用戶
2.2 分組與過濾 (GROUP BY & HAVING)
GROUP BY:將數(shù)據(jù)按某列分組。
HAVING:對分組后的結果進行過濾(WHERE 無法用于聚合函數(shù))。
-- 統(tǒng)計每個城市的用戶數(shù),只顯示超過 100 人的城市 SELECT city, COUNT(*) as user_count FROM users GROUP BY city HAVING user_count > 100 ORDER BY user_count DESC;
2.3 子查詢 (Subquery)
在查詢中嵌套查詢。雖然靈活,但性能通常不如 JOIN,需謹慎使用。
-- 查找訂單金額大于平均訂單金額的訂單 SELECT * FROM orders WHERE amount > (SELECT AVG(amount) FROM orders);
2.4 事務控制 (Transaction)
涉及金錢、庫存等關鍵業(yè)務,必須保證原子性(ACID)。
START TRANSACTION; -- 1. 扣減庫存 UPDATE products SET stock = stock - 1 WHERE id = 101; -- 2. 創(chuàng)建訂單 INSERT INTO orders (product_id, user_id) VALUES (101, 55); -- 檢查是否有錯誤,如果有則回滾,否則提交 -- ROLLBACK; COMMIT;
2.5 索引管理 (Index)
索引是查詢速度的加速器,但會拖慢寫入速度。
創(chuàng)建索引:
CREATE INDEX idx_username ON users(username); CREATE UNIQUE INDEX idx_email ON users(email); -- 唯一索引,防止重復
查看執(zhí)行計劃(優(yōu)化必做): 在 SQL 前加 EXPLAIN,查看是否用到了索引 (type: ref 或 range 為佳,ALL 為全表掃描,需優(yōu)化)。
EXPLAIN SELECT * FROM users WHERE username = 'alice';
三、避坑指南與最佳實踐
- 拒絕
SELECT *:- 原因:網(wǎng)絡傳輸浪費、無法利用覆蓋索引、表結構變更可能導致代碼出錯。
- 做法:明確列出需要的字段
SELECT id, name, ...。
- 小心
NULL值:NULL不等于0或空字符串。在計算和判斷時要格外小心(如COUNT(column)不統(tǒng)計 NULL 值,而COUNT(*)統(tǒng)計)。- 建議在建表時盡量設置
NOT NULL并給默認值。
- 分頁優(yōu)化的陷阱:
-- 推薦:利用主鍵索引 SELECT * FROM users WHERE id > 100000 LIMIT 10;
- 深分頁(
LIMIT 100000, 10)非常慢,因為 MySQL 要掃描前 100000 條然后丟棄。 - 優(yōu)化:使用“游標法”或“延遲關聯(lián)”。
- 字符集選擇:
- 現(xiàn)在統(tǒng)一推薦使用
utf8mb4,因為它支持 Emoji 表情等特殊字符,而舊的utf8在 MySQL 中實際上是utf8mb3,不支持 Emoji。
- 現(xiàn)在統(tǒng)一推薦使用
- SQL 注入防御:
- 永遠不要拼接用戶輸入到 SQL 字符串中。
- 必須使用預編譯語句(Prepared Statements),如在 Java 中使用
PreparedStatement,在 Node.js 中使用參數(shù)化查詢,在 Python 中使用%s占位符。
四、結語
MySQL 的學習曲線是“易學難精”。寫出能跑的 SELECT 語句只需五分鐘,但寫出在千萬級數(shù)據(jù)下依然毫秒級響應、在并發(fā)高負載下依然數(shù)據(jù)一致的 SQL,則需要深厚的功底。
- 對于初學者:熟練掌握 CRUD 和 JOIN,理解事務的基本概念。
- 對于進階者:深入理解索引原理(B+ 樹)、執(zhí)行計劃分析、鎖機制以及慢查詢優(yōu)化。
記住,數(shù)據(jù)庫是應用的最后一道防線。優(yōu)秀的代碼不僅邏輯嚴密,更要對數(shù)據(jù)心存敬畏。每一次 UPDATE 和 DELETE 前的深思熟慮,都是專業(yè)素養(yǎng)的體現(xiàn)。
到此這篇關于MySQL 實戰(zhàn)入門:從“增刪改查”到“高效查詢”的核心指南的文章就介紹到這了,更多相關mysql增刪改查到高效查詢內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
使用xshell實現(xiàn)代理功能并navicat?for?MySQL?進行測試
本文介紹使用xshell實現(xiàn)代理功能并使用navicat?for?MySQL進行測試,文章主要利用SSH連接工具xshell就可以實現(xiàn)簡單的代理功能,下面實現(xiàn)過程,需要的小伙伴可以參考一下2022-02-02
MySQL 大數(shù)據(jù)量快速插入方法和語句優(yōu)化分享
對于事務表,應使用BEGIN和COMMIT代替LOCK TABLES來加快插入2012-04-04

