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

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

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

以下实验在12.2.0.1中进行。

  1. drop table t_test_check purge;
  2. SELECT * FROM USER_CONSTRAINTS where table_name='T_TEST_CHECK';
  3. select * from T_TEST_CHECK
  4. --1. enable
  5. create table t_test_check(
  6. id int constraint ck_id_not_null check( id is not null) disable novalidate,
  7. name varchar2(30) constraint ck_name_not_null check(name is not null)
  8. )
  9.  
  10. declare
  11. i int;
  12. begin
  13. for i in 1..100 loop
  14. insert into t_test_check(id, name)
  15. values(null, to_char(sysdate,'yyyy') );
  16. dbms_output.put_line(i);
  17. end loop;
  18. commit;
  19. end;
  20. alter table t_test_check modify constraint ck_id_not_null enable
  21. alter table t_test_check modify constraint ck_id_not_null disable
  22. --结论,enable/disable实际控制约束是否可。disable的情况下,约束根本不被检查
  23.  
  24. --2. deferrable initially deferred/immediate
  25.  
  26. truncate table t_test_check
  27. --必须删除掉,否则无法修改为deferrable,并触发ora-02447异常
  28. alter table t_test_check drop constraint ck_name_not_null;
  29. alter table t_test_check add constraint ck_name_not_null check(name is not null) deferrable initially deferred enable validate;
  30.  
  31. declare
  32. i int;
  33. begin
  34. for i in 1..100 loop
  35. insert into t_test_check(id, name)
  36. values(i,case when i=20 then null else to_char(sysdate,'yyyy') end);
  37. dbms_output.put_line(i);
  38. end loop;
  39. commit;
  40. end;
  41. --结论,在enable的情况下,deferrable initially deferred的唯一作用就是提交的时候再验证,而
  42. --immediate是语句级别检验,但要是不通过,则都回滚整个事务。
  43.  
  44. --3. validate/novalidate
  45. alter table t_test_check modify constraint CK_ID_NOT_NULL disable;
  46.  
  47. declare
  48. i int;
  49. begin
  50. for i in 1..10 loop
  51. insert into t_test_check(id, name)
  52. values(null, to_char(sysdate,'yyyy') );
  53. dbms_output.put_line(i);
  54. end loop;
  55. commit;
  56. end;
  57.  
  58. alter table t_test_check modify constraint CK_ID_NOT_NULL enable novalidate;
  59. --证明novalidate不对过去的数据检查
  60. update t_test_check set id=null;
  61. --证明,更新的时候会检查的

通过试验可以获得几点:

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

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

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

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

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

--

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

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

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

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

例如:

  1. create table t_test_uk(
  2. sid varchar2(20) constraint ck_test_uk_sid unique constraint ck_test_uk_notnull check(sid is not null)
  3. )
  4. /
  5. begin
  6. for J in 1..10 loop
  7. insert into t_test_uk(sid) values('CHN-'||trim(to_char(J,'')));
  8. --DBMS_OUTPUT.put_line('CHN-'||trim(to_char(J,'00')));
  9. end loop;
  10. commit;
  11. end;
  12.  
  13. ALTER TABLE T_TEST_UK MODIFY CONSTRAINT ck_test_uk_sid DISABLE KEEP INDEX;
  14.  
  15. 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. Drupal theme_hook

    模板语言和主题引擎 用Drupal的行话来说,主题就是一组负责你站点外观的文件.你可以从http://drupal.org/project/Themes下载第 3方主题,或者你可以自己动手创建一个主题 ...

  2. twaver拓扑图通道组织图(百分比使用率/水槽)效果实现

    功能介绍: 利用拓扑图实现:64条通道,根据每条通道是否承载业务,提供百分比展示 首先上图,功能效果如图: 废话不多,直接上代码: <!DOCTYPE html> <html> ...

  3. iPython与notebook的基本用法

    1 Ipython 安装 pip install ipython 2 Notebooke 基本用法 启动ipython使用ipython 启动notebook 使用 ipython notebook ...

  4. TextView来实现跑马灯的效果

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...

  5. adnroid 自定义ProgressDialog加载中

    用来记录自己所用到的知识 前两天在做项目的时候发现有时候在访问网络数据的时候由于后台要做的工作较多,给我们返回数据的时间较长,所以老大叫我加了一个加载中的logo图用来提高用户体验. 于是就在网上找了 ...

  6. idea 新建文件夹目录问题解决

    选中工程,设置,去掉选项“Compact Empty Middle Packages” .

  7. raid管理

    raid管理 使用工具命令 storcli64 查看磁盘状态 storcli64 /c0 show 注:现在磁盘状态为UGood状态,表示可以直接制作raid 若磁盘状态为JBOD,则制作raid时会 ...

  8. 仿照jQuery写一个关于选择器的框架(带了注释,请多多指教~)

    var select = (function () { //这是一个异常与捕获的代码,它表示的意思是:如果push方法出现了错误那么就需要重写push方法 try { //这边是自己模拟一个场景,来使 ...

  9. Flask中数据库关联与分页与cache缓存(十二)

    1 一对多(One To Many) 表示一对多的关系时,在子表类 Post 中需要通过 foreign key (外键)引用父表类 User 在Post类中指定ForeignKey: class P ...

  10. zip4j之加压解压

    最近看同事搞个文件打包,搞了大半天,还是有问题!嗨~~ 网上明明有现成的,偏偏要自己写! 下面是基于zip4j实现加压解决的简单工具类 package com.learcher.zip; import ...