当前位置: 首页 > article >正文

数据库设计问题记录

唯一性约束和逻辑删除的冲突

问题描述

如果一张表中,存在唯一性约束,比如一些数据中的code,且数据表使用逻辑删除。当删除某行数据的时候,以后再次插入相同code的数据,数据库会报错。

问题分析

在逻辑删除中,数据没有被物理删除,而是用一个deleted字段标记数据已被删除,当查询数据时过滤掉已删除的数据。实际上数据仍保留在数据库中。当插入相同code的数据时,数据库的唯一性约束会限制数据的插入。

PS:如果使用的是mybatis-plus框架,可以通过配置文件开启逻辑删除功能。当查询数据时,会在where条件自动拼接deleted。

解决方案

解决方案是多样的,要基于业务和资源做权衡。由于项目要保持逻辑删除不变(数据是无价的!),解决方案是在有唯一性约束的表中,通过新增一个delete_timestamp字段,组成联合索引。delete_timestamp默认为0,在删除数据时,delete_timestamp赋值。这样,当下次插入的时候,数据库不再单独对code做唯一性校验,而是对code和delete_timestamp组成的联合索引做唯一性校验。由于删除后的delete_timestamp与新增的delete_timestamp必定不同,所以不会再有重复插入数据的报错。如果数据没被删除,新插入相同的code时,由于delete_timestamp都默认是0,所以同样会正常拦截。

PS:对于delete_timestamp字段的操作,建议封装成公共方法。

尽量不使用外键

虽然在学习的过程中,为了理想中的保持数据一致性,外键会经常被提及。但在实际业务开发过程中,非必要不使用外键约束。原因在于外键的使用可能引发一系列数据一致性的问题。比如在表中做增删改操作时,如果表字段使用了外键,要同时考虑外键所在表的数据一致性问题。这些问题会非常频繁地出现,而且解决起来会大大增加业务代码的复杂度,增加了维护成本和风险。

不使用外键,但又有相关需求,需要在一张表中存入另一张表的主键,如何实现?这种情况可直接通过业务代码控制,在插入数据时,先查询到相应的数据再插入。当然这不可避免难以保持数据一致性,但比起要保持数据一致性付出的代价,在业务层处理的成本要低得多。

总结

在数据库中建立的数据约束,都应该在业务层的时候做好相关校验,让错误在业务层被拦截并抛出,这样做有助于数据被定位和友好提示。数据库约束,是最后一道防线。


http://www.kler.cn/a/458259.html

相关文章:

  • uniapp3 手写签名组件(vue3 语法)封装与应用
  • 爬虫代码中如何添加异常处理?
  • 2024年中国新能源汽车用车发展怎么样 PaperGPT(二)
  • latex 尖括号怎么写 编译出来是问号
  • Matlab Hessian矩阵计算
  • OpenLinkSaas使用手册-项目外部资源管理
  • 语言模型的革命:大型概念模型(LCM)的崛起
  • UE5 小兵定点巡逻+追逐玩家AI
  • Python 高级游戏开发:构建一个基于 Pygame 的多人在线战斗游戏
  • React 组件通信完整指南 以及 自定义事件发布订阅系统
  • note 41:账务系统开发规范
  • arm架构mysql_基于arm架构linux操作系统centos安装mysql5
  • 基于SpringBoot的“大学生社团活动平台”的设计与实现(源码+数据库+文档+PPT)
  • 【高阶数据结构】AVL树
  • ESP-IDF HTTP POST请求发送音频-ESP32物联网方案
  • 深度学习领域车辆识别与跟踪
  • pytorch 张量的unfold方法介绍
  • Ubuntu修改swap大小
  • 农历节日倒计时:基于Python的公历与农历日期转换及节日查询小程序(升级版)
  • 2、Bert论文笔记
  • 基于Spring Boot的可盈保险合同管理系统【附源码】
  • 数据分析的革命——解读云数据库 SelectDB 版的力量
  • 容器化部署服务全流程
  • 小程序租赁系统开发的优势与实践探索
  • 雷电模拟器安装LSPosed
  • 风控模型面试常问问题