引言
刪除數(shù)據(jù)庫記錄是一個(gè)非常常見的需求斯够,當(dāng)數(shù)據(jù)失去價(jià)值時(shí)絮短,我們便會(huì)刪除它江兢,但是如果操作不當(dāng),往往就會(huì)把一些有價(jià)值的數(shù)據(jù)誤刪掉丁频,造成重要數(shù)據(jù)的丟失杉允,合理采用刪除方式才能更好地利用數(shù)據(jù)資源,下面介紹幾種常用的刪除方式席里。
刪除方式
物理刪除
物理刪除就是直接從數(shù)據(jù)庫中刪除一條或多條記錄叔磷,將數(shù)據(jù)從磁盤上擦除,可以使用DELETE FROM
SQL語句實(shí)現(xiàn)奖磁,這種方式產(chǎn)生的后果就是記錄永久性刪除世澜,無法找回,一般適用于小型或數(shù)據(jù)重要性不高的項(xiàng)目署穗,可以提高數(shù)據(jù)庫資源利用率寥裂。物理刪除方式是一種最簡(jiǎn)單最基本的數(shù)據(jù)刪除方式,這里不多做介紹案疲,我們主要來看一下邏輯刪除方式封恰。
邏輯刪除
所謂的邏輯刪除就是實(shí)現(xiàn)記錄已刪除的效果,但實(shí)際上數(shù)據(jù)仍然存在于數(shù)據(jù)庫中褐啡,只是對(duì)用戶隱藏這一部分?jǐn)?shù)據(jù)诺舔。一些大型的、數(shù)據(jù)關(guān)聯(lián)性高备畦、數(shù)據(jù)重要性高的應(yīng)用往往會(huì)采用這種刪除方式低飒,它可以實(shí)現(xiàn)回收站、刪除恢復(fù)懂盐、查看歷史版本等實(shí)用功能褥赊,根據(jù)業(yè)務(wù)的需要有不同的應(yīng)用場(chǎng)景。
應(yīng)用場(chǎng)景
例如莉恼,在一些郵箱應(yīng)用中拌喉,當(dāng)你刪除一條郵件時(shí),不會(huì)將郵件直接刪除俐银,而是把郵件移動(dòng)到回收站囊卜,你可以在回收站中對(duì)郵件進(jìn)行恢復(fù)内颗、徹底刪除等操作戚长,可以有效防止誤刪等情況晋被。
再比如博客管理平臺(tái)一般都會(huì)提供查看修改歷史、比較歷史版本等功能,我們可以方便地查看文章的修改歷史汽久,以及恢復(fù)到之前某一版本茴晋。
實(shí)現(xiàn)思路
標(biāo)記刪除
采用刪除標(biāo)記的方式可以很容易地實(shí)現(xiàn)邏輯刪除功能,通過在表中添加一個(gè)刪除標(biāo)記字段回窘,將正常記錄的該字段設(shè)置為0诺擅,已刪除記錄的該字段設(shè)置為1,查詢時(shí)添加一個(gè)where
條件篩選刪除標(biāo)記為0的記錄啡直,就可以實(shí)現(xiàn)邏輯刪除的功能烁涌,此時(shí)的刪除業(yè)務(wù)只需要將記錄的刪除標(biāo)記字段修改為1即可。
拉鏈
拉鏈方式來源于數(shù)據(jù)倉庫酒觅,是針對(duì)數(shù)據(jù)倉庫設(shè)計(jì)中表存儲(chǔ)數(shù)據(jù)的方式而定義的撮执,所謂拉鏈,就是記錄歷史舷丹,記錄一個(gè)事物從開始到當(dāng)前狀態(tài)的所有變化信息抒钱。拉鏈算法是目前數(shù)據(jù)倉庫領(lǐng)域最典型的算法之一。
這種方式的表結(jié)構(gòu)與普通表的區(qū)別在于多了兩個(gè)字段(START_DATE
&END_DATE
)表示記錄的有效時(shí)間颜凯,分別為記錄添加時(shí)間和記錄最大有效時(shí)間谋币。
- 數(shù)據(jù)表采用聯(lián)合主鍵的方式,使用
id
和START_DATE
來唯一的表示某條記錄症概,如:
CREATE TABLE `table_name` (
`id` INT NOT NULL AUTO_INCREMENT,
`start_date` datetime NOT NULL,
`end_date` datetime NOT NULL,
...,
primary key(`id`,`start_date`)
)ENGINE=MYISAM DEFAULT CHARSET=utf8;
- 新增記錄時(shí)
START_DATE
可設(shè)置為當(dāng)前時(shí)間蕾额,END_DATE
設(shè)置為null或未來某個(gè)時(shí)間來表示無窮大,如:
insert into table_name(start_date,end_date,...) values(當(dāng)前時(shí)間,一百年后,...);
- 查詢數(shù)據(jù)時(shí)只要對(duì)日期進(jìn)行篩選就可得到當(dāng)前有效的記錄彼城,例如
select * from table_name where id=記錄ID and start_date<=當(dāng)前時(shí)間 and end_date>當(dāng)前時(shí)間;
- 修改記錄的方式與傳統(tǒng)方式不同诅蝶,修改操作并不是直接修改數(shù)據(jù)庫中的某條記錄,而是把修改的原有效記錄的
END_DATE
設(shè)置為當(dāng)前時(shí)間,接下來新增一條完整的募壕、修改后的記錄调炬,如:
update table_name set end_date=當(dāng)前時(shí)間 where id=原記錄ID and end_date=一百年后;
insert into table_name(id,start_date,end_date,...) values(原記錄ID,當(dāng)前時(shí)間,一百年后,...);
- 刪除操作很簡(jiǎn)單,不是真的將記錄從數(shù)據(jù)表中移除舱馅,只需把記錄的
END_DATE
設(shè)置為當(dāng)前時(shí)間即可缰泡,如:
update table_name set end_date=當(dāng)前時(shí)間 where id=刪除記錄ID;
- 通過這種方式可以完整地記錄下數(shù)據(jù)的變化情況,使用下面的查詢語句就可以獲取某條記錄的完整版本列表以及查看特定版本的內(nèi)容:
-- 獲取版本列表
select start_date from table_name where id=記錄ID order by start_date;
-- 查看特定版本內(nèi)容
select * from table_name where id=記錄ID and start_date=版本日期;
寫在最后
不同的業(yè)務(wù)需要根據(jù)其應(yīng)用場(chǎng)景來選擇合適的數(shù)據(jù)刪除方式习柠,一般的應(yīng)用可以采用物理刪除的方式匀谣,簡(jiǎn)單粗暴地將數(shù)據(jù)擦除照棋,這樣可以有效提高數(shù)據(jù)庫地利用率资溃,如果歷史數(shù)據(jù)一點(diǎn)價(jià)值都沒有或者價(jià)值不高,那還留著干什么烈炭,這時(shí)如果采用邏輯刪除地方式反而加重了數(shù)據(jù)庫的負(fù)擔(dān)溶锭,浪費(fèi)了大量寶貴的資源。但是有些項(xiàng)目如金融符隙、交通趴捅、能源等領(lǐng)域的歷史數(shù)據(jù)垫毙,往往具有很高的利用價(jià)值,通過對(duì)這些數(shù)據(jù)進(jìn)行分析總結(jié)拱绑,可以更好的了解該領(lǐng)域的發(fā)展情況和健康程度综芥,以及對(duì)未來的發(fā)展規(guī)劃起到一定指導(dǎo)作用,這時(shí)就要采用邏輯刪除的方式猎拨,雖然數(shù)據(jù)管理平臺(tái)為了便于管理膀藐,刪除了過期的數(shù)據(jù),但數(shù)據(jù)分析系統(tǒng)仍能從數(shù)據(jù)庫中獲取到歷史數(shù)據(jù)红省,通過抽取轉(zhuǎn)換加載的過程额各,將歷史數(shù)據(jù)轉(zhuǎn)化為高價(jià)值的內(nèi)容,這是目前信息技術(shù)發(fā)展的主要趨勢(shì)吧恃。
本文為作者kMacro原創(chuàng)虾啦,轉(zhuǎn)載請(qǐng)注明來源:http://www.reibang.com/p/b22b7bc207a6。