热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Oracle约束(Constraint)详解

nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd

概述

  约束是数据库用来确保数据满足业务规则的手段,不过在真正的企业开发中,除了主键约束这类具有强需求的约束,像外键约束,检查约束更多时候仅仅出现在数据库设计阶段,真实环境却很少应用,更多是放到程序逻辑中去进行处理。这也比较容易理解,约束会一定程度上较低数据库性能,有些规则直接在程序逻辑中处理就可以了,同时,也有可能在面对业务变更或是系统扩展时,数据库约束会使得处理不够方便。不过在我看来,数据库约束是保证数据准确性的最后一道防线,对于设计合理的系统,处于性能考虑数据库约束自然可有可无;不过若是面对关联关系较为复杂的系统,且对系统而言,数据的准确性完整性要高于性能要求,那么这些约束还是有必要的(否则,就会出现各种相对业务规则来说莫名其妙的脏数据,本人可是深有体会的。。)。总之,对于约束的选择无所谓合不合理,需要根据业务系统对于准确性和性能要求的侧重度来决定。

数据库约束有五种:
  •      主键约束(PRIMARY KEY)
  •      唯一性约束(UNIQUE)
  •      非空约束(NOT NULL)
  •      外键约束(FOREIGN KEY)
  •      检查约束(CHECK)
下面我们就分别来看下这五类约束:

数据库约束

主键约束(PRIMARY KEY)

     主键是定位表中单个行的方式,可唯一确定表中的某一行,关系型数据库要求所有表都应该有主键,不过Oracle没有遵循此范例要求,Oracle中的表可以没有主键(这种情况不多见)。关于主键有几个需要注意的点:
  1. 键列必须必须具有唯一性,且不能为空,其实主键约束 相当于 UNIQUE+NOT NULL
  2. 一个表只允许有一个主键
  3. 主键所在列必须具有索引(主键的唯一约束通过索引来实现),如果不存在,将会在索引添加的时候自动创建
     添加主键(约束的添加可在建表时创建,也可如下所示在建表后添加,一般推荐建表后添加,灵活度更高一些,建表时添加某些约束会有限制)
SQL> alter table emp add constraint emp_id_pk primary key(id);
 

唯一性约束(UNIQUE)

     唯一性约束可作用在单列或多列上,对于这些列或列组合,唯一性约束保证每一行的唯一性。
     UNIQUE需要注意:
  1.      对于UNIQUE约束来讲,索引是必须的。如果不存在,就自动创建一个(UNIQUE的唯一性本质上是通过索引来保证的)
  2.      UNIQUE允许null值,UNIQUE约束的列可存在多个null。这是因为,Unique唯一性通过btree索引来实现,而btree索引中不包含null。当然,这也造成了在where语句中用null值进行过滤会造成全表扫描。
     添加唯一约束
SQL> alter table emp add constraint emp_code_uq unique(code);

非空约束(NOT NULL)

非空约束作用的列也叫强制列。顾名思义,强制键列中必须有值,当然建表时候若使用default关键字指定了默认值,则可不输入。

  添加非空约束,语法较特别

SQL> alter table emp modify ename not null;

外键约束(FOREIGN KEY)

外键约束定义在具有父子关系的子表中,外键约束使得子表中的列对应父表的主键列,用以维护数据库的完整性。不过出于性能和后期的业务系统的扩展的考虑,很多时候,外键约束仅出现在数据库的设计中,实际会放在业务程序中进行处理。外键约束注意以下几点:

  1.   外键约束的子表中的列和对应父表中的列数据类型必须相同,列名可以不同
  2.   对应的父表列必须存在主键约束(PRIMARY KEY)或唯一约束(UNIQUE)
  3.   外键约束列允许NULL值,对应的行就成了孤行了

  其实很多时候不使用外键,很多人认为会让删除操作比较麻烦,比如要删除父表中的某条数据,但某个子表中又有对该条数据的引用,这时就会导致删除失败。我们有两种方式来优化这种场景:

  第一种方式简单粗暴,删除的时候,级联删除掉子表中的所有匹配行,在创建外键时,通过 on delete cascade 子句指定该外键列可级联删除:

SQL> alter table emp add constraint emp_deptno_fk foreign key(deptno) references dept (deptno) on delete cascade;

  第二种方式,删除父表中的对应行,会将对应子表中的所有匹配行的外键约束列置为NULL,通过 on delete set null 子句实施:

SQL> alter table emp add constraint emp_deptno_fk foreign key(deptno) references dept(deptno) on delete set null;

实际上,外键约束列和对应的父表列可以在同一张表中,常见的就是表的业务逻辑含义是一棵树,最简单的例子如下(id为主键id,fid为父id,fid存储对id的引用),这种结构的表根据业务要求可通过Oracle的递归查询来获取这种层级关系

#

检查约束(CHECK)

检查约束可用来实施一些简单的规则,比如列值必须在某个范围内。检查的规则必须是一个结果为true或false 的表达式,比如:

SQL> alter table emp add constraint emp_sex_ck check(sex in('',''));

约束状态

  很多时候由于业务需要,比如我们有大量的历史数据,需要和现有数据合并,当前表存在数据库约束(如非空约束),而这些历史数据又包含违背非空约束的数据行,为了避免导入时由于违反约束而导入失败,我们通过调整约束状态来达到目的。

数据库约束有两类状态

  启用/禁用(enable/disable):是否对新变更的数据启用约束验证

  验证/非验证 (validate/novalidate) :是否对表中已客观存在的数据进行约束验证

这两类四种状态从语法角度讲可以随意组合,默认是 enable validate

下面我们来看着四类组合会分别出现什么样的效果:

enable validate : 默认的约束组合状态,无法添加违反约束的数据行,数据表中也不能存在违反约束的数据行;

enable novalidate : 无法添加违反约束的数据行,但对已存在的违反约束的数据行不做验证;

disable validate : 可以添加违反约束的数据行,但对已存在的违反约束的数据行会做约束验证(从描述中可以看出来,这本来就是一种相互矛盾的约束组合,只不过是语法上支持这种组合罢了,造成的结果就是会导致DML失败)

disable novalidate : 可以添加违法约束的数据行,对已存在的违反约束的数据行也不做验证。

拿上面的例子来说,我们需要上传大量违反非空约束的历史数据(从业务角度讲这些数据不会造成系统功能异常),可以临时将约束状态转为 disable novalidate,以保证这些不合要求的数据导入表中

SQL> alter table emp modify constraint emp_ename_nn disable novalidate;

在数据导入完成之后,我们再将约束状态转为enable novalidate 以确保之后添加的数据不会再违反约束

SQL> alter table emp modify constraint emp_ename_nn enable novalidate;

总结

  本文介绍了数据库中的五类约束,也提到了数据库约束的四种状态组合,当你由于业务需求或是系统扩展,在一个约束严苛的系统中由于约束限制频繁操作失败的时候,不同组合的约束状态或许能给你另一种处理方案。谢谢支持。


推荐阅读
  • nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • 【转】腾讯分析系统架构解析
    TA(TencentAnalytics,腾讯分析)是一款面向第三方站长的免费网站分析系统,在数据稳定性、及时性方面广受站长好评,其秒级的实时数据更新频率也获得业界的认可。本文将从实 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • Oracle Database 10g许可授予信息及高级功能详解
    本文介绍了Oracle Database 10g许可授予信息及其中的高级功能,包括数据库优化数据包、SQL访问指导、SQL优化指导、SQL优化集和重组对象。同时提供了详细说明,指导用户在Oracle Database 10g中如何使用这些功能。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 本文介绍了如何使用JSONObiect和Gson相关方法实现json数据与kotlin对象的相互转换。首先解释了JSON的概念和数据格式,然后详细介绍了相关API,包括JSONObject和Gson的使用方法。接着讲解了如何将json格式的字符串转换为kotlin对象或List,以及如何将kotlin对象转换为json字符串。最后提到了使用Map封装json对象的特殊情况。文章还对JSON和XML进行了比较,指出了JSON的优势和缺点。 ... [详细]
  • 图像因存在错误而无法显示 ... [详细]
  • 一面自我介绍对象相等的判断,equals方法实现。可以简单描述挫折,并说明自己如何克服,最终有哪些收获。职业规划表明自己决心,首先自己不准备继续求学了,必须招工作了。希望去哪 ... [详细]
  • 【Mysql】九、Mysql高级篇 索引
    MYSQL索引一、什么是索引?二、索引数据结构1、mysql数据库的四种索引2、BTREE结构三、索引分类、创建索引、查看索引1、单值索引2、复合索引3、函数索引4、 ... [详细]
  • mongoDB高可用集群环境搭建
    2019独角兽企业重金招聘Python工程师标准在生产环境下,部署一台mongodb服务的话,会存在以下问题:单点问题生产环境是一个 ... [详细]
  • 前面刚有AWS开战MongoDB,双方“隔空互呛”,这厢又曝出2亿+简历信息泄露——MongoDB的这场开年似乎“充实”得过分了些。长期以来,作为“最受欢迎的NoSQL数据库”,M ... [详细]
  • 数据库基本介绍
    1、数据库基本知识概念:数据库:database(DB),是一种存储数据的仓库数据库是根据数据结构组织、存储和 ... [详细]
  • MySQL:互联网公司常用 分库分表
    本文目录一、数据库瓶颈IO瓶颈CPU瓶颈二、分库分表水平分库水平分表垂直分库垂直分表三、分库分表工具四、分库分表步骤五、分库分表问题非partit ... [详细]
  • 在Ubuntu中安装MongoDB
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • 本文介绍了MongoDB中的覆盖索引查询(Covered Queries)的概念和使用方法。当查询的查询条件和查询计划中只包含索引属性时,MongoDB可以高效地执行查询操作,无需扫描documents或者将documents调入内存中。覆盖索引查询的条件是查询中的所有属性都是索引的一部分,并且查询结果中的属性值都在同一个索引中。通过使用覆盖索引查询,MongoDB可以直接从RAM中的索引中获取数据,比通过扫描文档读取数据要快得多。本文还提供了一个使用覆盖索引查询的示例。 ... [详细]
author-avatar
郝韵G
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有