实战2:如何使用软删除(逻辑删除)
1. 前言
在 Delete 一节中,我们介绍了 的基本,今天我们将以和
实战
的角度来进一步学习 的。
是很危险的操作,试想一下如果开发人员不慎操作失误,误删了一些数据,在数据未备份的情况下,该数据无法恢复,造成了损失绝对是致命的。
道路千万条,安全
第一条。因此为了保证数据的安全性,在真正的企业级应用中都会认的采用逻辑(软)的方式来处理数据。
那么既然软使用如此普遍,它究竟如何使用了?
2. 软与硬
从逻辑的角度上来说,我们可以把分为两大类:软
和硬
。
其实,在很多中,硬也并非直接将数据从磁盘上丢弃,而是通过标志位将该数据标志为已。由于是按页来组织存储数据的,如果硬直接将数据从页中丢弃的话,可能会引起数据页的分裂和重组,这样会大幅降低的。
但是硬的数据可能会被后面的数据覆盖,所以磁盘上也会真正的丢失掉该数据。
软是在程序层面上的,在中数据仍然存在,软常见的有两种实施方案:
整型字段标志位:在数据表deleted
字段来表示记录是否被,0
表示未,1
表示已被。
日期字段标志位:在数据表delete_time
字段来表示记录是否被,null
表示未,有日期
表示已被。
3. 实践
接下来,我们以实践的角度来看看软是如何实现的。
我们仍然以imooc_user
表为例,并deleted
作为逻辑标志位。如下:
DROP TABLE IF EXISTS imooc_user;CREATE TABLE imooc_user( id int PRIMARY KEY, username varchar(), age int, -- 以 deleted 字段作为软位 deleted int NOT NULL DEFAULT );
有了标志位后,我们一条记录:
INSERT INTO imooc_user(id,username,age) VALUES (,'pedro',);
成功后,记录如下:
+----+----------+-----+---------+ | id | username | age | deleted | +----+----------+-----+---------+ | 1 | pedro | 23 | 0 | +----+----------+-----+---------+
其中deleted
字段为0
表示记录正常,当有了标志位后,我们每次数据时都需要上标志位,即:
SELECT * FROM imooc_user WHERE id = AND deleted = ;
当要该记录时,我们不能直接通过 Delete 来了,而是通过 Update:
UPDATE imooc_user SET deleted = WHERE id = ;
软后,我们再次通过语句SELECT * FROM imooc_user WHERE id = 1 AND deleted = 0;
,发现已经查不到该记录了。于是,记录在逻辑上已经了,可它仍在中。
这样,就能在“”数据的情况下保证数据的安全性。
一下imooc_user
表:
DROP TABLE IF EXISTS imooc_user;CREATE TABLE imooc_user( id int PRIMARY KEY, username varchar(), age int, -- 以 delete_time 字段作为软位 delete_time timestamp DEFAULT NULL);
整体上与整形字段标志位相同,如下:
:
INSERT INTO imooc_user(id,username,age) VALUES (,'pedro',);
记录:
SELECT * FROM imooc_user WHERE id = AND delete_time IS NULL;
记录:
UPDATE imooc_user SET delete_time = () WHERE id = ;
你可能会觉得这有些麻烦,没关系不少好用的 ORM 库,如 Hibernate,Sequelize 均已经提供了软,你只需配置一下,就能直接API来达到软的。
4. 小结
若无特殊需求,比如需要记录的具体时间
,我们推荐使用整形字段软,较好。
软不会改变数据页的分布和排列,而硬可能会破坏数据页,从而降低,因此在磁盘容量允许的情况下,首选软。