摘要:語(yǔ)句最基礎(chǔ)的用法不再贅述。而這樣刪掉整張表的語(yǔ)句是不會(huì)清空自增值的。
這是MySQL系列筆記的第一部分,本系列筆記希望能按照筆者自己學(xué)習(xí)MySQL技術(shù)的經(jīng)歷來(lái)記錄,避免純粹按照內(nèi)容一塊一塊總結(jié),也就是不同于一般按內(nèi)容分配章節(jié)的書(shū)籍的結(jié)構(gòu),會(huì)有一個(gè)平滑的閱讀曲線。內(nèi)容比較豐富的技術(shù)點(diǎn)會(huì)按照專(zhuān)題在多個(gè)學(xué)習(xí)筆記中逐漸深入。
這部分的標(biāo)題叫比CRUD多一丁點(diǎn)兒,比起最基礎(chǔ)的w3c的SQL教程之外,只多一點(diǎn)的擴(kuò)展,滿足應(yīng)付從純粹閱讀入門(mén)資料到可以上手完成一個(gè)簡(jiǎn)單的工作的需求。
第三篇的主要內(nèi)容繼續(xù)是基礎(chǔ)SQL語(yǔ)句UPDATE和DELETE,這兩個(gè)相對(duì)比較簡(jiǎn)單,在運(yùn)維和處理線上數(shù)據(jù)問(wèn)題時(shí)候可能比較常用,在開(kāi)發(fā)過(guò)程中基本上都只會(huì)使用最基礎(chǔ)的操作。
DELETE語(yǔ)句最基礎(chǔ)的用法不再贅述。說(shuō)一下當(dāng)使用DELETE刪除的數(shù)據(jù)需要用一個(gè)條件關(guān)聯(lián)來(lái)查找而不止是簡(jiǎn)單的where條件時(shí)候,寫(xiě)法是這樣的:
DELETE t1, t2 FROM t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.id=t2.id AND t2.id=t3.id;
注意如果用了alias,刪除語(yǔ)句也必須用alias不能再用表名:
DELETE a1, a2 FROM t1 AS a1 INNER JOIN t2 AS a2 WHERE a1.id=a2.id; -- 正確 DELETE t1 AS a1, t2 AS a2 FROM t1 INNER JOIN t2 WHERE a1.id=a2.id; -- 錯(cuò)誤
一定要提醒的是,DELETE和UPDATE一定記得加限定條件,否則很容易就可能釀成一樁慘案,因?yàn)閿?shù)據(jù)庫(kù)需要保證MVCC(Multiversion concurrency control,是事務(wù)的基礎(chǔ)),這類(lèi)更新操作的開(kāi)銷(xiāo)很大甚至需要鎖表。筆者自己在線上數(shù)據(jù)庫(kù)做這些操作包括SELECT時(shí)候手已經(jīng)都已經(jīng)形成了下意識(shí),一定會(huì)先寫(xiě)下where條件,Ctrl-A再開(kāi)始寫(xiě)update,select。
TRUNCATE TABLE相對(duì)剛才說(shuō)的DELETE操作很慢,如果寫(xiě)單元測(cè)試和自己用的開(kāi)發(fā)庫(kù)需要快速的清空一個(gè)表時(shí)候要怎么做呢?答案是使用TRUNCATE。
注意使用TRUNCATE時(shí)候如果表有設(shè)置自增列,比如自增的主鍵,是會(huì)被清空到初始值的,也就是TRUNCATE之后。而DELETE FROM t;這樣刪掉整張表的DELETE語(yǔ)句是不會(huì)清空自增值的。另外如果有外鍵關(guān)聯(lián),那么就需要使用set foreign_key_checks來(lái)去掉外鍵檢查:
set foreign_key_checks = 0; truncate Account; set foreign_key_checks = 1;
這個(gè)特性還引起一個(gè)筆者開(kāi)發(fā)時(shí)候碰到的很有意思的異常:就是當(dāng)這樣清空了某張表t的主鍵后,與其有關(guān)聯(lián)關(guān)系的表a沒(méi)有清空,隨后在t中新插入數(shù)據(jù),自增ID重新從1開(kāi)始增加。結(jié)果a中的一些舊數(shù)據(jù)結(jié)果就跟t中的新數(shù)據(jù)關(guān)聯(lián)上了。哈哈哈,當(dāng)時(shí)著實(shí)是覺(jué)得是不是鬧鬼了,查了挺久才發(fā)現(xiàn)。
UPDATE語(yǔ)句最基礎(chǔ)的用法不再贅述??聪旅胬樱?/p>
UPDATE t1 SET yourname = realname + ".avi";
設(shè)置的值其實(shí)是一個(gè)表達(dá)式,其實(shí)可以這樣用別的列表,也可以同時(shí)更新兩個(gè)表,也就是用上JOIN:
UPDATE items,month SET items.price=month.price WHERE items.id=month.id;
其實(shí)和在select中直接select兩個(gè)表不用寫(xiě)join一樣,這其實(shí)也是join,只是是inner join的一種簡(jiǎn)寫(xiě)。那么更新還可以更新自身列:
UPDATE t1 SET counting = counting + 1 where id = 2;
列值這樣自增是實(shí)際開(kāi)發(fā)中一個(gè)很常用的技巧,用在計(jì)數(shù)統(tǒng)計(jì)時(shí)候非常方便,而且也免得需要自己去面對(duì)先讀后寫(xiě)在并發(fā)沖突時(shí)候引起的值覆蓋問(wèn)題。然后還可以加order by和limit來(lái)做只更新符合條件的前幾個(gè):
UPDATE t SET counting = counting + 1 ORDER BY id DESC LIMIT 10;
同樣上面這個(gè)自增自身的例子,有些特殊的情況很有意思,即當(dāng)要更新的主鍵自增id。那么如果不加order by直接更新的話:
UPDATE t SET id = id + 1; -- 這是錯(cuò)誤的
會(huì)報(bào)id沖突的錯(cuò)誤,無(wú)法執(zhí)行。增加了order by就可以順利執(zhí)行了:
UPDATE t SET id = id + 1 ORDER BY id DESC;
一定要提醒的是,DELETE和UPDATE一定記得加限定條件,否則很容易就可能釀成一樁慘案,因?yàn)閿?shù)據(jù)庫(kù)需要保證MVCC(Multiversion concurrency control,是事務(wù)的基礎(chǔ)),這類(lèi)更新操作的開(kāi)銷(xiāo)很大甚至需要鎖表。筆者自己在線上數(shù)據(jù)庫(kù)做這些操作包括SELECT時(shí)候手已經(jīng)都已經(jīng)形成了下意識(shí),一定會(huì)先寫(xiě)下where條件,Ctrl-A再開(kāi)始寫(xiě)update,select。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/17673.html
閱讀 1815·2021-09-28 09:43
閱讀 1159·2021-09-23 11:22
閱讀 2776·2021-09-14 18:05
閱讀 1851·2019-08-30 15:52
閱讀 2847·2019-08-30 10:55
閱讀 2045·2019-08-29 16:58
閱讀 1382·2019-08-29 16:37
閱讀 3066·2019-08-29 16:25