oracle约束约束状态和设计习惯
oracle约束状态有几个项目,会让人迷惑,分别是:
- enable/disable--是否启用/禁用
- validate/invalidate--确认/不确认
- 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;
--证明,更新的时候会检查的
通过试验可以获得几点:
- enable/disable完全决定约束是否启用,只有enalbe的情况下,其它状态才可用
- validate/invalide-后者只见确认新的数据和修改数据,前者确认所有的(老的现有数据)
- 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约束约束状态和设计习惯的更多相关文章
- oracle的约束隐式创建索引和先索引后约束的区别
oracle的约束隐式创建索引和先索引后约束的区别 两种情况:1.对于创建约束时隐式创建的索引,在做删除操作的时候: 9i~11g都会连带删除该索引 2.对于先创建索引,再创建约束(使用到此索引)这种 ...
- Oracle字段约束
初识约束 约束是数据库用来确保数据满足业务规则的手段,对数据做的条件限制. 约束的类型 1. 主键约束(PRIMARY KEY) 2. 唯一性约束(UNIQUE) 3. 非空约束(NOT NULL) ...
- Oracle笔记2-数据库设计
数据库的设计 软件开发的流程:立项->需求分析->概要设计->详细设计->实现->测试->交付->维护 [含数据库设计] 通过需求分析,就可以抽取出关键业务中 ...
- Oracle数据库的状态查询
本文来源:huang_xw 的<Oracle数据库的状态查询> 1 状态查询 启动状态 SQL语句 结果 nomount select status from v$instance; ST ...
- Oracle之约束
数据的完整性用于确保数据库数据遵从一定的商业的逻辑规则.在oracle中,数据完整性可以使用约束.触发器.应用程序(过程.函数)三种方法来实现,在这三种方法中,因为约束易于维护,并且具有最好的性能,所 ...
- Oracle 唯一 约束(unique constraint) 与 索引(index) 关系说明
一. 官网对Unique Constraints说明 http://download.oracle.com/docs/cd/E11882_01/server.112/e16508/datainte.h ...
- oracle修改约束列
Oracle 增加修改删除字段 添加字段的语法:alter table tablename add (column datatype [default value][null/not null],-. ...
- oracle之约束-主键、非空、唯一、check、外键、默认
--首先添加主键约束alter table studentadd constraint PK_student_sno primary key(sno) --删除约束alter table studen ...
- Oracle 检查约束check
--检查约束 create table test1( id ) primary key, email ) check (email like '%@%') ) drop table test1 ,'1 ...
随机推荐
- 项目在低版本浏览器下不兼容?友情提示客户升级浏览器(以下只针对IE浏览器)
(function (window) { var win = window, sys = {}, ua = navigator.userAgent.toLowerCase(); (/msie\s+(\ ...
- 1.HTML小结
HTML 基本文档 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> < ...
- Tomcat部分操作
一 概述 1.Tomcat是什么? Tomcat是Apache软件基金会提供的开源免费的服务器,适用于中小型系统与并发访问用户不是很多的情况. 2.域名 IP是互联网上一台计算机的唯一标识,但IP不容 ...
- sqlalchemy & python & datatables & javascript 中文拼音排序
近期有中文拼单排序需要,查询资料,mysql数据库有convert函数支持 select cname from channel order by convert(cname using gbk); # ...
- 3元购买微信小程序解决方案一个月
一.登录微信公众平台https://mp.weixin.qq.com/ 二.点击立即注册.注意:这里不要用微信公众号登录,小程序账号和微信公众号是不同的. 三.在注册页面点击小程序板块. 四.进入小程 ...
- 生产环境rac无法启动
节点二crs无法启动,查看启动日志:ohasd.log位置在/u01/app/11.2.0/grid/log/host01/ohasd/ohasd.log另外root.sh的log在rootcrs_X ...
- 关于simotion建立同步/解除同步的问题
关于simotion建立同步/解除同步的问题. 问题: [enable gearing][disable gearing][enable camming][disable camming]都是一个过程 ...
- xHTML与HTML的写法有什么不同?
全部标签都必须小写 在XHTML中,全部的标签都必须小写.不能大写和小写穿插当中.也不能全部都是大写. 事比例如以下. 错误:<Head></Head><Body> ...
- Android应用经典主界面框架之中的一个:仿QQ (使用Fragment, 附源代码)
备注:代码已传至https://github.com/yanzi1225627/FragmentProject_QQ 欢迎fork,如今来审视这份代码,非常多地方写的不太好,欢迎大家指正.有时间我会继 ...
- react中使用react-transition-group实现动画
css动画的方式,比较局限,涉及到一些js动画的时候没法处理了.react-transition-group是react的第三方模块,借住这个模块可以更方便的实现更加复杂的动画效果 https://g ...