指南:從建表到執(zhí)行計劃)
簡介這是頭歌MySQL數據庫實訓答案的PDF整理版面向正在完成頭歌平臺數據庫實訓、需要逐關核對SQL語句的初學者和自學者。壓縮包內為1個已生成目錄的PDF文檔大小433KB按實訓關卡的順序匯總了多章答案可從建庫建表一直查到外鍵刪除、數據更新等操作。內容覆蓋創(chuàng)建數據庫與數據表、主鍵/外鍵/唯一/默認值約束、查看表結構、修改表名、變更字段名與字段類型、添加刪除字段、調整字段排列位置等典型關卡均給出完整可直接參照的SQL語句對于約束應用部分還保留了一題多寫法或復合主鍵等細節(jié)能幫助讀者對照理解不同命令的作用。命令原文保留核心語法去掉冗余說明便于逐條閱讀和復制核驗。當前已有18369人在CSDN學習下載資料體積小、定位明確既適合實訓卡點快速排錯也適合作為MySQL常用命令的便攜速查筆記。1. 頭歌MySQL數據庫實訓答案有目錄.pdf這不是題庫而是一本帶索引的錯題集你對著頭歌MySQL數據庫實訓題一個表一個表試錯的時候突然拿到一份“頭歌MySQL數據庫實訓答案有目錄.pdf”第一反應是撿到寶終于有標準答案可以抄第二反應才是抄也抄不順本地環(huán)境和評測平臺的差異、字符集、sql_mode、DELIMITER哪一個都能讓同一段SQL在兩個環(huán)境里表現不一樣。這份PDF真正值錢的地方不在最后那幾行SQL而在“有目錄”三個字它給了你一條按知識點檢索答案的路徑也逼著你把散落的SQL語法按主題歸檔。適合讀這篇文章的人不是想復制粘貼的人而是想把實訓題當成體檢報告、順著目錄把MySQL漏洞一個個補齊的人。2. 答案文件覆蓋什么MySQL實訓從建表到存儲過程的五大出題點帶目錄的答案本質上是一張出題地圖。拿這類PDF和實訓題逐一比照會發(fā)現訓練編排非常固定先建庫建表再灌數據再寫查詢再做優(yōu)化和自動化最后落在存儲過程與觸發(fā)器上。下面按這個順序把五大出題點拆開同時把每類題里最容易忽略的語法語義講清楚。2.1 建表與約束主鍵、外鍵、唯一鍵在答案里怎么變形第一類題基本圍著CREATE TABLE和ALTER TABLE打轉。題目名字各不同但答案里繞不開一個點主鍵和唯一鍵的區(qū)別。主鍵在整張表里只允許一個唯一鍵可以有多個唯一鍵允許存NULL而NULL在唯一索引里可以出現多次。這道題之所以反復被拿出來考是因為很多人以為“唯一鍵就是不能重復”卻沒注意NULL的行不參與重復判斷。CREATE TABLE student ( id INT NOT NULL, no VARCHAR(20) NOT NULL, name VARCHAR(50), PRIMARY KEY (id), UNIQUE KEY uk_student_no (no) ); ALTER TABLE student ADD CONSTRAINT fk_student_class FOREIGN KEY (class_id) REFERENCES class(id);邏輯說明第一段建表語句把主鍵和唯一鍵都定義在列上告訴MySQL這兩類約束各自的名字第二段用ALTER TABLE追加外鍵是為了把“先建表、后補關系”的流程體現出來。實訓題經常同時考這兩種寫法實際工程里表結構往往是迭代出來的不是一次CREATE就定稿。參數說明PRIMARY KEY (id)會讓id列自動成為聚簇索引入口UNIQUE KEY uk_student_no (no)除了阻止重復學號還附帶生成一個二級索引外鍵約束要求class表的id必須是唯一鍵或主鍵否則創(chuàng)建直接報錯。MySQL 8.0里外鍵的級聯(lián)動作寫在ON DELETE和ON UPDATE上答案里如果只建約束不寫動作默認是NO ACTION刪除父表行會被攔下來。拿到這種答案時建議先在本地的兩張表上試一下“刪父表行”和“插入重復no”親眼確認約束行為比死記定義有用得多。2.2 增刪改與自增列INSERT、UPDATE、DELETE的高頻坑第二類題是增刪改看著最簡單卻最容易在“影響行數”上翻車。INSERT的坑集中在沒寫列清單、往自增列塞NULL、以及主鍵沖突后的處理UPDATE和DELETE的坑集中在WHERE條件寫窄或寫寬尤其是DELETE不帶WHERE直接清空全表。INSERT INTO student (name, class_id) VALUES (A同學, 1); UPDATE student SET class_id 2 WHERE id 5; DELETE FROM student WHERE id 10;邏輯說明三句話分別對應新增一行、修改一行、刪除一行答案簡潔到看不出門道真正考的是“你有沒有先確認WHERE命中的行”。習慣先寫SELECT看一眼再執(zhí)行UPDATE/DELETE是最穩(wěn)妥的落地習慣。參數說明INSERT如果省略列清單就必須按表結構順序給全所有列遇到自增列還得算好位置UPDATE的SET可以同時改多列用逗號分隔DELETE執(zhí)行后可以用ROW_COUNT()看影響行數也可以先開事務再決定COMMIT或ROLLBACK。實訓環(huán)境多半是自動提交所以DELETE全表的代價相當大。自增列是這類的隱藏考點。INSERT不指定自增列時MySQL自動分配下一個值顯式插入比當前最大值更大的id后下一個自動值會跳到這個值之上。很多人以為刪除最大id行再插入就會復用實際上InnoDB的自增計數器不會因為DELETE回退這個現象會在避坑章節(jié)再展開。2.3 查詢與聚合GROUP BY和HAVING為什么總在同一道題里查詢題是實訓的重頭目錄條目最多。最典型的組合是“多表JOIN 條件過濾 分組聚合 結果排序”。統(tǒng)計每個班的平均分只保留及格線以上的班級這類題幾乎每個實訓包都會出現。SELECT c.class_name, AVG(s.score) AS avg_score FROM class c JOIN student s ON c.id s.class_id WHERE s.score 0 GROUP BY c.class_name HAVING AVG(s.score) 60 ORDER BY avg_score DESC;邏輯說明WHERE在分組前過濾行HAVING在分組后過濾組這是答案能跑通的關鍵。如果把s.score 0寫進HAVING結果可能一樣但執(zhí)行順序完全不同優(yōu)化器處理起來也笨重。GROUP BY的列盡量和SELECT里的非聚合列保持一致否則會碰到only_full_group_by報錯這點在MySQL 5.7和8.0里都是默認開啟的。參數說明AVG忽略NULL但不忽略0統(tǒng)計前要先想清楚業(yè)務上0分算不算有效成績JOIN默認是INNER JOIN只有左右兩邊都匹配上的行才會出現ORDER BY里可以用SELECT中定義的別名avg_score但WHERE里不能用別名而HAVING可以使用別名這是SQL解析順序決定的。這類題拿到答案后建議把JOIN換成逗號連接加WHERE條件的老寫法跑一遍理解兩種寫法的等價關系和優(yōu)化器差異后面排查慢查詢會更有底氣。2.4 索引與視圖答案里看似配角其實決定性能與可復用性索引題和視圖題在實訓答案里占的比例不高但對照著做的人來說最該認真讀。索引題一般給一個查詢條件讓你決定在哪個列上建索引視圖題一般給一個復雜SELECT要求封裝成視圖供后續(xù)查詢復用。CREATE INDEX idx_student_class_id ON student(class_id); CREATE VIEW v_class_avg AS SELECT c.class_name, AVG(s.score) AS avg_score FROM class c JOIN student s ON c.id s.class_id GROUP BY c.class_name;邏輯說明CREATE INDEX只告訴MySQL在class_id上建二級索引查詢優(yōu)化器會在合適的時候選用它來加速等值查詢CREATE VIEW不存數據只是把SELECT語句存成命名對象每次查詢視圖都會執(zhí)行底層SQL所以視圖性能取決于底層SQL寫得怎么樣。參數說明索引名要按項目命名習慣來起否則索引多了之后分不清復合索引要考慮列順序通常把等值條件的列放前面范圍條件的列放后面視圖在8.0里可能用MERGE或物化臨時表兩種方式處理如果視圖里用了GROUP BY、DISTINCT、LIMIT等句法通常只能物化成臨時表。不要為了建索引而建索引。如果實訓答案只要求建索引不要求驗證可以執(zhí)行EXPLAIN對比前后兩趟看type列從ALL變成ref還是range再判斷這個索引建得有沒有意義。2.5 存儲過程與觸發(fā)器DELIMITER與事務提交的邊界最后一類題難度陡然上升存儲過程、函數、觸發(fā)器、事務。它們的共同點是答案里幾乎都有BEGIN...END塊而BEGIN...END塊內部允許出現分號這就會和MySQL客戶端默認的“分號即語句結束”沖突。DELIMITER // CREATE PROCEDURE sp_class_students(IN cid INT) BEGIN SELECT id, name, score FROM student WHERE class_id cid; END // DELIMITER ;邏輯說明DELIMITER的作用是把客戶端的語句分隔符暫時改成//讓創(chuàng)建過程時內部的分號不再打斷語句等過程建完再改回分號。很多實訓答案是從文本編輯器直接復制的在命令行粘貼時如果不帶DELIMITER兩行創(chuàng)建過程十有八九報語法錯。參數說明IN參數表示輸入參數存儲過程不能用RETURN回傳值SET結果集要由調用方接收CALL sp_class_students(1)即可調用。事務題里存儲過程默認沿用調用者的autocommit設定如果希望過程內多處寫入保持原子性需要顯式開啟事務正常結束COMMIT、異常ROLLBACK。觸發(fā)器題有相同的痛點BEFORE INSERT的FOR EACH ROW寫過第一條語句后只要遇到多條語句就離不開DELIMITER。這類環(huán)境適配問題避坑章節(jié)會給出最具體的應對。3. 把答案用出效率定位、先答、對照、改寫四步走3.1 用目錄定位題號先建自己的知識地圖拿到任何帶目錄的PDF第一動作不該是翻正文而是把目錄當索引做一次映射。常見目錄格式是按實訓分組實訓一建表、實訓二增刪改、實訓三查詢。題目順序和實訓平臺不一定一一對應所以要先花十分鐘手工確認章節(jié)序號和知識點建一張自己的映射表。目錄條目對應知識點我的掌握程度平臺題號實訓一 建表與約束主鍵、唯一鍵、外鍵不熟練待補充實訓三 分組查詢JOIN、GROUP BY、HAVING一般待補充建這張表的過程就是把“答案有目錄”變成“腦子里有目錄”。不需要寫太多字只寫下題目用了哪些表和列然后繼續(xù)下一步。3.2 先寫自己的版本再翻答案看答案的最優(yōu)策略是“先答題、后對照”。見過A同學一上來就逐條復制答案等實訓平臺的題目順序一變整個人就懵了。更有效的做法是拿到一道題先屏蔽答案自己寫下SQL在本地或平臺上執(zhí)行確認輸出符合預期然后把答案翻出來跟自己的版本逐行對比。-- 我的版本 SELECT c.class_name, AVG(s.score) avg_score FROM class c, student s WHERE c.id s.class_id GROUP BY c.class_name; -- 答案版本 SELECT c.class_name, AVG(s.score) AS avg_score FROM class c JOIN student s ON c.id s.class_id GROUP BY c.class_name HAVING AVG(s.score) 60;邏輯說明這道題如果只要求每個班平均分我的版本能過但如果題目要求“只顯示及格以上的班”兩段SQL的非等價部分就是HAVING那一行。逐行對比時會發(fā)現自己漏了過濾條件這才是答案給你帶來的真實增量。參數說明我的版本里逗號連接和WHERE是SQL-89老寫法答案版本是SQL-92標準的JOIN寫法。兩者語義等價但JOIN寫法更直白后面要加LEFT JOIN也不會產生歧義。對比時重點看三件事有沒有過濾條件、分組粒度對不對、排序要不要。3.3 把答案改寫成自己的命名再跑一遍只盯著答案看記憶留存率很低。我常用的做法是把答案中的表名、列名換成自己本地的命名再執(zhí)行一遍。比如實訓平臺叫student表我本地叫stu_info答案里的student不替換就直接報表不存在。這個替換動作本身就是在檢驗你有沒有真正讀懂答案。sed -i s/student/stu_info/g; s/class_id/cls_id/g answer.sql mysql -u root -p mydb answer.sql邏輯說明sed做全局替換后將SQL導入本地庫表不存在、列名不匹配的問題馬上暴露。如果你連答案里出現的列名都認不全這一步會卡住是在逼你回頭查表結構。參數說明sed的全局替換要注意誤傷student可能誤匹配student_detail這類長表名穩(wěn)妥做法是先人工過一遍替換清單再執(zhí)行把每條g替換后可能波及的對象整理出來mysql導入時如果答案里有USE語句會切到答案指定的庫建議先把那行刪掉再導入避免覆蓋自己不想動的庫。提示替換完之后運行一條SELECT * FROM stu_info LIMIT 5確認表結構仍然完整再繼續(xù)做后面的驗證。3.4 評測系統(tǒng)反饋差異別急著怪答案很多時候你把答案原封不動貼進評測系統(tǒng)仍然判錯原因大概率在環(huán)境。比如平臺用嚴格模式本地默認寬松又比如答案假設表結構是utf8平臺是utf8mb4還有答案依賴初始數據生成順序一旦平臺重置數據結果就對不上。把“本地跑通”和“平臺通過”當成兩件事分別記錄報錯信息和結果差異才有排查依據。具體的版本、字符集、時區(qū)問題下一章給出清單。4. 頭歌MySQL實訓答案跑不通的避坑清單版本、字符集與嚴格模式目錄解決的是找得到的問題跑不跑得通是環(huán)境的問題。以下五條踩坑記錄來自實際訓練里反復出現的現象每條按“現象→原因→解決”展開。4.1 分組查詢報錯only_full_group_by5.7與8.0的默認差異現象SELECT name, COUNT(*) FROM student GROUP BY class_id; 在實訓平臺或MySQL 8.0上直接報錯但換到一臺老配置機器上卻能跑通。原因only_full_group_by在MySQL 5.7和8.0里默認開啟要求SELECT列表里出現的非聚合列必須出現在GROUP BY列表里。答案里如果有這種寫法說明它默認了一個寬松環(huán)境一旦交給嚴格模式的評測環(huán)境立刻翻車。解決把非聚合列改成聚合寫法或者用ANY_VALUE()明確表達“我只要任意一個樣例值”SELECT class_id, ANY_VALUE(name) AS sample_name, COUNT(*) AS cnt FROM student GROUP BY class_id;邏輯說明ANY_VALUE(name)表面上給了name一個“聚合”的身份本質上就是告訴優(yōu)化器這一列我不關心具體哪一行隨便取一個。它能通過only_full_group_by的檢查但如果題目要求的是“每個班成績最高的學生”就不能指望這種寫法這種業(yè)務規(guī)則要用窗口函數或自連接實現不能靠ANY_VALUE的隨機性碰運氣。參數說明本地調試時臨時移除only_full_group_by是可行的SET SESSION sql_mode (SELECT REPLACE(sql_mode, ONLY_FULL_GROUP_BY, ));但實訓平臺沒法容忍這種修改所以不要把它寫進最終提交的答案改寫SQL本身才是最穩(wěn)的路。4.2 中文亂碼或插入失敗字符集沒對齊現象向表里插入中文執(zhí)行成功但查出來是問號或者直接報“Incorrect string value”錯誤。原因MySQL的字符集有服務端、數據庫、表、連接四個層面。實訓答案建表時如果沒指定CHARSET會繼承庫級設置客戶端寫入時如果連接字符集不是utf8mb4中文就會在傳輸層被翻譯成錯誤字節(jié)。解決執(zhí)行答案的會話里先統(tǒng)一連接字符集命令行連庫時直接指定mysql -uroot -p --default-character-setutf8mb4 training_db邏輯說明第一步先讓連接層是utf8mb4如果插入仍然報錯再檢查建表語句里是否用CHARSETutf8mb4顯式聲明。答案自帶的建表語句很多出自舊課程只有CHARSETutf8在MySQL 8.0里雖然可以運行但強烈建議統(tǒng)一為utf8mb4。參數說明SET NAMES utf8mb4等價于同時設置character_set_client、character_set_connection和character_set_results三個變量如果歷史遺留的表已經建成latin1還要先執(zhí)行ALTER TABLE student CONVERT TO CHARACTER SET utf8mb4這個操作會重寫整表執(zhí)行前先確認數據有備份。4.3 存儲過程或觸發(fā)器創(chuàng)建失敗DELIMITER引起的邊界錯亂現象把含BEGIN...END的存儲過程答案粘貼到命令行總是提示“ERROR 1064 near BEGIN”但答案看起來完整。原因客戶端默認把分號當語句結束符CREATE PROCEDURE內部的多個分號會把語句提前切碎服務端收到的是一段殘缺SQL。解決執(zhí)行前用DELIMITER改分隔符創(chuàng)建完再改回來DELIMITER // CREATE PROCEDURE sp_class_students(IN cid INT) BEGIN SELECT id, name FROM student WHERE class_id cid; END // DELIMITER ;邏輯說明DELIMITER本身不是SQL語法它是mysql客戶端內置的識別技巧。因此通過JDBC、Python的MySQL驅動或者部分IDE執(zhí)行時不一定要寫但實訓平臺的命令行窗口里DELIMITER是繞不過去的一步。參數說明DELIMITER后面的分隔符可以自定義常見有//和$$。DELIMITER與分隔符之間要有空格寫成DELIMITER //而不是DELIMITER//創(chuàng)建完立刻改回分號不然后續(xù)普通語句都以//結束會制造更多困惑。4.4 執(zhí)行成功但結果差8小時或日期格式化不對現象答案里用到NOW()或DATE_FORMAT的題目執(zhí)行不報錯但得到的時間比預期晚8小時或者日期格式輸出和預期不一樣。原因MySQL的時區(qū)設置不一致。NOW()返回會話時區(qū)里的當前時間如果會話時區(qū)是UTC本地是UTC8結果就差8小時DATE_FORMAT的格式符拼錯也會讓結果看起來詭異。解決執(zhí)行前統(tǒng)一設定會話時區(qū)SET time_zone 08:00; SELECT NOW(); SELECT DATE_FORMAT(NOW(), %Y-%m-%d %H:%i:%s);邏輯說明把time_zone顯式釘在08:00是讓本地結果和評測環(huán)境可以對比的最簡單方式。如果答案里日期寫的是某個固定值那還要判斷是不是MySQL 8.0對日期零值和默認值的處理變化。參數說明MySQL 8.0默認time_zone是SYSTEM跟隨操作系統(tǒng)SET SESSION只影響當前連接UNIX_TIMESTAMP()也受會話時區(qū)影響。遇到日期結果不一致先查time_zone和sql_mode兩個變量而不是懷疑SQL寫錯。4.5 自增主鍵不連續(xù)或插入指定id后順序被打亂現象插入失敗一次下一次成功行的id變成3DELETE掉最大id后再插入自增值并沒有回退最終SELECT ... ORDER BY id的結果順序和答案對不上。原因InnoDB的自增計數器一旦分配就不會回收事務回滾或DELETE行都不會讓它回退MySQL 8.0里這個計數器持久化保存重啟也不能重置。解決先確認題目是否校驗自增值。如果只是希望接下來從某個數字開始用ALTER TABLE設置ALTER TABLE student AUTO_INCREMENT 100;如果答案要求整張表回到初始狀態(tài)用TRUNCATE清空并重建自增起點隨之一同重置TRUNCATE TABLE student;邏輯說明ALTER TABLE設置自增起點只能往后調不能往前調TRUNCATE會重建表存儲結構所以能徹底重置。但外鍵引用這張表時TRUNCATE會被拒絕要先處理引用表再做全表清空。把自增列當作黑匣子不要用INSERT失敗來猜測下一個id才是站在工程視角對待答案的態(tài)度。參數說明TRUNCATE在MySQL里會隱式提交事務執(zhí)行后不能回滾務必確認操作對象再執(zhí)行最好先用SELECT確認當前最大id與總行數再決定要不要清。5. 超越答案用EXPLAIN判斷每條SQL值不值得借鑒目錄是文章的索引索引是數據庫的目錄。帶著這個視角去看答案會發(fā)現“能跑通”和“值得抄”是兩回事。下面用執(zhí)行計劃這條路徑把參考答案的價值再榨一層。5.1 執(zhí)行計劃里的type、key、rows三列怎么看先給一段常見實訓查詢EXPLAIN SELECT s.name, c.class_name FROM student s LEFT JOIN class c ON s.class_id c.id WHERE s.score 60;執(zhí)行計劃會返回一張表其中最重要的三列是type、key、rows。type表示訪問表的方式按從好到差大致是system const eq_ref ref range index ALLtype是ALL說明全表掃描ref或range則說明用到了索引。key列顯示實際使用的索引名沒顯示就表示索引沒被選中。rows是優(yōu)化器估算要掃描的行數不看絕對值看它和表總行數的比例。邏輯說明當rows占全表的大部分優(yōu)化器可能放棄索引改走全表掃描因為隨機訪問的代價反而更大當key為NULL而type為ALL第一件要做的事就是從WHERE條件和查詢字段里尋找能建立合適索引的列。答案沒給索引不代表不需要表結構設計才是決定查詢上限的根本。參數說明MySQL 8.0的EXPLAIN支持FORMATJSON能看到更細的成本估算如果對執(zhí)行計劃有疑問先看filtered列它表示存儲引擎返回的行里過濾條件的符合比例比例越低查詢中“無用行”越多。5.2 回表與覆蓋索引為什么答案里的SELECT *不要照抄實訓答案為了簡化輸出常在SELECT里寫星號。學習環(huán)境沒問題還原到業(yè)務場景問題就來了二級索引只存索引列和主鍵值回表是指根據主鍵再去聚簇索引取其他列的過程讀星號通常就會多一段回表IO。CREATE INDEX idx_class_id ON student(class_id); EXPLAIN SELECT * FROM student WHERE class_id 1; EXPLAIN SELECT class_id FROM student WHERE class_id 1;邏輯說明第一條因為要取name、score等列執(zhí)行計劃里Extra列不會有Using index想做的是回表第二條只需要class_id索引本身已經覆蓋Extra會顯示Using index。覆蓋索引是避免回表的最直接手段。參數說明覆蓋索引不是越多越好每一個索引都會拖慢寫入。對于實訓答案里考察索引設計的題判斷標準不是有沒有extra索引而是它減少了多少實際查詢的回表次數。單表的數據量、寫入壓力都得看規(guī)模再定不要盲目復合。5.3 同一道題的三種寫法子查詢、JOIN、窗口函數怎么選帶目錄的答案多數只給一種寫法但同一道“找出每個班成績最高的人”可以寫成子查詢、JOIN和窗口函數三種風格執(zhí)行計劃與語義差別都不小SELECT s.name, s.score FROM student s WHERE s.score (SELECT MAX(score) FROM student s2 WHERE s2.class_id s.class_id); SELECT s.name, s.score FROM student s JOIN ( SELECT class_id, MAX(score) AS max_score FROM student GROUP BY class_id ) t ON s.class_id t.class_id AND s.score t.max_score; SELECT name, score, RANK() OVER (PARTITION BY class_id ORDER BY score DESC) AS rk FROM student;邏輯說明第一種子查詢在MySQL 8.0里優(yōu)化器常常改寫成JOIN但寫錯的話可能造成逐行執(zhí)行變慢第二種先聚合再JOIN數據量大時通常是最穩(wěn)的第三種窗口函數在8.0才有語義最清晰。答案里如果沒出現窗口函數不代表不能寫可能只是出題時間早于8.0流行。參數說明RANK()遇到同分會把名次變成1、1、3DENSE_RANK()是1、1、2ROW_NUMBER()則對同分行隨機排序三者不可混用。實訓答案如果需要“取每個班的第一名”先確認題目是否允許并列再決定用哪個窗口函數。6. 一頁紙自測表從答案有目錄到腦子有目錄最后一個技巧把這份帶目錄PDF的“目錄”和你的執(zhí)行計劃結合起來做一張一頁紙自測表。紙不用多每次只放自己本周要攻克的5道題。題號知識點我能一次性寫對嗎答案差異點驗證EXPLAIN結論具體做法是先在“我能一次性寫對嗎”那格寫一個大膽的判斷不看答案寫寫完回想鎖上答案逐個對照“差異點”如果差異為零或很小這種掌握才真正體現水平最后把表里各條SQL的EXPLAIN結果寫進“驗證EXPLAIN結論”讓每一道題至少有一個基于索引、回表或掃描的判斷。每個差異點都要自問一句答案為什么用這種方式表達它是為了兼容某版本還是在語法層面更清晰或者只是作者的用語習慣只要能用自己話把這句回答清楚答案就已經轉化成自己的知識回答不了就別騙自己。背誦是起點復盤后的表達才是終點。我在這類實訓的復盤上有過一段彎路原因是拿刷題數衡量成果停留在“復制答案、運行通過、標記完成”這三步沒有自測、沒有差異記錄結果換了數據集或表名之后照樣不會用。后來改成這種一頁紙的方法每次只記5道題反而比整本筆記更有效。如果你手頭正拿著這份“頭歌MySQL數據庫實訓答案有目錄.pdf”先翻目錄挑三道不那么簡單的題按上面的四步走重寫一遍再用EXPLAIN驗證你會發(fā)現答案本體只是入口真正的收益藏在從目錄到執(zhí)行計劃的那條路徑上。希望幫到你。本文還有配套的精品資源點擊獲取