实体完整性在CREA TABLE
中用PRIMARY KEY
来定义。对单个属性构成的码有两种说明方法,定义为列级约束条件或表级约束条件。但是对多个属性构成的码,只有定义为表级约束条件。
例如:将Student表中的Sno属性定义为码:
CREAT TABLE Student(Sno CHAR(9) PRIMARY KEY,/*列级完整性约束条件Sno主码*/
Sname CHAR(20)UNQUIE, /*Sname取唯一值*/
Ssex CHAR(2),
Sage SMALLINT, /*短整*/
Sdept CHAR(20));
或者
CREAT TABLE Student(Sno CHAR(9),
Sname CHAR(20)UNQUIE NOT NULL, /*Sname取唯一值且不为空*/
Ssex CHAR(2),
Sage SMALLINT, /*短整*/
Sdept CHAR(20),
PRIMARY KEY(Sno)); /*表级完整性约束*/
多个属性构成码的情况:
CREAT TABLE SC(Sno CHAR(9) NOT NULL,
Cno CHAR(4) NOT NULL,
Grade SMALLINT,
PRIMARY KEY (Sno,Cno),/*主码由两个主属性构成,必须作为表级完整性进行定义*/
);
当我们用PRIMARY KEY
短语定义了关系的主码后,每次我们对基本表插入一条记录或对主码列进行更新操作的时候,关系数据库管理系统会根据实体完整性中的规则自动进行检查。包括:
检查记录中是否唯一的一种方法是进行全表扫描,依次判断表中每一条记录的主码值与将插入记录的主码值(或者修改的新主码值)是否相同。
全表扫描十分耗时,关系数据库管理系统一般都在主码上自动建立索引(B+树索引),大大提高效率。例如,如果新插入的主码值是25,通过主码索引,首先从树的根结点开始,如果小于根结点,往左子树比较,如果大于根结点往右子树比较。所以只要读取三个结点就可以知道值25已经存在,故不能插入。如果插入值为86,也只要查找三个结点就可以知道86不存在,可以插入。
参照完整性的规则:若属性(或者属性组)F是基本关系R的外码它与基本关系S的主码Ks对应(基本关系R和S可以是相同的关系),则对于R中每个元组在F上的值必须为:
例:学生关系的‘专业号’是外码,它参照专业关系的主码‘专业号’
R和S可以是同一个关系,在学生(学号,姓名,性别,年龄,专业号,班长)关系中,‘班长’属性表示该学生所在班级的班长的学号,它引用了本关系中‘学号’属性,所以‘班长’必须是确实存在的学生的学号。同时外码并不一定与相应的主码同名,这里主码是学号,外码是班长,但是当外码和主码属于不同关系时,往往用相同的名字。
参照完整性在CREAT TABLE
中用FOREIGN KEY
短语定义哪些列为外码,用REFERENCES
短语指明这些外码参照哪些表的主码。
例如:在选修课表SC中(Sno、Cno)构成主码,而Sno、Cno分别参照引用Student表和Course表的主码
定义SC中的参照完整性:
CREAT TABLE SC(Sno CHAR(9) NOT NULL,
Cno CHAR(4) NOT NULL,
Grade SMALLINT,
PRIMARY KEY (Sno,Cno),/*主码由两个主属性构成,必须作为表级完整性进行定义*/
FOREIGN KEY (Sno) REFERENCES Student(Sno),/*在表级定义参照完整性*/
FOREIGN KEY (Cno) REFERENCES Course(Cno)/*在表级定义参照完整性*/
);
参照完整性将两个表的相应元组联系起来,引用和被引用。因此,对被参照表和参照表进行增、删、改操作时有可能破坏参照完整性,必须检查以保证这个两个表的相容性。
例如:表SC和Student有四种可能破坏参照完整性的情况
2.
3.
4.
当上述的不一致发生时,系统可以才取一下策略加以处理:
NO ACTION
):不允许该操作执行,为默认策略CASCADE
):当删除或修改被参照(Student)的一个元组导致与参照表(SC)的不一致时,一并删除或修改参照表中所有不一致的元组。参照完整性的违约处理示例:
CREAT TABLE SC(Sno CHAR(9) NOT NULL,
Cno CHAR(4) NOT NULL,
Grade SMALLINT,
PRIMARY KEY (Sno,Cno),/*主码由两个主属性构成,必须作为表级完整性进行定义,Sno和Cno不可取空值*/
FOREIGN KEY (Sno) REFERENCES Student(Sno),/*在表级定义参照完整性*/
ON DELETE CASCADE /*当删除Student表中元组时,级联删除SC表中的相应元组*/
ON UPDATE CASCADE, /*当更新Student表中元组时,级联更新SC表中的相应元组*/
FOREIGN KEY (Cno) REFERENCES Course(Cno)/*在表级定义参照完整性*/
ON DELETE NO ACTION /*当删除Course表中的元组造成与SC表不一致时,拒绝删除,这一条也可以不写,是默认策略*/
ON UPDATE CASCADE /*当更新Course表中的Cno试,级联更新SC表中相应元组*/
);
在CREAT TABLE
中定义属性的同时,可以根据应用要求来定义属性上的约束,对属性值的限制,包括:
NOT NULL
)UNIQUE
)CHECK
短语)NOT NULL
和UNIQUE
经常使用
用CHECK
短语指定列值应该满足的条件:
CREAT TABLE Student(Sno CHAR(9) PRIMARY KEY,/*列级完整性约束条件Sno主码*/
Sname CHAR(20)UNQUIE, /*Sname取唯一值*/
Ssex CHAR(2) CHECK (Sex IN('男','女')),/*性别属性只允许设置为男和女*/
Sage SMALLINT CHECK(Sage>=18 AND Sage<=25), /*短整,年龄只能在18~25之间*/
Sdept CHAR(20));
与属性上约束条件类似,使用CHECK
短语定义元组上的约束条件,元组级的限制可以设置不同属性之间的取值的相互约束条件。
例如:当学生的性别试男时,其名字不能以Ms.开头
CREAT TABLE Student(Sno CHAR(9) PRIMARY KEY,/*列级完整性约束条件Sno主码*/
Sname CHAR(20)UNQUIE NOT NULL, /*Sname取唯一值且不为空*/
Ssex CHAR(2),
Sage SMALLINT, /*短整*/
Sdept CHAR(20));
CHECK (Ssex = '女' OR Sname NOT LIKE 'Ms.%')/*定义了元组Sname和Ssex两个属性之间鳄段约束条件*/
);
性别是女的,通过CHECK
检查,如果是男的,若条件为真,必须Sname开头不能为Ms.
以上的完整性约束条件是在CREAT TABLE
语句中定义,我们还可以在CREAT TABLE
中使用完整性约束命名子句CONSTRAINT
,用来对完整性约束取别名,这样方便我们增加,或者删除。如果没有命名,那么约束名是默认的,需要在数据字典中查看。
CONSTRAIN <完整性约束条件名><完整性约束条件>
,<完整性约束条件>包括NOT NULL
、UNIQUE
、PRIMARY KEY
、FOREIGN KEY
、CHECK
等CREAT TABLE Student(Sno NUMERIC(6)
CONSTRAINT C1 CHECK(Sno BETWEEN 172100 AND 172199)./*约束名为C1*/
Sname CHAR(20)
CONSTRAINT C2 NOT NULL,/*约束名为C2*/
Sage NUMERIC(3)
CONSTRAINT C3 CHECK (Sage<30),/*约束名为C3*/
Ssex CHAR(2)
CONSTRAINT C4 CHECK (Ssex IN('男','女')),/*约束名为C4*/
CONSTRAINT StudentKey PRIMARY KEY(Sno) /*主码约束名为StudentKey*/
);
)
ALTER TABLE <表名> DROP <约束名>
,ALTER TABLE <表名> ADD CONSTRAINT <完整性条件约束名><完整性约束>