所有的数据库设计人员,设计完表之后,一定要为其设置约束,以保证表中的数据是合法有效的数据
约束分六种:
数据类型
非空约束not null
某一列不能为空。
如果在设置了不能为空的列上插入了空值,则会报错
唯一约束 unique
某一列的数据不允许重复(null值例外)
如果插入了重复数据,则会提示错误,但此错误会以 (用户名…)的形式出现,这就是返回的错误信息,并且返回的错误内容。在oracle里,约束也是一个对象,而返回的一串字符是对象的名字。可以通过数据字典查看,使用(user_constraints)但此字典只能看出约束在哪个表,不能看出在表的哪个列,若想看出在哪个列,使用另一个数据字典(user_cons_columns)
但是这种方法只能在报错的时候查询一下数据字典,我们在设计表的时候可以给唯一约束设置一个别名,然后报错的时候直接根据别名判断错误原因,建议别名设置为(uk_列名)
如何给约束设置别名:
create table member (
mid number,
name varchar2(50),
constraint pk_mid_name primary key(mid,name)
);
语句:constraint 别名 约束名(列名)
主键约束primary key
主键约束= 唯一约束+非空约束
主键可以有两个(复合主键) —一般不考虑复合主键
create table member (
mid number,
name varchar2(50),
constraint pk_mid_name primary key(mid,name)
);
检查约束 check
检查约束指在更新操作前 设置一些过滤条件,满足此条件的可以实现更新
例:设置年龄范围 0-150;设置性别:男,女,中
create table member (
mid number,
name varchar2(50),
age number(3)
constraint ck_ age check(age between 0 and 250)
);
注:如果设置了过多的检查约束,那么进行数据更新的时候会严重影响到程序的性能,因为检查约束是一个个检查过滤的。最好由程序负责完成
外键约束 foreign key
两个表之间的约束,所谓的外检约束就是控制子表某一列的内容与父表中的一列数据相匹配
下面创建个示例进行演示:
创建表:
create table member(
mid number,
name varchar2(50),
constraint pk_mid primary key(mid)
);
create table book(
bid number,
title varchar2(100),
mid number,
constraint pk_bid primary key(bid),
constraint fk_mid foreign key(mid) references member(mid)
);
插入数据
insert into member (mid,name) values(10,'张三');
insert into member (mid,name) values(20,'李四');
insert into member (mid,name) values(30,'王五');
insert into book(bid,title,mid) values(101,'java',10);
insert into book(bid,title,mid) values(102,'oracle',10);
insert into book(bid,title,mid) values(103,'html+css',20);
insert into book(bid,title,mid) values(104,'vue',30);
插入错误数据:
insert into book(bid,title,mid) values(105,'c++',60);
解释:
子表book中的mid设置为父表member的外键,关联的member中的mid列,既book中的mid的值必须存在于member中的mid中。意思就是book中的mid的取值范围必须是member中mid规定好的(既member.mid中有的值)
外键作用于两个表的,一旦使用了外键,在表对象和表数据的操作上有一些限制:
限制一:
如果表中存在外键关系,那么在删除父表前,一定要先删除子表
但是如果a有b的外键,b有a 的外键,这样就不能删除了。可以采取强制删除
drop table 表名 cascade constraint;
限制二:
父表中作为外键的列,必须设置为主键或者唯一约束
否则会报错
限制三:
如果父表中的某一记录有对应的子表记录,那么父表中的这一记录不允许被删除
应该先删除掉子表中所对应的数据,在删除父表中的这一数据
但是,有时候我们希望可以首先删除父表中的某一数据,并且希望在删除父表中的某一数据之后,其对应子表中的数据也一起被删除掉,这个时候就需要用到级联操作:
constraint fk_mid foreign key(mid) references member(mid) on delete cascade;
还有些时候,我们希望首先删除表中的某一数据,其子表中的数据不被删除。这个时候可以用另外一种级联操作,可以在父表某一数据删除后,子表中的数据不会删除,对应的列变为空值:
constraint fk_mid foreign key(mid) references member(mid) on delete set null;