oracle约束状态有几个项目,会让人迷惑,分别是:

  1. enable/disable--是否启用/禁用
  2. validate/invalidate--确认/不确认
  3. deferrable/not deferrable--可延迟/不可延迟

所以,通过简单的实验,来确认它们之间的区别。

以下实验在12.2.0.1中进行。

  drop table t_test_check purge;
SELECT * FROM USER_CONSTRAINTS where table_name='T_TEST_CHECK';
select * from T_TEST_CHECK
--1. enable
create table t_test_check(
id int constraint ck_id_not_null check( id is not null) disable novalidate,
name varchar2(30) constraint ck_name_not_null check(name is not null)
) declare
i int;
begin
for i in 1..100 loop
insert into t_test_check(id, name)
values(null, to_char(sysdate,'yyyy') );
dbms_output.put_line(i);
end loop;
commit;
end;
alter table t_test_check modify constraint ck_id_not_null enable
alter table t_test_check modify constraint ck_id_not_null disable
--结论,enable/disable实际控制约束是否可。disable的情况下,约束根本不被检查 --2. deferrable initially deferred/immediate truncate table t_test_check
--必须删除掉,否则无法修改为deferrable,并触发ora-02447异常
alter table t_test_check drop constraint ck_name_not_null;
alter table t_test_check add constraint ck_name_not_null check(name is not null) deferrable initially deferred enable validate; declare
i int;
begin
for i in 1..100 loop
insert into t_test_check(id, name)
values(i,case when i=20 then null else to_char(sysdate,'yyyy') end);
dbms_output.put_line(i);
end loop;
commit;
end;
--结论,在enable的情况下,deferrable initially deferred的唯一作用就是提交的时候再验证,而
--immediate是语句级别检验,但要是不通过,则都回滚整个事务。 --3. validate/novalidate
alter table t_test_check modify constraint CK_ID_NOT_NULL disable; declare
i int;
begin
for i in 1..10 loop
insert into t_test_check(id, name)
values(null, to_char(sysdate,'yyyy') );
dbms_output.put_line(i);
end loop;
commit;
end; alter table t_test_check modify constraint CK_ID_NOT_NULL enable novalidate;
--证明novalidate不对过去的数据检查
update t_test_check set id=null;
--证明,更新的时候会检查的

通过试验可以获得几点:

  1. enable/disable完全决定约束是否启用,只有enalbe的情况下,其它状态才可用
  2. validate/invalide-后者只见确认新的数据和修改数据,前者确认所有的(老的现有数据)
  3. deferrable/not deferrable 仅仅用于延迟检查而已,但最终还是要检查的。如果是deferrable,则可以按照语句级别或者事务级别检查。

在实际情况中,常常会遇到那么一些人有一些习惯:不对字段或者表做任何约束。

好处是:节约了表设计时间,减少了变更说需要耗费的时间。

坏处是:终归需要通过其它程序来实现业务逻辑,必须在程序中对数据检查,而且是必须每个应用中都做这种检查,所耗费的时间未必少,可能还更多。

这种习惯,大体而言不好,虽然设计的时候节约了时间,但最终还是要付出代价的,否则为什么数据库要设计这种功能。

--

俗话说:磨刀不误砍材工。

在数据库中实现了约束,那么所有应用就可以放心地使用数据,尤其是一些要求很高的生产系统。

此外,如果担心加载数据的时候,速度会变慢,oracle也是有提供折中的方案--deferrable,enable/disable.

通常的做法是在加载前先disable约束,加载之后再启用约束(这种操作在olap或者dw中尤其常见),如果是uk或者pk,可以使用keep index。

例如:

create table t_test_uk(
sid varchar2(20) constraint ck_test_uk_sid unique constraint ck_test_uk_notnull check(sid is not null)
)
/
begin
for J in 1..10 loop
insert into t_test_uk(sid) values('CHN-'||trim(to_char(J,'')));
--DBMS_OUTPUT.put_line('CHN-'||trim(to_char(J,'00')));
end loop;
commit;
end; ALTER TABLE T_TEST_UK MODIFY CONSTRAINT ck_test_uk_sid DISABLE KEEP INDEX; SELECT * FROM T_TEST_UK WHERE SID='CHN-01';

最后的select语句,无论是否启用约束,都可以利用上索引。
而且重新启用索引,也是很容易的:

ALTER TABLE T_TEST_UK MODIFY CONSTRAINT CK_TEST_UK_SID enable;

oracle约束约束状态和设计习惯的更多相关文章

  1. oracle的约束隐式创建索引和先索引后约束的区别

    oracle的约束隐式创建索引和先索引后约束的区别 两种情况:1.对于创建约束时隐式创建的索引,在做删除操作的时候: 9i~11g都会连带删除该索引 2.对于先创建索引,再创建约束(使用到此索引)这种 ...

  2. Oracle字段约束

    初识约束 约束是数据库用来确保数据满足业务规则的手段,对数据做的条件限制. 约束的类型 1. 主键约束(PRIMARY KEY) 2. 唯一性约束(UNIQUE) 3. 非空约束(NOT NULL) ...

  3. Oracle笔记2-数据库设计

    数据库的设计 软件开发的流程:立项->需求分析->概要设计->详细设计->实现->测试->交付->维护 [含数据库设计] 通过需求分析,就可以抽取出关键业务中 ...

  4. Oracle数据库的状态查询

    本文来源:huang_xw 的<Oracle数据库的状态查询> 1 状态查询 启动状态 SQL语句 结果 nomount select status from v$instance; ST ...

  5. Oracle之约束

    数据的完整性用于确保数据库数据遵从一定的商业的逻辑规则.在oracle中,数据完整性可以使用约束.触发器.应用程序(过程.函数)三种方法来实现,在这三种方法中,因为约束易于维护,并且具有最好的性能,所 ...

  6. Oracle 唯一 约束(unique constraint) 与 索引(index) 关系说明

    一. 官网对Unique Constraints说明 http://download.oracle.com/docs/cd/E11882_01/server.112/e16508/datainte.h ...

  7. oracle修改约束列

    Oracle 增加修改删除字段 添加字段的语法:alter table tablename add (column datatype [default value][null/not null],-. ...

  8. oracle之约束-主键、非空、唯一、check、外键、默认

    --首先添加主键约束alter table studentadd constraint PK_student_sno primary key(sno) --删除约束alter table studen ...

  9. Oracle 检查约束check

    --检查约束 create table test1( id ) primary key, email ) check (email like '%@%') ) drop table test1 ,'1 ...

随机推荐

  1. Facebook 爬虫

    title: Facebook 爬虫 tags: [python3, facebook, scrapy, splash, 爬虫] date: 2018-06-02 09:42:06 categorie ...

  2. 检测IE浏览器兼容Edge模式及IE11

    document.documentMode || +(navigator.userAgent.match(/MSIE (\d+)/) && RegExp.$1) 判断布尔值

  3. SQL 出现18456

    SQL Server 2008R2 18456错误解决方案   SQL Server 2008R2 18456错误解决方案 微软解释说,因密码或用户名错误而使身份验证失败并导致连接尝试被拒时,类似下面 ...

  4. DataBase Migration 使用笔记

    Add-Migration 新建数据库迁移版本 Update-Database -Verbose 更新到数据库(-Verbose 显示详细信息) Update-Database –TargetMigr ...

  5. 笨办法学Python(三十八)

    习题 38: 阅读代码 现在去找一些 Python 代码阅读一下.你需要自己找代码,然后从中学习一些东西.你学到的东西已经足够让你看懂一些代码了,但你可能还无法理解这些代码的功能.这节课我要教给你的是 ...

  6. February 23 2017 Week 8 Thursday

    In order to be irreplaceable, one must always be different. 想要无可取代,必须与众不同. In recent days, a news ab ...

  7. March 10 2017 Week 10 Friday

    If you love life, life will love you back. 爱生活,生活也会爱你. Love life, and it will love you back. All thi ...

  8. 我的HTML总结之常用基础便签

    HTML:是Hyper Text Markup Language(超级文本标记语言)的缩写,HTML不是一种程序,只是一种控制网页中数据显示的标识语言. HTML由一组标签组成. HTML的基本结构 ...

  9. 每天一个linux命令(21):chgrp,chown,chmod

    这三个命令都是改变文件属性与权限的,就放一起写了 charp:改变文件所属用户组 chown:改变文件所属者 chmod:改变文件的权限 一个文件对于owner,group ,others有不同的权限 ...

  10. java随机数Reandom(简单介绍)

    简单介绍 Java中存在着两种Random函数 一.java.lang.Math.Random; 调用这个Math.Random()函数能够返回带正号的double值,该值大于等于0.0且小于1.0, ...