注:所有的下划线+斜体语句都是非必须语句
静态约束:
- 数据集合(O):列或者表
- 谓词条件(P):需要定义
- 触发条件(A):更新时检查(默认)
- 响应动作(R):拒绝(默认)
Col_constr 列约束/table_constr 表约束:
创建表时增加约束:Create table 表名(列名1 not null
unique 或 primary key 或 check (表达式) 或 ( references 表名(列名) on delete cascade 或 set null )
列名2 约束……)
- not null:列值不能为空
- unique:列值是否唯一
- primary key:列值是否为主键
- check (表达式):列值必须满足的条件,例如"岁数"不能超过100岁,不能为负数
- references 表名(列名) on delete cascade 或 set null:级联更新,引用另一表tablename的列colname的值,如有on delete cascade 或on delete set null 语句,则删除被引用表的某列值v时,要将本表该列值为v的记录删除或列值更新为null;缺省为无操作
例子:
创建一个学生表,性别要检查只能是"男"或"女",岁数要检查是否在[1, 149]范围内,Dt作为表Dept的外键,如果Dept中Dt被 学校开除,则该学生表中所有与Dt相关的元组全部一并删除
Create Table Stpudent(St char(8) not null unique, Sname char(10),
Ssex char(2), check(Ssex='男' or Ssex='女'),
Sage integer check (Sage>=1 and Sage<150),
Dt char(2) references Dept(Dt) on delete cascade,
Sclass char(6));
创建表后增加约束:Alter table 表名 add constraint 约束名 约束……
注意创建表后增加的约束如果是级联更新,那么必须在语句"references infer(st) …"前加上"foreign key(st)"声明外键
创建表后删除约束:Alter table 表名 drop constraint 约束名 约束……
注意Mysql可能不支持上述语句,并且Mysql也不支持check(),只不过可以运行
同理Mysql只能删除外键约束和主键约束
例子:
alter table sc
add constraint yueshu1 unique(st);
alter table sc
add constraint yueshu2 check(ct='001' or ct='002' or ct='003' or ct='004' or ct='005');
alter table infer
add constraint yueshu3 unique(st);
alter table infer
add constraint yueshu4 check(ct='001' or ct='002' or ct='003' or ct='004' or ct='005');
alter table sc
add constraint yueshu5 foreign key(st) references infer(st) on delete cascade;
注意:
- 如果原本的元组不满足现在增加的约束,那么增加约束就会失败(Mysql:Error1062)
- 如果增加的约束重复,那么增加约束也会失败(Mysql:Error1061)
check 中的条件可以是Select-From-Where 内任何Where后的语句,包含子查询,例如:
选课表中的课程必须在课程表里有,学生必须在学号名单里面有
create Table Sc(St char(8) check(St in (select St from student)),
Ct char(3) check( Ct in (select Ct from course)),
Score float(1), constraint ctscore check (Score>=0.0 and
Score<=100.0))
断言:
- 一个断言就是一个谓词表达式,它表达了希望数据库总能满足的条件
- 表约束和列约束就是一些特殊的断言
- SQL还提供了复杂条件表达的断言,其语法形式为:create assertion 断言名 check 谓词
- 当一个断言创建后,系统将检测其有效性,并在每一次更新中测试更新是否违反该断言
- 断言测试增加了数据库维护的负担,要小心使用复杂的断言,也几乎没有人用断言