前言
表建立完成后,并不能检查表中的数据是否合法,如果想要针对表中的数据做一些过滤的话,则可以通过约束完成。
约束的主要功能是保证表中的数据合法性,按照约束的分类,一共有五种约束:
非空约束、唯一约束、主键约束、检查约束、外键约束
一、非空约束 /NOT NULL/NK
当数据表中的某个字段上的内容不希望设置为null的话,则可以使用NOT NULL进行指定
<1>定义一张表,指定name字段不能为空
SQL> create table member(
2 mid number,
3 name varchar2(20) not null);
<2>插入正确的数据
SQL> insert into member(mid,name) values(1,'zhangsan');
<3>当插入name为空的数据时,会报错
二、唯一键约束 /UNIQUE/UK
唯一约束指的是某一个列上的数据是不允许重复的,如邮件地址。
<1>定义一张数据表
SQL> drop table member purge;
SQL> create table member(
2 mid number,
3 name varchar2(50) not null,
4 email varchar2(50) unique);
<2>插入正确的数据
SQL> insert into member(mid,name,email) values(1,'zhangsan','123@qq.com');
<3>插入email字段重复的数据
<4>为了了解具体的错误信息,可以在创建表时,添加约束条件
SQL> drop table member purge;
SQL> create table member(
2 mid number,
3 name varchar2(20) not null,
4 email varchar2(20),
5 constraint uk_email unique(email)); //uk_email自定义
<5>再次尝试添加重复的邮箱,可以看到错误提示,受到email字段的唯一键约束
三、主键约束/PRIMARY KEY/PK
主键约束=非空约束+唯一约束。在之前设置唯一约束的时候发现可以设置为null,而如果使用了主键约束之后则不能为null,而主键一般作为数据的唯一的一个标记出现,例如人员的编号
1.单独主键
<1>建立主键约束
SQL> drop table member purge;
SQL> create table member(
2 mid number primary key,
3 name varchar2(20) not null);
<2>插入正确的数据
SQL> insert into member (mid,name) values (1,'zhangsan');
<3>若插入mid重复,或name为空则会报错
<4>上图唯一键错误不明确,我们可以设置约束名称
SQL> drop table member purge;
SQL> create table member(
2 mid number,
3 name varchar2(20) not null,
4 constraint pk_mid primary key(mid));
<5>验证结果
2.复合主键
<1>建立约束主键
SQL> drop table member purge;
SQL> create table member(
2 mid number,
3 name varchar2(20),
4 constraint pk_mid_name primary key(mid,name));
<2>插入正确的数据
SQL> insert into member (mid,name) values (1,'zhangsan');
SQL> insert into member (mid,name) values (1,'lisa');
SQL> insert into member (mid,name) values (2,'lisa');
在复合主键的使用之中,只有两个字段的内容都一样的情况下,才被称为重复数据。
<3>再次插入字段完全一致的内容时会报错
四、检查约束 /CHECK/CK
检查约束指为表中的数据增加一些过滤条件,如:设置年龄的时候范围为0-200,设置性别的时候为男、女和其他
<1>设置检查约束
SQL> drop table member purge;
SQL> create table member(
2 mid number,
3 name varchar2(20) not null,
4 gender varchar(10) not null,
5 age number(3),
6 constraint pk_mid primary key(mid),
7 constraint ck_gender check (gender in ('man','woman','other')),
8 constraint ck_age check (age between 0 and 200));
<2>插入正确的数据
SQL> insert into member (mid,name,gender,age) values (1,'lisa','woman',20);
<3>插入错误的性别和年龄
五、外键约束
之前的约束都是在单张表中进行的,而外键约束是在两张表中进行的,这两张表是存在父子关系的,即子表中的某个字段的取值范围是由父表所决定。
1.<1>创建有相同字段的两张表,在末行添加外键约束
SQL> create table member(
2 mid number,
3 name varchar2(50) not null,
4 constraint pk_mid primary key (mid));
SQL> create table book(
2 bid number,
3 title varchar2(20) not null,
4 mid number,
5 constraint pk_bid primary key (bid),
6 constraint fk_mid foreign key (mid) references member (mid));
<2>向两张表中插入如下数据
SQL> insert into member (mid,name) values (1,'zhangsan');
SQL> insert into member (mid,name) values (2,'lisi');
SQL> insert into book (bid,title,mid) values (101,'java',1);
SQL> insert into book (bid,title,mid) values (102,'android',2);
SQL> insert into book (bid,title,mid) values (103,'python',2);
SQL> insert into book (bid,title,mid) values (104,'ejb',1);
SQL> insert into book (bid,title,mid) values (105,'ajax',1);
<3>有外键约束后,我们向book表添加member中没有的mid字段的值,可以看到错误中显示其在父表中无法找到mid=5的行
2.使用外键最大好处是控制了子表中某些数据的取值范围,但是同样带来了不少的问题,如:
<1>删除member表中mid为1的数据
由于外键约束关系,错误提示找到子记录 ,所以我们可以先删掉子表中mid为1的值再删除父表中mid=1的值
这种操作明显不方便,若在主表数据删除之后,子表中对应的数据也可以删除,则可在建立外键的时候指定一个级联删除的功能,修改数据库创建脚本;
删除原来的表(先删除子表再删除父表),重新创建,在末尾添加"on delete cascade"
constraint fk_mid foreign key (mid) references member (mid) on delete cascade
还是上面的数据,此处略
此时删除父表中mid=1的数据("SQL> delete from member where mid=1;"),查询子表已经不存在mid=1的数据,如下图
<2>删除数据的时候,让子表中对应的数据设置为null
删除原来的表(先删除子表再删除父表),重新创建,在末尾添加"on delete set null"
constraint fk_mid foreign key (mid) references member (mid) on delete set null
此处数据省略不粘贴同上
此时删除父表中mid=1的数据("SQL> delete from member where mid=1;"),查询子表mid=1的数据都为空,如下图
<3>先删除子表,再删除父表,这种操作很麻烦,对于未知的数据库,若要按照此顺序来执行,须知道表之间的父子关系。
在oracle中,提供了一个强制性删除表的操作,不再关心约束,如下:
SQL> drop table member cascade constraint purge;
再次查询子表,未受影响