说白了就是保证数据安全、合法。

比如列”Sex”,其值只能是”male”或”female”。
比如主键必须不为空且不能重复
外键也有一些约束
数据库必须有一套机制来保证数据合法。

完整性约束条件(或称完整性约束规则)的一般形式
Integrity Constraint ::= ( O,P,A,R)

  • O:数据集合:约束的对象? 可以是列、多列(元组)、元组集合
  • P:谓词条件:什么样的约束?
  • A:触发条件:什么时候检查?
  • R:响应动作:不满足时怎么办?

一、分类

1、按约束对象分类

1)、域完整性约束条件
即对单独一列的条件检查。作用在一列上。
如: Sage>0
2)、关系完整性(表完整性)约束条件
对多列进行综合判断。
比如每小时工资不少于30元:
Salary/Time >=30
(Salary与Time是不同的列)

作用在一张表上。

2、按约束来源分类

1)结构约束
来自于模型的约束,例如函数依赖约束、主键约束(实体完整性)、外键约束(参照完整性),只关心数值相等与否、是否允许空值等;
2)内容约束
来自于用户的约束,如用户自定义完整性,关心元组或属性的取值范围。例如Student表的Sage属性值在15岁至40岁之间等。

按约束状态分类

1)静态约束
要求DB在任一时候均应满足的约束;例如Sage在任何时候都应满足大于0而小于150(假定人活最大年龄是150)。
2)动态约束
要求DB从一状态变为另一状态时应满足的约束;例如工资只能升,不能降:工资可以是800元,也可以是1000元;可以从800元更改为1000元,但不能从1000元更改为800元。

二、SQL实现:

域约束示例:

Create Table Student ( S# char(8) not null unique, 
                    Sname char(10),
                    Ssex char(2) constraint ctssex check (Ssex=‘男’ or Ssex=‘女’), 
                    Sage integer check (Sage>=1 and Sage<150),
                    D# char(2) references Dept(D#) on delete cascade,
                    Sclass char(6) );

Ssex取值只能为’男’或’女’。该规则被命名为ctsex,命名是为了日后进行删除等操作
D#为外键,Dept中的D#为主键。on delete cascade的意思是:如果主键中数据被删除,Student中的外键对应数据也会被删除。如果不定义on delete cascade,删除会报错。

表约束示例1:

Create Table Course ( C# char(3) , Cname char(12), Chours integer,
Credit float(1) constraint ctcredit check (Credit >=0.0 and Credit<=5.0 ), 
T# char(3) references Teacher(T#) on delete cascade, 
primary key(C#),
constraint ctcc check(Chours/Credit = 20) );

表约束示例2:

Create Table SC ( S# char(8), C# char(3),
Score float(1) constraint ctscore check (Score>=0.0 and
Score<=100.0),
forergn key (S#) references student(S#) on delete cascade,
forergn key (C#) references course(C#) on delete cascade );

三、断言

语法:

CREATE ASSERTION <assertion-name> CHECK <predicate>

当一个断言创建后,系统将检测其有效性,并在每一次更新中测试更新是否违反该断言。

断言使用起来很方便,但会增加数据库系统的负担,所以要谨慎使用。

示例“每笔贷款,要求至少一位借款者账户中存有最低数目的余额,例如1000元”

create assertion balance_constraint check
(not exists (
select * from loan
where not exists (
select * from borrower, depositor, account
where loan.loan_number = borrower.loan_number
and borrower.customer_name = depositor.customer_name
and depositor.account_number = account.account_number
and account.balance >= 1000)))

断言里的语句应该是要返回一个布尔值。