添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

突然被问有没有写过博客。非常惭愧,没有养成写博客的习惯,但感觉在这行里做了那么些年,有时是该记录点东西了,为了可能的遗忘,或者为网友提供那么一点点的帮助也是好的。

想起正好前两天和几个同事聊了点小问题,其实是个小技巧,就以此为题作点记录,当是练练手吧!

现在很多系统都不允许真正删除数据库中的数据,而是通过引入删除标记字段的方式进行假删除,即我们通常说的逻辑删除。其它的数据查询都只查询标记为未删除的数据。目前流行的hibernate 和 mybatis 等框架也提供了对假删除的支持。据我的一些同行说,他们公司甚至不允许在程序中出现删除语句,甚至在实施时,分配给你的数据库用户就不具有删除数据的权限!

但是逻辑删除会面临一个违反唯一约束的问题。比如一个商品表:

create table goods (
    id bigint primary key,
    goods_no varchar(20) not null comment '商品编号',
    goods_name varchar(20) comment '商品名称',
    ......
    deleted bit comment '是否删除', 
    constraint uq_goods_goods_no unique(goods_no)

当用户添加了一个编码为 '001' 的商品,并且删除之后,goods 表中便有一条goods_no 字段为 '001' 的记录。而如果用户想再添加一个编号为 '001' 的商品,则无法再添加进去了,因为这条数据已经在表中存在了。

但从用户角度看,编号为‘001’ 的这个商品明明都已经删除了;但再次添加的时候,却又说编号已经被占用;好吧,既然已经存在,那我去把它找出来进行修改,或者再删除之后重新添加,却又找不到这条记录!真是莫名其妙!

要想解决这种问题,最简单的办法就是在数据库中不要创建唯一约束,数据的唯一性靠应用程序来解决。但可能某种性格的设计师就不乐意了!

笔者认为,可能为了系统运行的性能之类的原因,数据库中可以不用创建各种约束。但在开发阶梯,应当尽量多地在数据为吕创建一些约束。因为约束体现了业务规则,只要违反了约束,肯定会违反业务规则,这样能够把开发过程中可能产生的 bug 尽早地暴露出来,尽早地修复。这样比将来发现问题,再去修改程序,还要修复错误的数据要好得多。其实要坚持在数据库中创建唯一约束,办法也很简单:

1)将删除标记字段类型改为与主键相同的类型,当值为0(主键是数值类型时)或者为空/空字符串(主键是字符串类型)时,表示未删除,当想标记数据为删除状态时,将删除标记字段值修改为与主键相同的值

2)字段的唯一约束,改为字段.与删除标记字段的联合唯一约束

以上述商品表为例,商品表定义改为:

create table goods (
    id bigint primary key,
    goods_no varchar(20) not null comment '商品编号',
    goods_name varchar(20) comment '商品名称',
    ......
    deleted bigint default 0 not null comment '是否删除,当值为0时,表示未删除,当值为非0时,表示已经删除', 
    constraint uq_goods_goods_no unique(goods_no, deleted)

添加了一个商品,数据库中存在这样一条记录:

    "id": 10,     "goods_no": "001",     "goods_name": "XXXX牌XXX包装的洗衣粉",      "deleted": 0

当删除这条记录时,这条记录变成了:

    "id": 10,     "goods_no": "001",     "goods_name": "XXXX牌XXX包装的洗衣粉",      "deleted": 10

注意删除字段 deleted = 10,这个字段值取自本条记录的 id 值 

当要再次添加编号为 '001' 的商品时,可以是:

    "id": 11,     "goods_no": "001",     "goods_name": "XXX牌洋娃娃",      "deleted": 0

虽然商品编号为 001 的记录已经存在,但这个唯一约束是 goods_no 和 deleted 在一起的,所以不会违反唯一约束。

而如果新加的这条编号为'001'的商品未删除时,想继续添加一条编号为 '001' 的商品,由于新加的记录 deleted = 0,因此会尝试生成两条  goods_no = '001', deleted = 0 的记录,这时违反了唯一约束,添加失败。

var code = "3a62c96a-8d0e-4d5c-a49f-4e7a4de9bdfb"

由此,即满足了逻辑删除的需求,同时又可以不必违反唯一约束。

简单总结一下即是:只要是被标记删除的数据,虽然商品编号可能存在重复,但删除标记字段的值不可能重复(它的值即是主键的值,而主键本身不可能重复);而被标记未被删除的数据,由于其删除标记值都为0,这已经是重复的值了,所以只要商品编号重复,则必然违反唯一约束!

一、问题现在很多系统都不允许真正删除数据库中的数据,而是通过引入删除标记字段的方式进行假删除,即我们通常说的逻辑删除。其它的数据查询都只查询标记为未删除的数据。目前流行的hibernate和 mybatis等框架也提供了对假删除的支持。据我的一些同行说,他们公司甚至不允许在程序中出现删除语句,甚至在实施时,分配给你的数据库用户就不具有删除数据的权限!但是逻辑删除会面临一个违反唯一约束的问题。比如一个商品表:create table goods ( id bigint primary...
为了使SoftMan系统具有灵活的实时自适应能力,一种扩展的ECA规则模型即提出了RSECAP。 在该规则模型中,引入了新的概念资源主体和SoftMan对象,分别描述了规则的触发对象和有效对象,并引入了后置条件来表达规则动作执行后的状态约束。 基于RSECAP模型,建立了基于规则的SoftMan正向推理机制,并讨论了规则冲突问题。 分别从动作约束和后置条件约束两个角度定义了规则冲突问题的形式化描述,并证明了这两种描述方式之间的内在逻辑关系。 在此关联理论的基础上,提出了将静态规则与动态规则相结合的规则冲突检测方法,并通过动态构建规则冲突解决方案集并计算后置条件约束偏好值来实现冲突解决。 与其他典型方法的比较评估表明,基于后置条件约束偏好的规则冲突检测和解决方法具有较高的成功率和准确性,并且具有稳定可靠的特征。
物理删除指的是直接将数据从数据库删除,不保留。   逻辑删除指的是修改数据的某个字段,使其表示为已删除状态,而非删除数据,保留该数据在数据库中,但是查询时不显示该数据(查询时过滤掉该数据)。 给数据表增加一个字段:delete_flag,用于表示该数据是否被逻辑删除。 CREATE TABLE test_mybatis_plus_users id BIGINT NOT NULL COMMENT '主键.
您遇到了一个异常,即 java.sql.SQLIntegrityConstraintViolationException,表示在执行 SQL 操作时违反了唯一约束条件。而具体的错误信息是 ORA-00001。这个错误通常是由于试图向数据库中插入重复值导致的。 ORA-00001 是 Oracle 数据库的错误代码,表示违反了唯一约束条件。唯一约束条件要求指定的列或组合列的值在表中是唯一的,不能重复。 要解决这个问题,您可以考虑以下几个方案: 1. 检查您的数据源,确保您要插入或更新的数据不会导致唯一约束条件冲突。 2. 确保数据库中已经没有重复的数据,可以通过查询来验证是否存在重复值。 3. 在插入或更新数据之前,先进行判断,避免重复操作。 4. 如果需要插入重复的数据,可以考虑修改唯一约束条件,或者使用其他方式来确保数据的唯一性,例如使用序列生成唯一值。 请注意,具体解决方法可能因您的业务逻辑和数据结构而异,请根据实际情况进行调整。