完整性的约束

维护完整性
非空约束:
唯一约束
主键约束
检查约束
主外健约束:(最麻烦的约束)


非空约束:什么叫非空,空是列属性的合法。
如果要设置非空约束的话,只要在表加非空如下
drop table member purge;
create table member (
mid number ,
name varchar2(20) not null
)
insert into member (mid ,name )values(1, '余华')
insert into member (mid , name )values(2, null)
这时报出异常,不能插入null

select * from member

唯一约束:
主要的作用,是表上的列不能有重复
create table member (
mid number ,
name varchar2(20) not null,
email varchar2(50) unique
)
insert into member (mid ,name,email )values(1, '余华','dfs@dfs.com');
insert into member (mid ,name,email )values(2, '余华1','dfs@dfs.com');
这时报出异常,00001错误信息。

约束的简写:“约束简写_字段”,那么现在唯一约束的简写应该是UK,

create table member (
mid number ,
name varchar2(20) not null,
email varchar2(50),
constraint uk_email unique(email)
)
这样插入数据,报错会告诉你是uk_email 的错误。而不是告诉你动态的错误。
insert into member (mid ,name,email )values(1, '余华',null);
insert into member (mid ,name,email )values(2, '余华1',null);
在这里null 是不受约束

具体要看数据库原理的约束。

如果你不想为空,不像重复,就用主键 pk

主键约束:
了解复合主键的定义。
主键约束=非空约束+唯一约束
简称pk ,

create table member (
mid number primary key,
name varchar2(20) not null,
email varchar2(50),
constraint uk_email unique(email)
)
将mid 设置为空
insert into member (mid ,name,email )values(null, '余华',null);
这是就报出mid不能为空,ORA-01400.
如果设置重复,
insert into member (mid ,name,email )values(1, '余华',null);
insert into member (mid ,name,email )values(1, '余华',null);
这是就报出不能重复,ORA-00001。

如果没有为主键约束设置名字,报出异常是动态的
create table member (
mid number ,
name varchar2(20) not null,
email varchar2(50),
constraint pk_mid primary key (mid),
constraint uk_email unique(email)
)
主键名字设置之后,错误信息就会出现该主键名字。
在开发过程中,每个表都要有一个主键,有一些表可以不用主键。
复合主键,尽量不要去用。
create table member (
mid number ,
name varchar2(20) not null,
email varchar2(50),
constraint pk_mid primary key (mid,name),
constraint uk_email unique(email)
)
insert into member (mid ,name,email )values(1, '余华',null);
insert into member (mid ,name,email )values(2, '余华',null);
只有两个主键,字段都相同,就会违法复合主键约束,这是还没报出。
insert into member (mid ,name,email )values(2, '余华',null);
这时就报出错误。

一般不建议使用复合主键。

检查约束:ck
检查约束就是说,对我们数据更新操作,相当于过滤网一样。
drop table member purge;
create table member (
mid number ,
name varchar2(20) not null,
email varchar2(50),
sex varchar2(20),
age number check ( age between 0 and 200 ),
constraint pk_mid primary key (mid,name),
constraint uk_email unique(email),
constraint ck_sex check (sex in ('男','女'))
)
insert into member (mid ,name,email ,sex,age)values(1, '余华','dfa@dd','男',100);
如果增加的检出约束越多,那么实际上一定会影响更新的性能,所以一张数据表如果被频繁修改的话,那么检出约束不建议使用了
这些验证操作一般由程序来完成,减少数据库的压力。


主——外键:
外键约束难度不高,
外键约束
范例:编写一个脚本,
drop table member purge;
create table member (
mid number ,
name varchar2(20) not null,
age number check ( age between 0 and 200 ),
constraint pk_mid primary key (mid)
);
create table advice (
adid number,
content clob not null,
mid number,
constraint pk_adid primary key (adid)
)
先增加一个数据
insert into member (mid,name ) values(1,'梨花');
insert into member (mid,name ) values(2,'马涛');

insert into advice (adid,content,mid ) values(1,'应该提倡内部沟通机制,设置经理办公室',1);
insert into advice (adid,content,mid ) values(2,'应该提出外部',1);
insert into advice (adid,content,mid ) values(3,'应该提倡整理办公室',2);
insert into advice (adid,content,mid ) values(4,'应该提倡完善机制',2);

查询出每个成员的完整信息等
select m.mid,m.name,a.content
from member m,advice a
where m.mid=a.mid
order by m.mid

这个时候,插入
insert into advice (adid,content,mid ) values(5,'应该提倡完善机制',99);
现在查询,就找不到99号的数据
select m.mid,m.name,a.content
from member m,advice a
where m.mid=a.mid
order by m.mid

为了保证外键的约束性,
增外键。
drop table advice purge;
create table advice (
adid number,
content clob not null,
mid number,
constraint pk_adid primary key (adid),
constraint fk_mid foreign key(mid) references member (mid)
);
insert into advice (adid,content,mid ) values(1,'应该提倡内部沟通机制,设置经理办公室',1);
insert into advice (adid,content,mid ) values(2,'应该提出外部',1);
insert into advice (adid,content,mid ) values(3,'应该提倡整理办公室',2);
insert into advice (adid,content,mid ) values(4,'应该提倡完善机制',2);

insert into advice (adid,content,mid ) values(5,'应该提倡完善机制',99);
此时插入99号码的信息,就报出错误。

如果要删除父表的数据,先删除子表的数据。
delete from member where mid=2

这样的做法太狠了,为了解决外键中的数据的操作问题,实际上就提出l数据的级联问题 on delete cascade
drop table advice purge
drop table member purge

create table member (
mid number ,
name varchar2(20) not null,
age number check ( age between 0 and 200 ),
constraint pk_mid primary key (mid)
);
create table advice (
adid number,
content clob not null,
mid number,
constraint pk_adid primary key (adid),
constraint fk_mid foreign key(mid) references member (mid) on delete cascade
);
insert into member (mid,name ) values(1,'梨花');
insert into member (mid,name ) values(2,'马涛');

insert into advice (adid,content,mid ) values(1,'应该提倡内部沟通机制,设置经理办公室',1);
insert into advice (adid,content,mid ) values(2,'应该提出外部',1);
insert into advice (adid,content,mid ) values(3,'应该提倡整理办公室',2);
insert into advice (adid,content,mid ) values(4,'应该提倡完善机制',2);

delete from member where mid=2
select * from member
select * from advice
直接将关联的数据也删除了。

另外有一种级联更新,ON DELETE SET NULL
主表数据被删除了,对应得子表变成null
drop table advice purge;
drop table member purge;

create table member (
mid number ,
name varchar2(20) not null,
age number check ( age between 0 and 200 ),
constraint pk_mid primary key (mid)
);
create table advice (
adid number,
content clob not null,
mid number,
constraint pk_adid primary key (adid),
constraint fk_mid foreign key(mid) references member (mid) ON DELETE SET NULL
);
insert into member (mid,name ) values(1,'梨花');
insert into member (mid,name ) values(2,'马涛');

insert into advice (adid,content,mid ) values(1,'应该提倡内部沟通机制,设置经理办公室',1);
insert into advice (adid,content,mid ) values(2,'应该提出外部',1);
insert into advice (adid,content,mid ) values(3,'应该提倡整理办公室',2);
insert into advice (adid,content,mid ) values(4,'应该提倡完善机制',2);

delete from member where mid=2;
select * from member
select * from advice


以上的级联删除操作,是看实际,看业务需求。
所有程序没有一个固定的方法。
如果说现在直接删除父表
有一种强制性删除:(不管你有没有外键)
drop table member cascade constraint;
以下子就删除,这样删除会带来什么坏处呢?
不建议使用是在我们编写数据的时候,要考虑先后的关系。
这个方法作为知识点知道就行了。

主要是集中在数据级联操作上。
drop table advice

最麻烦的是外键。
学数据库最好的方式,就是看数据。

查看约束:
约束是由数据库自己创建的对象,所有对象都会在数据字典之中进行保存,
将回收站清空:
PURGE RECYCLEBIN

create table member(
mid number primary key,
name varchar2(20) not null
)

insert into member(mid,name) values (1,'张三');
insert into member(mid,name) values (1,'王五');

查看约束
select * from user_constraints;
知道约束,不知道字段,那应该怎么办?
select * from user_cons_columns;

约束是要取名字,便于维护,这就是约束。


修改约束:(这个也是大概了解就行了)
之前说过,表尽量不要修改,约束和表一起建立起来。
这个算是sql 的标准语法。
增加约束:
如果表没有任何约束,那么可以通过指定的语法来增加约束。
在约束中,有非空。
drop table member purge
create table member(
mid number ,
name varchar2(20),
age number
)
查看有没有约束:
select * from user_constraints where table_name='MEMBER'
增加约束:
设置主键约束:(名称是不可以重复的)
alter table member add constraint pk_mid primary key (mid);

非空约束:(而不是通过以上的设置非空)
alter table member modify (name varchar2(20) not null)

insert into member (mid, name ) values(1,null)


禁用主键、外键的方法:
alter table menber disable constraint ps_mid cascade;

启用主键:
alter table menber enable constraint pk_mid;
alter table menber enable constraint pk_adid;
如果要保证约束可以正的启用,要保证数据中重复数据的问题。

约束一定要和表一起建立,最低限度也应该数据库正式使用之前,就要设置好。