前言
今天在进行后端代码维护的时候,有一条数据怎么也删除不了,在MySQL里面一直存在。我旁边的同事随口说了一句,你看看是不是软删除的缘故导致MySQL里面的数据一直删除不了。之后在我搜索对应资料之后才知道软删除以及对应的硬删除是什么。以下是我对软删除和硬删除的理解,如果不对,恳请斧正。
小结
在数据库操作之中,软删除和硬删除是两种常见的删除策略,它们的主要区别就是数据是否真的从MySQL数据库类里面删除掉了。
硬删除
硬删除是指直接从数据库表中删除记录,数据一旦删除,就无法恢复(其实也不是不可以恢复,但是要通过日志来恢复,)。硬删除是最直接的删除方式,我们平常在后端开发之中用到删除就是硬删除。我现在用的xorm框架举一个例子。
type User struct {
Id int64 `xorm:"pk autoincr"`
Name string `xorm:"not null"`
}
//DB为 *xorm.Engine,执行硬删除代码
_,err:=DB.ID(id).Delete(&User{})
if err!=nil{
log.Fatal(err)
}
上面的就是硬删除操作。
软删除
软删除是指通过标记的方式“删除”数据,而不是实际删除它。通常,会在表中添加一个用于标记删除的字段(例如 is_deleted
、deleted_at
、status
等),然后通过更新该字段来标记数据为已删除。这意味着数据在数据库中仍然存在,只是逻辑上被标记为删除状态,因此可以在后续的操作中恢复。 我们还是举一个例子。
type User struct {
Id int64 `xorm:"pk autoincr"`
Name string `xorm:"not null"`
IsDeleted bool `xorm:"default false"` // 软删除标志字段
}
//DB为 *xorm.Engine,执行硬删除代码
_, err := engine.ID(id).Update(&User{IsDeleted: true})
if err!=nil{
log.Fatal(err)
}
在此后的查询的过程之中,通过加一个where或则是And筛选条件就可以过滤掉已删除的记录 ,或者 在 xorm 中,通过设置字段的标签为 xorm:"deleted"
,你可以简化软删除的实现,并通过全局过滤自动忽略软删除的记录 。
为什么要软删除?
看到这里,有些同学可能要问了,我为什么要软删除呢?这不是白白的占用我的MySQL存储空间嘛?我给你举几个业务场景你就知道了。
1.内容管理系统(CMS)
我们在对文章、图片的删除通常是软删除, 当用户删除文章时,内容不会立即从数据库中删除,而是被标记为已删除。这允许管理员恢复误删除的内容,并且保留内容的历史记录。当用户点击恢复的时候,就将IsDeleted这个字段更新为false,这样在文章列表之中就又能展示出来了。
2.电子商务平台
在电商平台中,订单的删除通常会采用软删除。当订单被取消或删除时,数据仍然保留在系统中,但对用户不可见。这有助于后续分析,例如统计被取消的订单、退款数据等。
3. 敏感数据管理
某些行业(如医疗、金融、政府等)有严格的合规性要求,需要保留所有历史数据,包括删除的数据。软删除可以让数据在逻辑上“消失”,不展现给用户,但仍然保留在数据库中,以便随时审计和合规检查。
个人在思考时候的疑问
**疑问:**既然软删除只是在逻辑上删除了数据,但是在物理层面,数据还是真真切切的存在在MySQL里面的,这样不就严重的占用了MySQL的存储空间了嘛?
答:现在想一想,嫌占用存储空间,咱们定期硬删除那些已经被标记为软删除的数据就行了嘛。我现在的一个思路就是,在设计表结构的时候,增加一个时间戳字段,然后设置一个定时任务,根据当前的时间戳来判断是否已经到删除时间了。这样子就可以进行定期的删除了。
type User struct {
Id int64 `xorm:"pk autoincr"`
Name string `xorm:"not null"`
IsDeleted bool `xorm:"default false"`// 软删除标志字段
Deleted int64 `xorm:"deleted"`
}
//DB为 *xorm.Engine,执行硬删除代码
_, err := engine.ID(id).Update(&User{IsDeleted: true})
if err!=nil{
log.Fatal(err)
}
总结:
软删除非常适用于需要保留数据历史、支持数据恢复、符合合规要求或具有审计需求的场景。它为系统提供了更多的灵活性和安全性,避免了数据的彻底丢失。在很多数据敏感的业务中,软删除是一个非常实用的功能。