精华内容
下载资源
问答
  • Mysql逻辑删除保留唯一索引

    千次阅读 2020-08-03 14:33:37
    通常的业务系统中为了防止认为操作失误,造成误删数据,都要求对于删除操作只执行逻辑删除,即假删除。常见的做法添加删除标识字段,用户操作删除时更新删除标识字段来达到目的。但是当遇到表中需要有唯一索引时则会...

    通常的业务系统中为了防止认为操作失误,造成误删数据,都要求对于删除操作只执行逻辑删除,即假删除。常见的做法添加删除标识字段,用户操作删除时更新删除标识字段来达到目的。但是当遇到表中需要有唯一性索引时则会造成问题。

    案例

    创建一个商品编码为A110的商品,商品编码为该表的唯一性索引,此时对该商品进行删除后,无法再次添加商品编码为A110的商品。

    将删除标识加入唯一索引

    把商品编码和删除标识设置为复合唯一索引,删除A110商品后可以再次新建一个A110,解决了上述问题。但是此时需要再次删除A110商品时则会出现无法删除。

    再添加一个token标识

    将商品编码与token标识设置为复合唯一索引,删除记录时将ID存入token标识中,这样每次删除时由于ID不一致则不会导致无法删除的情况。需要注意的是这样删除操作将会无法批量处理,必须逐条更新

    最终解决方案

    将商品编码与删除标识设置为复合唯一索引,每次删除时将删除标识设置为NULL,由于NULL不会与其他字段有组合唯一的效果,所以完美的解决了逻辑删除保留唯一索引的问题。

    展开全文
  • MyBatisPlus逻辑删除唯一索引冲突问题

    千次阅读 热门讨论 2021-01-23 14:26:57
    在开发中,我们经常会有逻辑删除唯一索引同时使用的情况。但当使用mybatis plus时,如果同时使用逻辑删除唯一索引,会报数据重复Duplicate entry的问题。 举个例子: 原来数据库结构: 这里location_id是唯一...

    1、问题背景:

    在开发中,我们经常会有逻辑删除和唯一索引同时使用的情况。但当使用mybatis plus时,如果同时使用逻辑删除和唯一索引,会报数据重复Duplicate entry的问题。
    举个例子:
    原来数据库结构:
    这里location_id是唯一索引

    CREATE TABLE `eam_location` (
        `id` int(11) NOT NULL AUTO_INCREMENT,
        `location_id` varchar(50) UNIQUE NOT NULL COMMENT '位置代码',
        `location_level` tinyint(1) NOT NULL COMMENT '位置级别',
        `location_name` varchar(50) NOT NULL COMMENT '位置名称',
        `parent_location_id` varchar(50) COMMENT '上级位置代码',
        `delete_flag` tinyint(1) DEFAULT 0 COMMENT '软删除',
        `version` int(11) DEFAULT 1 COMMENT '乐观锁',
        PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    

    这里在删除添加某一条数据后,delete_flag变成0,当删除后delete_flag会变成1,再次添加相同的数据时,由于数据库检测不到原来数据,会报数据重复Duplicate entry的问题
    解决办法:参考逻辑删除与唯一约束的需求冲突
    SQL数据结构,将delete_flag用时间戳进行表示,唯一索引变成了联合唯一索引 UNIQUE KEY unique_location_delete_flag(location_id, delete_flag) ,当添加一条数据时,delete_flag变成null,当删除数据时,delete_flag变成删除时的一个时间戳。再次添加相同数据时,由于添加的数据是联合唯一索引unique_location_delete_flag ,delete_flag为null,不会产生冲突,多次删除也是,完美解决问题。

    CREATE TABLE `eam_location` (
        `id` int(11) NOT NULL AUTO_INCREMENT,
        `location_id` varchar(50) NOT NULL COMMENT '位置代码',
        `location_level` tinyint(1) NOT NULL COMMENT '位置级别',
        `location_name` varchar(50) NOT NULL COMMENT '位置名称',
        `parent_location_id` varchar(50) COMMENT '上级位置代码',
        `delete_flag` datetime  COMMENT '软删除',
        `version` int(11) DEFAULT 1 COMMENT '乐观锁',
        PRIMARY KEY (`id`),
        UNIQUE KEY `unique_location_delete_flag`(`location_id`, `delete_flag`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    

    entity类:

    @AllArgsConstructor
    @NoArgsConstructor
    @Builder(toBuilder = true)
    @Data
    @EqualsAndHashCode(callSuper = false)
    public class EamEquipmentType implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        /**
         * 数据库自增id
         */
        @TableId(value = "id", type = IdType.AUTO)
        private Integer id;
    
        /**
         * 设备类型编号
         */
        private String typeId;
    
        /**
         * 设备类型
         */
        private String typeName;
    
        /**
         * 设备厂商
         */
        private String manufacture;
    
        /**
         * 设备型号
         */
        private String model;
    
        /**
         * 标准设备bom 0:未创建 1:已创建
         */
        private Boolean typeBom;
    
        /**
         * 标准设备bom id
         */
        private Integer typeBomId;
    
        /**
         * 创建时间
         */
        private LocalDateTime createTime;
    
        /**
         * 软删除
         */
        @TableLogic()
        @TableField(fill = FieldFill.INSERT)
        private LocalDateTime deleteFlag;
    
        /**
         * 乐观锁
         */
        @Version
        @TableField(fill = FieldFill.INSERT)
        private Integer version;
    

    yml配置文件:

    mybatis-plus:
      global-config:
        db-config:
          logic-delete-value: "now()" #逻辑删除值是个db获取时间的函数
          logic-not-delete-value: "null"  #逻辑未删除值为字符串 "null"
    
    展开全文
  • 在开发过程中有时候会使用逻辑删除,与之相对的则是物理删除。...下面就来介绍如何在使用逻辑删除的同时,建立唯一索引(或者不建立索引但是能保持数据的唯一性)。 解决方案: 不使用逻辑删除,直

    文章首发于个人博客,欢迎访问关注:https://www.lin2j.tech

    在开发过程中有时候会使用逻辑删除,与之相对的则是物理删除。逻辑删除的作用有几个

    • 防止数据误删除,方便数据找回。
    • 数据存在一定的商业价值,可以积累起来。
    • 数据与其他数据存在关联,不能删除。

    当然也有它的缺点,比如数据冗余、影响查询效率、查询的 SQL 书写复杂度增加、存在唯一索引时,容易发生插入错误。

    下面就来介绍如何在使用逻辑删除的同时,建立唯一索引(或者不建立索引但是能保持数据的唯一性)。

    解决方案:

    1. 不使用逻辑删除,直接物理删除。
    2. 使用备份表,或者叫历史表,将原来的数据进行物理删除,同时保存一份到历史表中。
    3. 引入 redis ,使用 redis set ,通过 set 的特性来判重。
    4. 删除状态字段 is_deleted 采用 bigint 类型,删除时不再是将字段置为 1,而是将当前时间戳写入。重新建立唯一索引时,将 is_deleted 字段组合进去,比如 uk(S, is_deleted) S是原来建立唯一索引的字段集合。
    5. 保留删除状态字段,引入另一个字段 del_tid ,默认为 0,删除时将该行记录的主键填入(所以字段类型要和主键一致)。重新建立唯一索引时,将 del_tid 字段组合进去,比如 uk(S, del_tid ) S是原来建立唯一索引的字段集合。

    方案比较

    第一种方式显然不符合这次讨论的情况,因为我们需要使用逻辑删除。

    第二种方案就需要再多维护一个历史表,如存在关联查询,则需要多关联一个历史表,会降低查询效率。

    第三种方案因为引入了 redis ,会增加系统的复杂度,而且使用 redis 做缓存还需要考虑,高并发下 mysql 和 缓存的一致性,但是具备一定的可行性。

    第四种和第五种方案大同小异,都是将标志字段更新为能保证唯一性的值。两者的选用应该根据实际情况使用:

    如果是在项目的开发阶段,那么就是用第四种,这样除了 is_deleted 字段,不用再加一个 del_tid

    如果是项目已经在线上工作了,那么可以采用第五种,这样不用大改原来的业务逻辑,也可以避免发生唯一索引报错。

    第四种方式示例:

    在更新时,将 is_deleted 字段置为时间戳,这里使用 now() 函数。

    ALTER TABLE `dict` ADD UNIQUE UK_DICT_NAME (`name`, `is_deleted`);
    
    <update id="deleteLogicallyBatch" parameterType="list" >
        update `dict` set is_deleted = now() where tid in
        <foreach collection="tids" item="tid" open="(" close=")" separator=",">
            #{tid}
        </foreach>
    </update>
    

    请根据自己的实际情况,去更新 is_deleted 的值,我这里的数据都是人工添加删除的,所以我的时间戳精确到秒就没了。

    展开全文
  • 在数据表结构设计的时候有同时存在唯一索引逻辑删除,通常逻辑删除is_deleted是取值范围0、1,当删除同一个唯一索引字段值时,就会失败。 二、 解决方案 2.1 物理删除 不再设置逻辑删除标志位,直接物理删除,...

    一、 场景

    在数据表结构设计的时候有同时存在唯一索引和逻辑删除,通常逻辑删除is_deleted是取值范围01,当删除同一个唯一索引字段值时,就会失败。

    二、 解决方案

    2.1 物理删除

    不再设置逻辑删除标志位,直接物理删除,这依赖业务数据的特性。

    2.2 历史表

    每个表新建一个历史表,存储已经删除的历史数据,缺点是大量的历史表。当然还可以参考mysql schema的table表来设计,存储schema和tableName,然后行数据json类型存储,需要根据场景选择。

    2.3 删除时间

    删除标志位不使用01,使用删除时间戳来替代,同一秒时间,相同唯一字段可能性基本为零,使用初始值0或者Null来作为未删除标志符,会占用一定的存储空间,但可以显示删除时间。

    2.4 删除设置为Null

    删除字段删除标识设为Null,未删除设置为0。

    展开全文
  • 在开发中,我们经常会有逻辑删除唯一索引同时使用的情况。但当使用mybatis plus时,如果同时使用逻辑删除唯一索引,会报数据重复Duplicate entry的问题。 举例来说,有表user,建立唯一索引(user_name,is_del...
  • 0表示未删除,其余的表示已删除,近期准备加唯一索引的时候发现问题,假如有某个唯一索引的字段,删除后,又重新创建同样一条记录,再次删除的时候,就会出现唯一索引重复的问题,这个时候,唯一索引逻辑删除就有...
  • 1.实际生产中出现了这个问题,核心表需要保留以前的记录,所以使用逻辑删除,这次其实也算业务上没设计好,还是看解决方法吧; 主键 id 用户名 user_name 状态 status 删除标识(0正常 -1删除) yn 1 gy ...
  • 表中的唯一索引会和逻辑删除字段互斥,导致逻辑删除后的数据和要插入的数据出现重复索引时无法插入。 有如下表: CREATE TABLE `pata_biz` ( `ID` bigint(32) NOT NULL AUTO_INCREMENT COMMENT 'ID主键', `NAME` ...
  • 2019独角兽企业重金招聘Python工程师标准>>> ...这样唯一索引就可以加在(uk字段,删除flag)上了 UK字段 删除flag x 0 x -1 x -2 转载于:https://my.oschina.net/jsycwangwei/blog/2962812
  • 1 死锁问题背景 1 1.1 一个不可思议的死锁 1 1.1.1 初步分析 3 1.2 如何阅读死锁日志 3 ...2.1 Delete操作的加锁逻辑 4 2.2 死锁预防策略 5 2.3 剖析死锁的成因 6 3 总结 
  • 一、问题 现在很多系统都不允许真正删除数据库中的数据,而是通过引入删除标记字段的方式进行假删除,...但是逻辑删除会面临一个违反唯一约束的问题。比如一个商品表: create table goods ( id bigint primary...
  • 逻辑删除还要保证某个字段唯一的设计方案
  • change buffer 唯一索引和普通索引

    千次阅读 2020-01-03 16:55:51
    唯一索引和普通索引 change buffer 学习检测 什么是change buffer? 唯一索引和普通索引查找数据流程及性能对比? 唯一索引和普通索引更新数据流程及性能对比? change buffer 适用场景? change buffer 和 ...
  • 很多时候,当我们的数据很重要,删除采用的是逻辑删除,仅仅是在记录上指定一个删除标记;这个时候,我们又需要该表的某一字段唯一(未删除的保持唯一,已经有删除标记的行不管),仅仅是采用数据库本身的check ...
  • 删除重复数据,建立唯一索引

    千次阅读 2017-03-02 15:55:53
    一开始数据库中未建立唯一索引,但是在业务逻辑上是有唯一性约束的。在运行一段时间后,才发现这个问题,记录一下 对应的表T_ROUTE_ORBIT,唯一限制字段: longitude, latitude, task_id 删除重复记录,...
  • 别踩坑!使用MySQL唯一索引请注意

    万次阅读 多人点赞 2019-01-28 21:33:14
    背景 在程序设计中了,我们往往需要...但是我们不能确保同时有两个人使用同一个手机号注册到我们的系统中,因此这里就需要在更深的层次去确保手机号的唯一性了。不同存储方案,解决方式不一样,这里以MySQL为例,我...
  • Oracle主键约束、唯一键约束、唯一索引的区别 一般,我们看到术语“索引”和“键”交换使用,但实际上这两个是不同的。索引是存储在数据库中的一个物理结构,键纯粹是一个逻辑概念。键代表创建来实施业务...
  • 索引、唯一索引、聚集索引

    千次阅读 2012-04-28 09:14:50
    索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存。如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录。表里面的记录数量越多,这个操作的...
  • Oracle 主键外键唯一索引索引

    千次阅读 2016-09-29 17:45:17
    1.查询索引  select table_name,index_name from user_indexes where table_name=upper('test_temp1'); 2.创建主键  (1)创建表的时候创建:  create table test_temp1(id int primary key,name varchar2(20)); ...
  • Oracle主键、唯一键与唯一索引的区别   一般,我们看到术语“索引”和“键”交换使用,但实际上这两个是不同的。索引是存储在数据库中的一个物理结构,键纯粹是一个逻辑概念。键代表创建来实施业务规则的完整性...
  • 按照维护与管理索引角度分为:唯一索引、复合索引和系统自动创建的索引。 索引的结构是由:根节点--->非叶节点--->非叶节点--->叶节点   1、聚集索引:表中存储的数据按照索引的顺序存储,检索效率比普通索引高,但...
  • 但是,由于每个表只允许使用一个聚集索引,因此按照这个简单的逻辑来确定要创建哪种类型的索引并不总能成功。对于该问题有一个简单的物理原因。对于聚集索引 B 树结构的上部(非叶层),如果像对它们的非聚集索引...
  • 可以通过人家专业的人事给我们提供的解释,可以看到,这个索引就是一种单独的、物理对数据库表中一列或多列的值进行排序的一种存储结构,然后再往后看,指向表中物理标识的逻辑指针清单。 这个怎么去理解呢,我来举...
  • 因为主键可以唯一标识某一行记录,所以可以确保执行数据更新、删除的时候不会出现张冠李戴的错误。 主键除了上述作用外,常常与外键构成参照完整性约束,防止出现数据不一致。数据库在设计时,主键起到了很重要的...
  • 一般,我们看到术语“索引”和“键”交换使用,但实际上这两个是不同的。...接下来我们看看数据库中的主键约束、唯一键约束和唯一索引的区别。 SQL> select * from v$version; BANNER -------------
  • MySQL:主键与唯一索引

    千次阅读 2018-11-06 11:30:50
    所谓主键就是能够唯一标识表中某一行的属性或属性组,一个表只能有一个主键,但可以有多个候选索引。 因为主键可以唯一标识某一行记录,所以可以确保执行数据更新、删除的时候不会出现张冠李戴的错误。主键除了上述...
  • 主键、唯一键与唯一索引的区别

    千次阅读 2016-08-10 08:40:10
    这篇文章的意义已经理解,但是他举得例子不错,保存下来,下次想看的时候可以参考一下。...索引是存储在数据库中的一个物理结构,键纯粹是一个逻辑概念。键代表创建来实施业务规则的完整性约束。索引和键的
  • Mybatis批量插入数据 -- 校验唯一索引

    千次阅读 2018-12-14 18:22:50
    Mybatis批量插入数据 -- 校验唯一索引1. 单条插入2. 批量插入同时校验唯一性 1. 单条插入 (1)未校验唯一索引:抛出违反唯一索引异常。 (2)单条校验唯一性后插入:频繁连接数据库,性能低 2. 批量插入同时校验...
  • 索引概念的理解 索引是对数据库表中一个或多个列(例如,employee 表的姓名 (name) 列)的值进行排序的结构。如果想按特定职员的姓来查找他或她, 则与在表中搜索所有的行相比,索引有助于更快地获取信息,使用索引...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 120,431
精华内容 48,172
关键字:

逻辑删除唯一索引