據(jù)操作指南:從INSERT到事務(wù)與索引安全)
在 MySQL 的學(xué)習(xí)路徑中“表數(shù)據(jù)操作”是很容易被低估的一個(gè)環(huán)節(jié)。很多新手花了不少時(shí)間理解建表語句、字段類型、主鍵外鍵但到了真正寫業(yè)務(wù)代碼時(shí)每天接觸最多的反而是對(duì)表里數(shù)據(jù)進(jìn)行增刪改查。更麻煩的是這類操作看起來簡(jiǎn)單寫錯(cuò)之后的代價(jià)卻可能非常大一條沒有 WHERE 的 UPDATE 會(huì)改掉整張表一條沒有事務(wù)保護(hù)的 DELETE 可能讓線上數(shù)據(jù)無法恢復(fù)。本文圍繞 MySQL 表數(shù)據(jù)操作展開系統(tǒng)梳理 INSERT、SELECT、UPDATE、DELETE 的使用方法、常見寫法、事務(wù)與鎖的影響并給出一個(gè)可以直接運(yùn)行的完整案例。無論你是剛開始學(xué)數(shù)據(jù)庫的初學(xué)者還是已經(jīng)寫過一段時(shí)間 SQL、想補(bǔ)齊安全細(xì)節(jié)的開發(fā)者這篇文章都值得收藏對(duì)照。1. 表數(shù)據(jù)操作到底是什么1.1 DML 與 DDL、DCL 的分工要理解 MySQL 表數(shù)據(jù)操作先要分清 SQL 語句的幾個(gè)大類。數(shù)據(jù)庫日常執(zhí)行的語句通??梢詣澐譃?DDL、DML、DCL、DQL類別英文全稱主要語句作用對(duì)象DDLData Definition LanguageCREATE、ALTER、DROP、TRUNCATE表結(jié)構(gòu)、數(shù)據(jù)庫結(jié)構(gòu)DMLData Manipulation LanguageINSERT、UPDATE、DELETE表中的數(shù)據(jù)DQLData Query LanguageSELECT查詢表中的數(shù)據(jù)DCLData Control LanguageGRANT、REVOKE用戶權(quán)限與訪問控制本文關(guān)注的重點(diǎn)是 DML也就是對(duì)表數(shù)據(jù)的增、刪、改操作。不過在日常開發(fā)中SELECT 查詢和 DML 的關(guān)系非常緊密因?yàn)槲覀冃枰炔槌瞿男?shù)據(jù)滿足條件才敢放心執(zhí)行 UPDATE 或 DELETE。所以下文會(huì)把 SELECT 也納入“表數(shù)據(jù)操作”的完整講解范圍。1.2 為什么表數(shù)據(jù)操作如此重要建表只是搭建骨架真正驅(qū)動(dòng)業(yè)務(wù)運(yùn)轉(zhuǎn)的是表里的數(shù)據(jù)。用戶注冊(cè)后要插入一條用戶記錄下單后要更新訂單狀態(tài)商品下架后要?jiǎng)h除或標(biāo)記失效記錄。這些都是典型的表數(shù)據(jù)操作。從另一個(gè)角度看后端開發(fā)中大量性能問題、數(shù)據(jù)一致性問題、線上事故也都集中在數(shù)據(jù)操作環(huán)節(jié)。比如 UPDATE 沒有走索引導(dǎo)致鎖范圍擴(kuò)大DELETE 刪掉了重要業(yè)務(wù)數(shù)據(jù)INSERT 大批量逐條提交導(dǎo)致性能很差。掌握表數(shù)據(jù)操作不等于只會(huì)寫四條基本語句而是要理解條件過濾、事務(wù)邊界、索引影響、備份策略這樣在真實(shí)項(xiàng)目中才能安全落地。1.3 先理解行、列與記錄在 MySQL 中一張表由行和列組成。列定義了字段名稱與數(shù)據(jù)類型行則是一條具體的數(shù)據(jù)記錄。例如學(xué)生表里每一行代表一個(gè)學(xué)生每一列代表學(xué)號(hào)、姓名、班級(jí)等信息。學(xué)習(xí) DML 時(shí)要始終帶著“操作對(duì)象是行”的意識(shí)。INSERT 是新增一行或多行UPDATE 是修改符合條件的行DELETE 是刪除符合條件的行SELECT 是篩選出符合條件的行。寫 SQL 時(shí)最重要的就是明確“哪些行會(huì)被影響”。2. 環(huán)境準(zhǔn)備與測(cè)試表設(shè)計(jì)2.1 連接 MySQL開始操作前先確認(rèn)已經(jīng)安裝并啟動(dòng)了 MySQL 服務(wù)。MySQL 的安裝方式很多可以用官方安裝包、操作系統(tǒng)軟件源也可以用 Docker 快速啟動(dòng)一個(gè)實(shí)例。本文的重點(diǎn)是表數(shù)據(jù)操作SQL 語法在 MySQL 5.7 和 MySQL 8.0 中基本通用如果你的版本較新個(gè)別細(xì)節(jié)以自己環(huán)境為準(zhǔn)即可。連接本機(jī) MySQL 最常用的命令是mysql -uroot -p輸入密碼后會(huì)出現(xiàn)mysql提示符??吹教崾痉f明已經(jīng)進(jìn)入 MySQL 客戶端可以執(zhí)行 SQL 語句了。如果 MySQL 不在當(dāng)前機(jī)器的默認(rèn) socket 路徑也可以指定主機(jī)和端口mysql -h127.0.0.1 -P3306 -uroot -p這里-h指定主機(jī)-P指定端口-u指定用戶-p表示需要輸入密碼。生產(chǎn)環(huán)境不建議直接用 root 操作業(yè)務(wù)庫最好單獨(dú)創(chuàng)建業(yè)務(wù)賬號(hào)并授予最小權(quán)限。2.2 創(chuàng)建數(shù)據(jù)庫與成績(jī)表為了方便后續(xù)演示我們創(chuàng)建一個(gè)school_db數(shù)據(jù)庫并設(shè)計(jì)一張學(xué)生表和一張成績(jī)表。先創(chuàng)建數(shù)據(jù)庫CREATE DATABASE IF NOT EXISTS school_db DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci;使用數(shù)據(jù)庫USE school_db;創(chuàng)建學(xué)生表CREATE TABLE student ( id INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 主鍵, student_no VARCHAR(20) NOT NULL COMMENT 學(xué)號(hào), student_name VARCHAR(50) NOT NULL COMMENT 姓名, gender CHAR(1) DEFAULT NULL COMMENT 性別, class_no VARCHAR(20) DEFAULT NULL COMMENT 班級(jí), create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 創(chuàng)建時(shí)間, PRIMARY KEY (id), UNIQUE KEY uk_student_no (student_no) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT學(xué)生表;創(chuàng)建成績(jī)表CREATE TABLE score ( id INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 主鍵, student_no VARCHAR(20) NOT NULL COMMENT 學(xué)號(hào), course_name VARCHAR(50) NOT NULL COMMENT 課程名稱, score DECIMAL(5,2) NOT NULL COMMENT 成績(jī), exam_date DATE NOT NULL COMMENT 考試日期, create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 創(chuàng)建時(shí)間, PRIMARY KEY (id), KEY idx_student_course (student_no, course_name) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT成績(jī)表;這里沒有創(chuàng)建物理外鍵而是通過student_no字段保持邏輯關(guān)聯(lián)。實(shí)際項(xiàng)目中是否使用外鍵需要根據(jù)業(yè)務(wù)設(shè)計(jì)權(quán)衡外鍵能保證完整性但也可能帶來額外的鎖與性能開銷。表數(shù)據(jù)操作示例中先使用邏輯外鍵更靈活。關(guān)于字段類型這里單獨(dú)強(qiáng)調(diào)一個(gè)常見誤區(qū)MySQL 中的INT(5)并不表示“只能存 5 位數(shù)字”。INT的存儲(chǔ)范圍是固定的括號(hào)里的數(shù)字通常只是配合ZEROFILL使用時(shí)的顯示寬度。比如INT(5)仍然可以存儲(chǔ)超過 5 位的整數(shù)只是某些場(chǎng)景下顯示效果不同。計(jì)算時(shí)也仍然按照整數(shù)類型處理并不會(huì)因?yàn)閷懗闪薎NT(5)就限制數(shù)值大小。2.3 準(zhǔn)備初始測(cè)試數(shù)據(jù)插入幾條學(xué)生數(shù)據(jù)INSERT INTO student (student_no, student_name, gender, class_no) VALUES (1001, 張三, M, 2024-01班), (1002, 李四, F, 2024-01班), (1003, 王五, M, 2024-02班), (1004, 趙六, F, 2024-02班), (1005, 孫七, M, 2024-03班);插入成績(jī)數(shù)據(jù)INSERT INTO score (student_no, course_name, score, exam_date) VALUES (1001, 數(shù)據(jù)庫原理, 82.50, 2025-01-10), (1001, Java程序設(shè)計(jì), 67.00, 2025-01-12), (1002, 數(shù)據(jù)庫原理, 58.00, 2025-01-10), (1002, Java程序設(shè)計(jì), 74.00, 2025-01-12), (1003, 數(shù)據(jù)庫原理, 45.50, 2025-01-10), (1004, 網(wǎng)絡(luò)基礎(chǔ), 90.00, 2025-01-15), (1005, Java程序設(shè)計(jì), 63.50, 2025-01-12);這樣我們就有了一個(gè)可以反復(fù)練習(xí)的表環(huán)境。后面的講解都會(huì)圍繞這兩張表展開。3. 插入數(shù)據(jù)INSERT 的多種寫法3.1 基礎(chǔ)的單行插入INSERT 的作用是向表中新增記錄。最基本的語法是INSERT INTO student (student_no, student_name, gender, class_no) VALUES (1006, 周八, M, 2024-03班);執(zhí)行后MySQL 會(huì)返回類似下面的信息Query OK, 1 row affected (0.01 sec)這說明成功插入了 1 行記錄。如果省略字段列表就需要按照建表時(shí)的字段順序依次提供所有值INSERT INTO student VALUES (NULL, 1007, 吳九, F, 2024-01班, NOW());但這種寫法要求調(diào)用方對(duì)表結(jié)構(gòu)非常清楚一旦表結(jié)構(gòu)調(diào)整這段 SQL 很容易出錯(cuò)。實(shí)際開發(fā)中更推薦顯式寫出字段列表可讀性和穩(wěn)定性都更好。3.2 插入部分字段當(dāng)某些字段有默認(rèn)值或者允許為 NULL 時(shí)INSERT 語句可以不提供完整字段列表。例如gender允許為 NULLcreate_time有默認(rèn)值那么可以這樣寫INSERT INTO student (student_no, student_name, class_no) VALUES (1008, 鄭十, 2024-01班);執(zhí)行后gender會(huì)是 NULLcreate_time會(huì)自動(dòng)使用當(dāng)前時(shí)間。靈活使用默認(rèn)值可以減少業(yè)務(wù)代碼里不必要的賦值。3.3 一次插入多行當(dāng)需要批量插入多條記錄時(shí)不要一條一條執(zhí)行 INSERT而是使用多行 VALUES 的寫法INSERT INTO score (student_no, course_name, score, exam_date) VALUES (1009, 數(shù)據(jù)庫原理, 88.00, 2025-03-01), (1010, Java程序設(shè)計(jì), 72.50, 2025-03-05), (1011, 網(wǎng)絡(luò)基礎(chǔ), 91.00, 2025-03-08);一次插入多行可以減少客戶端與 MySQL 服務(wù)端之間的網(wǎng)絡(luò)交互次數(shù)也能讓導(dǎo)入效率明顯提升。在數(shù)據(jù)量較大時(shí)可以按每批 500 到 2000 行的量級(jí)分批執(zhí)行避免單條 SQL 過大。3.4 通過 SELECT 復(fù)制數(shù)據(jù)INSERT 的數(shù)據(jù)來源不一定只能手寫 VALUES也可以來自另一張表或同一張表的查詢結(jié)果。例如要把學(xué)生表中 2024-01 班的學(xué)生復(fù)制到一張臨時(shí)表中可以先建一張臨時(shí)表CREATE TABLE student_temp LIKE student;然后使用 INSERT INTO ... SELECT 把數(shù)據(jù)復(fù)制進(jìn)去INSERT INTO student_temp (student_no, student_name, gender, class_no) SELECT student_no, student_name, gender, class_no FROM student WHERE class_no 2024-01班;這種寫法常用于數(shù)據(jù)歸檔、臨時(shí)表加工、表結(jié)構(gòu)升級(jí)等場(chǎng)景。需要注意SELECT 出來的字段順序必須和 INSERT 后面的字段列表一致。3.5 處理唯一鍵沖突如果表中已經(jīng)存在唯一約束插入重復(fù)記錄時(shí)會(huì)報(bào)錯(cuò)。比如student_no有唯一索引再次插入學(xué)號(hào) 1001 就會(huì)提示ERROR 1062 (23000): Duplicate entry 1001 for key student.uk_student_no有兩種常見處理方式。第一種是使用INSERT IGNORE忽略沖突并保留原記錄INSERT IGNORE INTO student (student_no, student_name, gender, class_no) VALUES (1001, 張三, M, 2024-01班);執(zhí)行后返回Query OK, 0 rows affected說明重復(fù)數(shù)據(jù)被忽略。第二種是使用ON DUPLICATE KEY UPDATE在沖突時(shí)執(zhí)行更新操作INSERT INTO student (student_no, student_name, gender, class_no) VALUES (1001, 張三, M, 2024-05班) ON DUPLICATE KEY UPDATE class_no VALUES(class_no);這條語句的意思是如果學(xué)號(hào) 1001 不存在就正常插入如果已經(jīng)存在則把該學(xué)生的班級(jí)更新為2024-05班。高版本 MySQL 對(duì)VALUES()函數(shù)可能出現(xiàn)棄用提示但當(dāng)前示例思路仍可運(yùn)行生產(chǎn)環(huán)境請(qǐng)根據(jù)版本選擇更合適的別名寫法。4. 查詢數(shù)據(jù)SELECT 的核心用法4.1 基礎(chǔ)查詢與字段別名SELECT 是使用頻率最高的 SQL 語句。最簡(jiǎn)單的查詢可以列出全部學(xué)生SELECT * FROM student;*表示返回所有字段適合快速查看數(shù)據(jù)但生產(chǎn)環(huán)境不建議在業(yè)務(wù)代碼里經(jīng)常使用SELECT *。因?yàn)楸斫Y(jié)構(gòu)可能增加字段返回過多無用數(shù)據(jù)會(huì)增加網(wǎng)絡(luò)傳輸和內(nèi)存開銷。更推薦按需列出字段并為字段設(shè)置可讀的別名SELECT student_no AS sno, student_name AS name, class_no FROM student;這里AS用于給字段或表起別名。在 Java、Python 等語言中接收查詢結(jié)果時(shí)清晰的別名能讓字段映射更直觀。4.2 WHERE 條件過濾與 NULL 判斷WHERE 子句用于篩選符合條件的行。例如查詢班級(jí)為2024-01班的學(xué)生SELECT student_no, student_name, class_no FROM student WHERE class_no 2024-01班;多個(gè)條件可以用 AND、OR 組合。查詢成績(jī)大于 80 分且考試日期在 2025 年之后的記錄SELECT student_no, course_name, score, exam_date FROM score WHERE score 80 AND exam_date 2025-01-01;新手經(jīng)常在 NULL 判斷上出錯(cuò)。NULL 表示“未知值”不能用或!判斷。比如學(xué)生表中有學(xué)生的gender為空正確的寫法是SELECT student_no, student_name FROM student WHERE gender IS NULL;如果寫成gender NULLMySQL 不會(huì)報(bào)錯(cuò)但查詢結(jié)果永遠(yuǎn)是空因?yàn)?NULL 不等于任何值包括它自己。這一點(diǎn)在面試和日常開發(fā)中都經(jīng)常被考察。4.3 排序 ORDER BY使用 ORDER BY 可以讓查詢結(jié)果按照指定字段排序。默認(rèn)是升序 ASC也可以指定降序 DESC。查詢成績(jī)從高到低排列SELECT student_no, course_name, score FROM score ORDER BY score DESC;需要按多個(gè)字段排序時(shí)可以寫多個(gè)排序鍵。比如先按成績(jī)降序成績(jī)相同則按考試日期升序SELECT student_no, course_name, score, exam_date FROM score ORDER BY score DESC, exam_date ASC;在 MySQL 默認(rèn)字符集和排序規(guī)則下字符串比較通常不區(qū)分大小寫。如果你希望區(qū)分大小寫可以使用BINARY關(guān)鍵字或指定大小寫敏感的排序規(guī)則。這個(gè)問題經(jīng)常被忽視但在用戶名、編碼類字段查詢時(shí)可能造成不符合預(yù)期的結(jié)果。4.4 聚合統(tǒng)計(jì)與分組 GROUP BY聚合函數(shù)可以將多行數(shù)據(jù)匯總成一個(gè)或多個(gè)統(tǒng)計(jì)值。常用的聚合函數(shù)有 COUNT、SUM、AVG、MAX、MIN。例如統(tǒng)計(jì)成績(jī)表中共有多少條記錄SELECT COUNT(*) AS total_cnt FROM score;統(tǒng)計(jì)每個(gè)學(xué)生參加了幾門考試、平均分是多少SELECT student_no, COUNT(*) AS exam_cnt, ROUND(AVG(score), 2) AS avg_score FROM score GROUP BY student_no ORDER BY avg_score DESC;這里的ROUND(AVG(score), 2)表示對(duì)平均分四舍五入并保留兩位小數(shù)。執(zhí)行結(jié)果會(huì)按學(xué)生學(xué)號(hào)分組分別統(tǒng)計(jì)每個(gè)人的考試次數(shù)和平均成績(jī)。WHERE 和 GROUP BY 的執(zhí)行順序需要特別注意WHERE 是在分組之前過濾原始行GROUP BY 之后如果想對(duì)分組結(jié)果再做過濾必須使用 HAVING而不能使用 WHERE。例如只保留平均分大于 70 的學(xué)生SELECT student_no, COUNT(*) AS exam_cnt, ROUND(AVG(score), 2) AS avg_score FROM score GROUP BY student_no HAVING AVG(score) 70 ORDER BY avg_score DESC;把HAVING AVG(score) 70換成WHERE AVG(score) 70會(huì)直接報(bào)錯(cuò)因?yàn)?WHERE 無法作用于聚合結(jié)果。4.5 分頁 LIMIT當(dāng)查詢結(jié)果很多時(shí)可以用 LIMIT 限制返回條數(shù)也可以配合 OFFSET 實(shí)現(xiàn)分頁。例如查詢成績(jī)最高的前 3 條記錄SELECT student_no, course_name, score FROM score ORDER BY score DESC LIMIT 3;分頁查詢第 2 頁每頁 3 條SELECT student_no, course_name, score FROM score ORDER BY score DESC LIMIT 3 OFFSET 3;這里的OFFSET 3表示跳過前 3 條記錄。如果只寫LIMIT 3表示返回 3 條如果寫LIMIT 3, 3則第一個(gè) 3 表示偏移量第二個(gè) 3 表示返回條數(shù)容易混淆實(shí)際項(xiàng)目中建議寫清OFFSET可讀性更好。4.6 多表關(guān)聯(lián)查詢 JOIN業(yè)務(wù)數(shù)據(jù)往往分散在多個(gè)表中查詢時(shí)需要把表關(guān)聯(lián)起來。比如想查看學(xué)生的姓名和對(duì)應(yīng)成績(jī)可以使用 JOINSELECT s.student_no, s.student_name, sc.course_name, sc.score FROM student s JOIN score sc ON s.student_no sc.student_no WHERE sc.course_name 數(shù)據(jù)庫原理 ORDER BY sc.score DESC;這里s和sc分別是 student、score 表的別名。JOIN 的作用是把兩個(gè)表中student_no相同的行連接在一起。如果希望查詢所有學(xué)生以及他們的成績(jī)情況即使某些學(xué)生沒有成績(jī)也要顯示可以使用 LEFT JOINSELECT s.student_no, s.student_name, sc.course_name, sc.score FROM student s LEFT JOIN score sc ON s.student_no sc.student_no;LEFT JOIN 會(huì)保留左表中的所有行右表中沒有匹配到數(shù)據(jù)時(shí)對(duì)應(yīng)字段會(huì)顯示為 NULL。這種寫法在統(tǒng)計(jì)“哪些學(xué)生沒有考試記錄”時(shí)非常有用。5. 修改數(shù)據(jù)UPDATE 的正確姿勢(shì)5.1 UPDATE 基礎(chǔ)語法UPDATE 用于修改表中已有記錄基礎(chǔ)語法如下UPDATE score SET score 90.00 WHERE student_no 1001 AND course_name 數(shù)據(jù)庫原理 AND exam_date 2025-01-10;執(zhí)行后MySQL 會(huì)返回受影響的行數(shù)。如果該條件匹配到了 1 條記錄就會(huì)返回Query OK, 1 row affected (0.01 sec)這里最關(guān)鍵的是 WHERE 條件。UPDATE 如果沒有 WHERE會(huì)更新表中所有行。在開發(fā)環(huán)境和測(cè)試環(huán)境可能無所謂但在生產(chǎn)環(huán)境執(zhí)行全表 UPDATE幾乎等同于事故。5.2 更新字段自身進(jìn)行計(jì)算修改數(shù)據(jù)時(shí)常需要基于原字段值進(jìn)行計(jì)算。比如給某位學(xué)生的一門課程成績(jī)加 5 分UPDATE score SET score score 5 WHERE student_no 1002 AND course_name 數(shù)據(jù)庫原理;這里的score score 5表示讀取當(dāng)前成績(jī)加上 5 后再寫回字段。MySQL 的字段計(jì)算不需要額外使用 SELECT 先把值取出來直接寫表達(dá)式即可。還有一種常見需求是根據(jù)條件給不同行設(shè)置不同的值可以用 CASE WHEN 實(shí)現(xiàn)。例如對(duì) 2025 年考試中的數(shù)據(jù)庫原理成績(jī)加 2 分對(duì) Java 程序設(shè)計(jì)成績(jī)加 1 分UPDATE score SET score score CASE course_name WHEN 數(shù)據(jù)庫原理 THEN 2 WHEN Java程序設(shè)計(jì) THEN 1 ELSE 0 END WHERE course_name IN (數(shù)據(jù)庫原理, Java程序設(shè)計(jì));CASE WHEN 讓一條 UPDATE 可以處理更豐富的分支邏輯降低了在業(yè)務(wù)代碼中逐條 update 的需求。5.3 UPDATE 的安全風(fēng)險(xiǎn)UPDATE 是數(shù)據(jù)操作中最需要謹(jǐn)慎對(duì)待的語句。建議在更新之前先用 SELECT 確認(rèn) WHERE 條件命中了哪些數(shù)據(jù)。例如原本要執(zhí)行UPDATE score SET score 80 WHERE student_no 1002;可以先執(zhí)行SELECT student_no, course_name, score FROM score WHERE student_no 1002;確認(rèn)這些記錄確實(shí)都是需要修改的目標(biāo)。如果 SELECT 查出了意想不到的數(shù)據(jù)說明 WHERE 條件可能寫錯(cuò)了需要立即停下來檢查。在生產(chǎn)環(huán)境修改重要數(shù)據(jù)時(shí)更好做法是放到事務(wù)中執(zhí)行更新后先查詢驗(yàn)證確認(rèn)無誤再提交事務(wù)。這部分內(nèi)容會(huì)在第 7 章詳細(xì)展開。6. 刪除數(shù)據(jù)DELETE 與 TRUNCATE 的區(qū)別6.1 按條件刪除記錄DELETE 用于刪除表中符合條件的記錄。例如刪除學(xué)號(hào)為 1005 的學(xué)生成績(jī)記錄DELETE FROM score WHERE student_no 1005;如果 DELETE 不寫 WHERE會(huì)清空整張表的數(shù)據(jù)DELETE FROM score;這種操作非常危險(xiǎn)。雖然 InnoDB 引擎下不提交還能通過 ROLLBACK 回滾但在自動(dòng)提交模式下相當(dāng)于一瞬間清空整張表且恢復(fù)成本很高。平時(shí)練習(xí)和開發(fā)中一定要形成“DELET 前先 SELECT”的習(xí)慣。6.2 DELETE 與 TRUNCATE 的區(qū)別TRUNCATE TABLE 也可以清空表數(shù)據(jù)但它和 DELETE 有本質(zhì)區(qū)別DELETE 是 DML可以帶 WHERE可以配合事務(wù)回滾TRUNCATE 是 DDL不能帶 WHERE執(zhí)行后通常無法按事務(wù)回滾TRUNCATE 會(huì)重置 AUTO_INCREMENT 自增計(jì)數(shù)DELETE 默認(rèn)不會(huì)TRUNCATE 清空大表的速度通常比 DELETE