深度分析DROP,TRUNCATE与DELETE的区别【我的数据库之路系列】
轉(zhuǎn)載自:http://hi.baidu.com/bjn_wuming/blog/item/8b27a9af36ef26f6faed5077.html
?? 很久不發(fā)文章了,實(shí)際上前2個(gè)星期有點(diǎn)忙的過(guò)頭了,現(xiàn)在正處于前一個(gè)需求剛結(jié)束,后一個(gè)還沒(méi)來(lái)的真空休閑期,早就想要發(fā)點(diǎn)東西,但是光研究DUMP就花了我2天半。。下面正題
-----------------------------------------------------------------------------------------------------
這次特意從數(shù)據(jù)庫(kù)塊的層次深度分析一下DROP,TRUNCATE和DELETE的區(qū)別:
???? 在此之前先為那些初學(xué)數(shù)據(jù)庫(kù)的童鞋們闡述2個(gè)概念,如果你還沒(méi)有真正理解這2個(gè)概念那也請(qǐng)你看完:DML語(yǔ)句與DDL語(yǔ)句。
簡(jiǎn)單的DML與DDL概念:
???? 我們不去重復(fù)那些抽象又沒(méi)用的概念,簡(jiǎn)單的說(shuō)DML語(yǔ)句就是增刪改(INSERT,DELETE,UPDATE),DDL就是對(duì)數(shù)據(jù)庫(kù)對(duì)象操作的語(yǔ)句(CREATE,DROP,TRUNCATE)等,何為數(shù)據(jù)庫(kù)對(duì)象:數(shù)據(jù)庫(kù)商們將表,索引,視圖,同義詞等都稱為數(shù)據(jù)庫(kù)對(duì)象。所以區(qū)分DDL和DML的方法其實(shí)在語(yǔ)句字面上就可以看到,DDL語(yǔ)句都是在動(dòng)作+對(duì)象的格式,比如great是動(dòng)作,說(shuō)明要?jiǎng)?chuàng)建什么,table就是對(duì)象,所以create table就是DDL,其他的DDL同樣,沒(méi)注意過(guò)的可以去看一看。DML語(yǔ)句則是動(dòng)作+具體的對(duì)象名,比如insert into + 表明等,相信大家從來(lái)也沒(méi)有見過(guò)insert table,update table這樣的寫法吧?我甚至還能肯定很多人曾因?qū)懗鰀elete table這樣的語(yǔ)法而被報(bào)錯(cuò)。
深度的DML與DDL概念:
???? 如果你有數(shù)據(jù)庫(kù)體系結(jié)構(gòu)的基礎(chǔ),相信你一定不會(huì)對(duì)上面提出的那個(gè)概念感興趣,那么這里就給你一個(gè)真正的DML與DDL的概念:
?????
???? 所有對(duì)數(shù)據(jù)文件中的數(shù)據(jù)的操作就稱為DML語(yǔ)句,所有對(duì)數(shù)據(jù)字典表的操作為DDL語(yǔ)句。
?????
???? 何為數(shù)據(jù)字典表?你可以去網(wǎng)上查一查研究一下,我只給以個(gè)略通俗的解釋,數(shù)據(jù)庫(kù)在啟動(dòng)的時(shí)候會(huì)先連接上數(shù)據(jù)字典表,這些表(不是一張)里存放了上面說(shuō)的數(shù)據(jù)庫(kù)對(duì)象的基本信息,比如表的表名,表對(duì)應(yīng)的存放數(shù)據(jù)的數(shù)據(jù)文件的名字和在操作系統(tǒng)中的具體位置等等,我們平時(shí)所寫的查詢語(yǔ)句就是數(shù)據(jù)庫(kù)先通過(guò)數(shù)據(jù)字典表找到SQL中的表的位置,然后才能從中查詢數(shù)據(jù),也就是說(shuō),如果數(shù)據(jù)字典表中沒(méi)有你建的表的信息,那么你的SQL就不可能查到這張表,就會(huì)報(bào)出找不到表的錯(cuò)誤。
????
???? 注意上面給出的數(shù)據(jù)字典的概念很重要,理解了才能真正明白后面的結(jié)論。
PS:SELECT語(yǔ)句不屬于DML和DDL語(yǔ)句,它是DQL語(yǔ)句,看名字就知道了,其中的Q是QUERY查詢的意思,但有人也喜歡把它分到DML里,理論上說(shuō)它確實(shí)也是對(duì)數(shù)據(jù)的操作。
???? 雖然能夠查到這個(gè)文章的各位應(yīng)該都知道DROP,TRUNCATE和DELETE的效果是什么,但還是稍微解釋一下,效果上就是TRUNCATE和DELETE都可以把數(shù)據(jù)刪除,TRUNCATE只能一次刪除所有數(shù)據(jù)且不能回滾,DELETE則可以選擇性的刪數(shù)據(jù),刪除之后如果后悔還有一次回滾不提交結(jié)果的機(jī)會(huì)。而DROP當(dāng)然是直接刪表(或者其他對(duì)象)。
????????
????接下來(lái)就是重點(diǎn)了,我在這里直接給出核心結(jié)論,看完結(jié)論后如果對(duì)后面的測(cè)試過(guò)程部分實(shí)在不感興趣的童鞋們就可以不用看了:
??????????
???? TRUNCATE和DROP是不真正刪除表中數(shù)據(jù)的,也就是說(shuō)即便你用TRUNCATE達(dá)到了刪數(shù)據(jù)的效果,甚至用DROP看似刪掉了那張表,其中的數(shù)據(jù)實(shí)際上還存在于數(shù)據(jù)文件上,那些數(shù)據(jù)會(huì)在下次新的數(shù)據(jù)進(jìn)來(lái)的時(shí)候被覆蓋掉。
??????????
???? DELETE也不是立刻就刪除數(shù)據(jù)的,但它對(duì)數(shù)據(jù)文件中的數(shù)據(jù)的標(biāo)志位做個(gè)一個(gè)改動(dòng)(添加了一個(gè)‘D’),這些數(shù)據(jù)就代表被刪除了,下次數(shù)據(jù)塊重組的時(shí)候就會(huì)被刪掉。
??????????
???? 解釋以上問(wèn)題的原因就在于剛才提到的,DROP和TRUNCATE是DDL語(yǔ)句,它們只對(duì)數(shù)據(jù)字典表中的關(guān)于這個(gè)表的某個(gè)值做了改動(dòng),所以如果你愿意實(shí)驗(yàn)下的話就會(huì)發(fā)現(xiàn),無(wú)論數(shù)據(jù)有幾億幾十億幾百億,DROP和TRUNCATE的速度都非常快,原因就是他們只需要改數(shù)據(jù)字典表,不會(huì)去動(dòng)實(shí)際的數(shù)據(jù)。
??????????
???? 之后關(guān)于TRUNCATE修改高水位線的問(wèn)題大家想必也就清楚了,高水位線記錄了最后一條數(shù)據(jù)在磁盤中的物理位置(地址),這個(gè)地址就存在數(shù)據(jù)字典表中,TRUNCATE只是去修改這個(gè)值,而DROP是刪除數(shù)據(jù)字典表中與該表有關(guān)的幾條數(shù)據(jù)。
???? 下面就以oracle數(shù)據(jù)庫(kù)為例,來(lái)讓我們來(lái)用測(cè)試證明DDL確實(shí)沒(méi)有對(duì)數(shù)據(jù)進(jìn)行任何改動(dòng),在這里我只使用TRUNCATE和DELETE證明,DROP和TRUNCATE是一樣的所以不再做重復(fù)實(shí)驗(yàn):
???????
首先,為了方便測(cè)試,我創(chuàng)建了一個(gè)比較小的表空間,注意只能在授權(quán)用戶或是DBA用戶下創(chuàng)建:
create tablespace ttt??
logging????????????????????????????????????????????????????? --創(chuàng)建重做日志,反之則寫成nologging
datafile 'D:\oracle\oradata\Oracle9i\user_data.dbf'??? --指定表空間的路徑和文件,文件會(huì)自動(dòng)創(chuàng)建的
size 1m???????????????????????????? --指定表空間的初始大小,我們就用1M就夠了
autoextend on??????????????????????????????????????????????? --支持表空間自動(dòng)擴(kuò)展
next 1m maxsize 20m??????????????? --表空間擴(kuò)展時(shí)每次擴(kuò)展的空間大小以及最大空間上限
extent management local??????????????????????????????????? --規(guī)定區(qū)大小由系統(tǒng)自動(dòng)確定
AUTO;?????????????????????????????????????????? --只能使用在本地管理的表空間中,由LOCAL管理表空間時(shí),數(shù)據(jù)塊中的空閑空間增加或減少后,其新狀態(tài)都會(huì)在位圖中反映出來(lái),以便更好的自動(dòng)管理,對(duì)含LOB字段的表無(wú)效
表空間建好后,我們就可以在這個(gè)表空間上建表:
SQL> CREATE TABLE ttt(
2???????? a_id number,
3???????? b_char varchar2(100)
4 ) tablespace space_t;
表已創(chuàng)建。
這里說(shuō)一個(gè)分支問(wèn)題,有人會(huì)想通過(guò)數(shù)據(jù)字典表來(lái)查看表空間中的數(shù)據(jù)是否真的刪除或存在,但實(shí)際上是沒(méi)有效果的,數(shù)據(jù)字典表是從數(shù)據(jù)庫(kù)的角度去記錄表的信息,所以你TRUNCATE后就算數(shù)據(jù)存在,數(shù)據(jù)字典表依然會(huì)寫成不存在,比如用如下語(yǔ)句可以計(jì)算出表空間的使用情況,但不能說(shuō)明數(shù)據(jù)是否還存在于數(shù)據(jù)文件中:
select
b.file_name 物理文件名,
b.tablespace_name 表空間,
b.bytes/1024/1024 大小M,
(b.bytes-sum(nvl(a.bytes,0)))/1024/1024 已使用M,
substr((b.bytes-sum(nvl(a.bytes,0)))/(b.bytes)*100,1,5) 利用率
from dba_free_space a,dba_data_files b
where a.file_id=b.file_id
group by b.tablespace_name,b.file_name,b.bytes
order by b.tablespace_name;
我們?cè)倩氐秸},用下面的語(yǔ)句我們可以看到表空間所在的數(shù)據(jù)文件的ID號(hào)和你建的表的表頭處于第幾個(gè)塊,當(dāng)然用上面那條SQL語(yǔ)句中的2個(gè)表也可以看到他們表空間所在的數(shù)據(jù)文件號(hào):
select t.header_file,t.header_block from dba_segments t
where t.segment_name='TTT';??????????? --要特別注意里面的名字要大寫,數(shù)據(jù)字典表會(huì)把你的表名等信息都變成大寫存起來(lái)
HEADER_FILE HEADER_BLOCK
----------- ------------
????????? 6?????????? 19
我們看到數(shù)據(jù)文件號(hào)為6,表頭信息所在塊為第19個(gè),但是,我們插入數(shù)據(jù)的時(shí)候不能確定數(shù)據(jù)就在第20塊上,因?yàn)锳SSM會(huì)通過(guò)特定算法來(lái)決定你的數(shù)據(jù)存在哪個(gè)塊上,你可以通過(guò)數(shù)據(jù)的ROWID去算它的數(shù)據(jù)塊,當(dāng)然也可以用土方法往后一個(gè)一個(gè)找,一般來(lái)說(shuō)數(shù)據(jù)的數(shù)據(jù)塊應(yīng)該不會(huì)離表頭所在塊很遠(yuǎn),比我新插的數(shù)據(jù)就在第21個(gè)上。怎么一個(gè)個(gè)的確定?要么用"segment management manual"將ASSM變成MSSM,要么就挨個(gè)DUMP吧。。后面我解釋怎么DUMP數(shù)據(jù)塊
插入數(shù)據(jù):
SQL> INSERT INTO ttt VALUES(1,'sdkjaskdhksdhdsf');
已創(chuàng)建 1 行
SQL> INSERT INTO ttt VALUES(1,'sdkjaskdhksdhdsasdassadf');
已創(chuàng)建 1 行
SQL> commit;
提交完成
DUMP數(shù)據(jù)塊的語(yǔ)句如下,如果你想DUMP別的,語(yǔ)法去網(wǎng)上可以查到,我這里不解釋了:
SQL> alter system dump datafile 6 block 20;
系統(tǒng)已更改
看到上面的語(yǔ)句就是我剛才查出來(lái)的對(duì)應(yīng)的文件號(hào)和存放表頭信息的塊的后一個(gè)塊,存表頭信息的塊一般是不存數(shù)據(jù)的。
DUMP結(jié)束后我們?nèi)?duì)應(yīng)的控制文件中找結(jié)果,以.trc結(jié)尾,別找錯(cuò)了不是.dmp結(jié)尾的文件。
我的路徑在下面,你們的路徑可以根據(jù)我的大概找一找:
C:\oracle\product\10.2.0\admin\orcl\udump\orcl_ora_4984.trc
打開后里面會(huì)有這樣的信息:
*** 2010-07-02 14:26:21.484
Start dump data blocks tsn: 7 file#: 6 minblk 20 maxblk 20
buffer tsn: 7 rdba: 0x01800014 (6/20)
scn: 0x0000.003eeda7 seq: 0x01 flg: 0x00 tail: 0xeda70601
frmt: 0x02 chkval: 0x0000 type: 0x06=trans data
Hex dump of block: st=0, typ_found=1
Dump of memory from 0x07C12200 to 0x07C14200
7C12200 0000A206 01800014 003EEDA7 00010000 [..........>.....]
7C12210 00000000 00000001 0000D7A7 003EED64 [............d.>.]
7C12220 00000000 00320002 01800011 00000000 [......2.........]
7C12230 00000000 00000000 00000000 00000000 [................]
??????? Repeat 2 times
7C12260 00000000 00000000 000EFFFF 1F8A1F98 [................]
7C12270 00001F8A 00000000 00000000 00000000 [................]
7C12280 00000000 00000000 00000000 00000000 [................]
??????? Repeat 502 times
7C141F0 00000000 00000000 00000000 EDA70601 [................]
Block header dump: 0x01800014
Object id on Block? Y
seg/obj: 0xd7a7 csc: 0x00.3eed64 itc: 2 flg: E typ: 1 - DATA
???? brn: 0 bdba: 0x1800011 ver: 0x01 opc: 0
???? inc: 0 exflg: 0
Itl?????????? Xid????????????????? Uba???????? Flag Lck??????? Scn/Fsc
0x01?? 0x0000.000.00000000 0x00000000.0000.00 ----??? 0 fsc 0x0000.00000000
0x02?? 0x0000.000.00000000 0x00000000.0000.00 ----??? 0 fsc 0x0000.00000000
data_block_dump,data header at 0x7c12264
===============
tsiz: 0x1f98
hsiz: 0xe
pbl: 0x07c12264
bdba: 0x01800014
???? 76543210
flag=--------
ntab=0
nrow=0
frre=-1
fsbo=0xe
fseo=0x1f98
avsp=0x1f8a
tosp=0x1f8a
block_row_dump:
end_of_block_dump
End dump data blocks tsn: 7 file#: 6 minblk 20 maxblk 20
在我們現(xiàn)在的話題里大家不需要對(duì)上面的東西了解太多,注意看標(biāo)紅的地方的nrow=0說(shuō)明了這個(gè)塊是個(gè)空塊,我插入的數(shù)據(jù)沒(méi)在這個(gè)塊里,這就驗(yàn)證上面說(shuō)的插入的數(shù)據(jù)不一定緊跟在表頭之后,那我們就去DUMP下一個(gè)塊看看(好土的窮舉法-_-!)
步驟同上:
SQL> alter system dump datafile 6 block 21;
系統(tǒng)已更改。
*** 2010-07-02 14:28:56.203
Start dump data blocks tsn: 7 file#: 6 minblk 21 maxblk 21
buffer tsn: 7 rdba: 0x01800015 (6/21)
scn: 0x0000.003eeddc seq: 0x02 flg: 0x06 tail: 0xeddc0602
frmt: 0x02 chkval: 0xa204 type: 0x06=trans data
Hex dump of block: st=0, typ_found=1
Dump of memory from 0x07C12200 to 0x07C14200
7C12200 0000A206 01800015 003EEDDC 06020000 [..........>.....]
7C12210 0000A204 00000001 0000D7A7 003EED64 [............d.>.]
7C12220 00000000 00320002 01800011 00010006 [......2.........]
7C12230 00000536 0080215D 000104C2 00002001 [6...]!....... ..]
7C12240 003EEDA7 00030009 0000056C 00800343 [..>.....l...C...]
7C12250 003203B8 00002001 003EEDDC 00000000 [..2.. ....>.....]
7C12260 00000000 00020100 0016FFFF 1F4C1F62 [............b.L.]
7C12270 00001F4C 1F810002 00001F62 00000000 [L.......b.......]
7C12280 00000000 00000000 00000000 00000000 [................]
??????? Repeat 499 times
7C141C0 00000000 022C0000 02C10202 6B647318 [......,......sdk]
7C141D0 6B73616A 736B6864 73646864 61647361 [jaskdhksdhdsasda]
7C141E0 64617373 02012C66 1002C102 6A6B6473 [ssadf,......sdkj]
7C141F0 646B7361 64736B68 66736468 EDDC0602 [askdhksdhdsf....]
Block header dump: 0x01800015
Object id on Block? Y
seg/obj: 0xd7a7 csc: 0x00.3eed64 itc: 2 flg: E typ: 1 - DATA
???? brn: 0 bdba: 0x1800011 ver: 0x01 opc: 0
???? inc: 0 exflg: 0
Itl?????????? Xid????????????????? Uba???????? Flag Lck??????? Scn/Fsc
0x01?? 0x0006.001.00000536 0x0080215d.04c2.01 --U-??? 1 fsc 0x0000.003eeda7
0x02?? 0x0009.003.0000056c 0x00800343.03b8.32 --U-??? 1 fsc 0x0000.003eeddc
data_block_dump,data header at 0x7c12264
===============
tsiz: 0x1f98
hsiz: 0x16
pbl: 0x07c12264
bdba: 0x01800015
???? 76543210
flag=--------
ntab=1
nrow=2
frre=-1
fsbo=0x16
fseo=0x1f62
avsp=0x1f4c
tosp=0x1f4c
0xe:pti[0] nrow=2 offs=0
0x12:pri[0] offs=0x1f81
0x14:pri[1] offs=0x1f62
block_row_dump:
tab 0, row 0, @0x1f81
tl: 23 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 02
col 1: [16] 73 64 6b 6a 61 73 6b 64 68 6b 73 64 68 64 73 66
tab 0, row 1, @0x1f62
tl: 31 fb: --H-FL-- lb: 0x2 cc: 2
col 0: [ 2] c1 02
col 1: [24]
73 64 6b 6a 61 73 6b 64 68 6b 73 64 68 64 73 61 73 64 61 73 73 61 64 66
end_of_block_dump
End dump data blocks tsn: 7 file#: 6 minblk 21 maxblk 21
看一看上面的信息,我們從標(biāo)紅的地方可以看出,數(shù)據(jù)在數(shù)據(jù)塊中以從后往前的形式確實(shí)存進(jìn)去了,下面開始正式測(cè)試,為了節(jié)省字?jǐn)?shù),在下面的實(shí)驗(yàn)過(guò)程中,我將省略掉標(biāo)紅部分以外的信息。
首先我們從DELETE開始:
SQL> delete from ttt;
已刪除2行。
SQL> commit;
提交完成。
SQL> alter system dump datafile 6 block 21;
系統(tǒng)已更改。
7C141C0 00000000 013C0000 02C10202 6B647318 [......<......sdk]
7C141D0 6B73616A 736B6864 73646864 61647361 [jaskdhksdhdsasda]
7C141E0 64617373 02013C66 1002C102 6A6B6473 [ssadf<......sdkj]
7C141F0 646B7361 64736B68 66736468 EE950601 [askdhksdhdsf....]
...
nrow=2
...
block_row_dump:
tab 0, row 0, @0x1f81
tl: 2 fb: --HDFL-- lb: 0x1
tab 0, row 1, @0x1f62
tl: 2 fb: --HDFL-- lb: 0x1
end_of_block_dump
End dump data blocks tsn: 7 file#: 6 minblk 21 maxblk 21
注意看上面,DELETE后雖然在上面看數(shù)據(jù)還在,nrow顯示也為2行,但下面則對(duì)其做了修改,在原來(lái)--H-FL--的位置增加了一個(gè)標(biāo)志位'D',在其后面該行的信息也被清理了,這些就是標(biāo)志信息,原本的數(shù)據(jù)則會(huì)在下次數(shù)據(jù)塊進(jìn)行重組的時(shí)候清理掉,或者被滿足某些條件的新信息進(jìn)入的時(shí)候覆蓋掉。
下面我們來(lái)看一下TRUNCATE,我再插入2條數(shù)據(jù)
SQL> INSERT INTO ttt VALUES(1,'aaaaaaaaaaaaaaaa');
已創(chuàng)建 1 行。
SQL> INSERT INTO ttt VALUES(1,'aaaaaaaaaaaaaaaa');
已創(chuàng)建 1 行。
SQL> commit;
提交完成。
SQL> alter system dump datafile 6 block 21;
系統(tǒng)已更改。
7C14190 00000000 00000000 0202022C 611002C1 [........,......a]
7C141A0 61616161 61616161 61616161 2C616161 [aaaaaaaaaaaaaaa,]
7C141B0 C1020202 61611002 61616161 61616161 [......aaaaaaaaaa]
7C141C0 61616161 013C6161 02C10202 6B647318 [aaaaaa<......sdk]
7C141D0 6B73616A 736B6864 73646864 61647361 [jaskdhksdhdsasda]
7C141E0 64617373 02013C66 1002C102 6A6B6473 [ssadf<......sdkj]
7C141F0 646B7361 64736B68 66736468 F2200603 [askdhksdhdsf.. .]
...
nrow=4
...
block_row_dump:
tab 0, row 0, @0x1f81
tl: 2 fb: --HDFL-- lb: 0x1
tab 0, row 1, @0x1f62
tl: 2 fb: --HDFL-- lb: 0x1
tab 0, row 2, @0x1f4b
tl: 23 fb: --H-FL-- lb: 0x2 cc: 2
col 0: [ 2] c1 02
col 1: [16] 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
tab 0, row 3, @0x1f34
tl: 23 fb: --H-FL-- lb: 0x2 cc: 2
col 0: [ 2] c1 02
col 1: [16] 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
end_of_block_dump
End dump data blocks tsn: 7 file#: 6 minblk 21 maxblk 21
DELETE的數(shù)據(jù)沒(méi)有被覆蓋掉有很多原因,其中上面提到的數(shù)據(jù)庫(kù)的高水位線問(wèn)題就是其中之一,它記錄了最末尾的記錄的位置,所以新數(shù)據(jù)不會(huì)覆蓋原數(shù)據(jù)而是在其之后插入。
然后我們TRUNCATE一下看看:
SQL> truncate table ttt;
表被截?cái)唷?br />SQL> alter system dump datafile 6 block 21;
系統(tǒng)已更改。
7C14190 00000000 00000000 0202022C 611002C1 [........,......a]
7C141A0 61616161 61616161 61616161 2C616161 [aaaaaaaaaaaaaaa,]
7C141B0 C1020202 61611002 61616161 61616161 [......aaaaaaaaaa]
7C141C0 61616161 013C6161 02C10202 6B647318 [aaaaaa<......sdk]
7C141D0 6B73616A 736B6864 73646864 61647361 [jaskdhksdhdsasda]
7C141E0 64617373 02013C66 1002C102 6A6B6473 [ssadf<......sdkj]
7C141F0 646B7361 64736B68 66736468 F2200603 [askdhksdhdsf.. .]
...
nrow=4
...
block_row_dump:
tab 0, row 0, @0x1f81
tl: 2 fb: --HDFL-- lb: 0x1
tab 0, row 1, @0x1f62
tl: 2 fb: --HDFL-- lb: 0x1
tab 0, row 2, @0x1f4b
tl: 23 fb: --H-FL-- lb: 0x2 cc: 2
col 0: [ 2] c1 02
col 1: [16] 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
tab 0, row 3, @0x1f34
tl: 23 fb: --H-FL-- lb: 0x2 cc: 2
col 0: [ 2] c1 02
col 1: [16] 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61
end_of_block_dump
End dump data blocks tsn: 7 file#: 6 minblk 21 maxblk 21
看到了嗎?數(shù)據(jù)與之前沒(méi)任何變化,說(shuō)明TRUNCATE沒(méi)有對(duì)數(shù)據(jù)做任何操作,但這時(shí)候你再查詢表中數(shù)據(jù)的時(shí)候會(huì)發(fā)現(xiàn)表是空的。
下面咱們?cè)俅尾迦胍粭l:
SQL> INSERT INTO ttt VALUES(1,'bbbbbbbbbbbbbbb');
已創(chuàng)建 1 行。
SQL> commit;
提交完成。
SQL> alter system dump datafile 6 block 21;
系統(tǒng)已更改。
94A2200 0000A206 01800015 003EF72C 06010000 [........,.>.....]
94A2210 0000AE46 00000001 0000D7A8 003EF72A [F...........*.>.]
94A2220 00000000 00320002 01800011 002D0001 [......2.......-.]
94A2230 00000431 00800197 003101B6 00002001 [1.........1.. ..]
94A2240 003EF72C 00000000 00000000 00000000 [,.>.............]
94A2250 00000000 00000000 00000000 00000000 [................]
94A2260 00000000 00010100 0014FFFF 1F6E1F82 [..............n.]
94A2270 00001F6E 1F820001 00000000 00000000 [n...............]
94A2280 00000000 00000000 00000000 00000000 [................]
??????? Repeat 501 times
94A41E0 00000000 012C0000 02C10202 6262620F [......,......bbb]
94A41F0 62626262 62626262 62626262 F72C0601 [bbbbbbbbbbbb..,.]
...
nrow=1
...
block_row_dump:
tab 0, row 0, @0x1f82
tl: 22 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 2] c1 02
col 1: [15] 62 62 62 62 62 62 62 62 62 62 62 62 62 62 62
end_of_block_dump
End dump data blocks tsn: 7 file#: 6 minblk 21 maxblk 21
這次大家都看明白了吧,顯示的nrow從本來(lái)的4行變成了1行,TRUNCATE重置了高水位線,所以數(shù)據(jù)會(huì)從新插入并蓋掉了之前所有的數(shù)據(jù)
最后重復(fù)一下我們一開始提到的結(jié)論,truncate和drop都是DDL語(yǔ)句,他們只對(duì)數(shù)據(jù)字典表進(jìn)行操作與實(shí)際數(shù)據(jù)無(wú)關(guān),所以執(zhí)行速度很快,原來(lái)的數(shù)據(jù)會(huì)在下一次使用這個(gè)塊的時(shí)候被覆蓋掉,
而DELETE是DML語(yǔ)句,它直接對(duì)數(shù)據(jù)進(jìn)行操作,但并非立刻就刪除數(shù)據(jù),而是先做上標(biāo)志,之后在重組數(shù)據(jù)塊的時(shí)候清除,或者滿足某些條件(如數(shù)據(jù)塊填滿,高水位線重置等)的時(shí)候被新數(shù)據(jù)覆蓋掉。
轉(zhuǎn)載于:https://www.cnblogs.com/qiangqiang/archive/2010/09/19/1831104.html
總結(jié)
以上是生活随笔為你收集整理的深度分析DROP,TRUNCATE与DELETE的区别【我的数据库之路系列】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 备份的误区
- 下一篇: linux cmake编译源码,linu