外键约束先要理清几个概念:1)候选键(Candidate Key):关系中的一个属性组,其值能唯一标识一个元组,若从该属性组中去掉任何一个属性,它就不具有这一性质了,这样的属性组称作候选键(候选码)。
2)主键(Primary Key):当有多个候选键时,可以选定一个作为主键,选定的候选键称为主键(主码)。
主键唯一标识表中的每行记录。
主键约束有如下特点:每个表中只能有一个主键,主键可以是一列,也可以是多列的组合;主键值必须唯一并且不能为空,对于多列组合的主键,某列值可以重复,但列的组合值必须唯一。
3)外键(Foreign Key):关系R中的一个属性组,它不是R的候选键,但它与另一个关系S 的候选键相对应,则称这个属性组为R的外键(外码)。
关系R称为参照关系(参照表、从表),关系S称为被参照关系(被参照表、主表)。
外键是指一个表(从表)中的一列或列组合,它虽不是该表的主键,但却是另一个表(主表)的主键。
通过外键约束可以为相关联的两个表建立联系,实现数据的引用完整性,维护两表之间数据的一致性关系。
特殊情况下,参照关系和被参照关系可以是同一个关系。
即,特殊情况下,从表和主表可以是同一个表。
参照[引用]关系(Referencing Relation)、子表、从表、外键表、参照[引用]表,这些作为同一术语的同义词使用。
被参照[被引用]关系(Referenced Relation)、父表、主表、主键表、被参照[被引用]表、查找表,这些作为同一术语的同义词使用。
请注意,在英语国家讲数据库的英语文献中,relation有时指“表”,有时指两表之间的联系(relationship)。
指两表之间的relationship时也常用link[链接]。
relationship和relation通常都翻译为关系,但在数据库中两者含义不同。
relationship [关系;联系;关联],在数据库中指不同表之间的数据彼此联系的方法。
数据库表之间的表之间的relationship有:一对一、一对多、多对多。
relation[关系],在数据库指表,从本质上说,关系是一个包含行和列的二维表或数组。
应根据语境区别理解。
例、有两个关系:student (s#, sname, d#),即学生这个关系有三个属性:学号,姓名,所在系别department(d#, dname),即院系有两个属性:系号、系名则s#、d#是各自所在关系的主键,d#还是关系student的外键。
student是参照关系(从表),department是被参照关系(主表)。
建立外键约束(FOREIGN KEY)后,从表中的外键的取值,要么在主表有对应的值,要么为NULL,但不能是主表中没有对应的值。
特殊情况下,从表和主表可以是同一个表。
通过外键能实现数据的参照完整性(Referential Integrity引用完整性),参照完整性约束意味着,从表中某列(外键列)和主表中的某列(主键或UNIQUE约束)匹配。
这些列称为对应列(有时也称为公共字段)。
外键既能确保数据完整性,也能表现表之间的关系(relationship)。
也就是说,如果你为引用表(从表)定义了外键,就在你定义外键的表(从表、引用表)和外键引用的表(主表、被引用表)之间既确保了数据完整性也确定了两表之间的关系。
◇建立外键约束后,从表中的外键的取值,要么在主表有对应的值,要么为NULL,通过定义引用列(从表中的外键)为NOT NULL,可以确保外键的取值必须在主表有对应的值。
☆建立参照完整性约束后的级联动作受{ON DELETE | ON UPDATE} { NO ACTION | CASCADE |SET NULL | SET DEFAULT }决定,默认拒绝(NO ACTION)。
建立外键约束后,DBMS将执行参照完整性检查和违约处理:[注]拒绝执行时,将产生一个错误提示。
①更新主表中的主键(或UNIQUE约束)值操作。
②由ON DELETE { NO ACTION | CASCADE | SET NULL | SET DEFAULT }决定,默认拒绝执行(NO ACTION)。
③由ON UPDATE { NO ACTION | CASCADE | SET NULL | SET DEFAULT }决定,默认拒绝执行(NO ACTION)。
建立外键约束后,DBMS将如下检查处理:外键约束对子表如此检查处理:在子表上进行INSERT、UPDATE 操作的限制是,要和主表中的主键值匹配,或为NULL,否则不允许。
外键约束对父表如此检查处理:在父表上进行UPDATE、DELETE操作的限制,取决于在定义子表的外键时指定的ON UPDATE、ON DELETE子句(不同的DBMS支持的情况不尽相同)。
☆ON DELETE子句各选项的作用:①NO ACTION :删除主表记录,如果子表中有和主表匹配的记录,则不允许(产生一个错误提示)。
此为默认操作(不指定ON DELETE子句,系统自动采取的操作)。
②CASCADE (级联):删除主表记录,也将删除子表中的匹配记录。
③SET NULL :删除主表记录,将子表中的匹配记录的外键值改为NULL。
④SET DEFAULT :删除主表记录,将子表中的匹配记录的外键值改为默认值。
☆ON UPDATE子句各选项的作用:①NO ACTION :更新主表记录的主键值,如果子表中有和主表匹配的记录,则不允许(产生一个错误提示)。
此为默认操作(不指定ON UPDATE子句,系统自动采取的操作)。
②CASCADE :更新主表记录的主键值,子表中的匹配记录的外键值一起修改。
③SET NULL :更新主表记录的主键值,子表中的匹配记录的外键值改为NULL。
④SET DEFAULT :更新主表记录的主键值,子表中的匹配记录的外键值改为默认值。
参照完整性属于表间规则。
对于相关的表,在更新、插入或删除记录时,如果只改其一不改其二,就可能影响数据的完整性:例如,删除父表的某记录后,子表的相应记录未删除,致使这些记录成为孤立记录;修改父表中对应列的值后,子表对应列的值未做相应改变;对于子表插入的记录,父表中没有对应列的值的记录;更改子表的外键值,父表中没有对应列的值的记录。
外键约束的例子先创建一个主表deptCREATE TABLE dept(deptno NUMBER(4) PRIMARY KEY,deptname VARCHAR2(20),loc VARCHAR(50));在从表中建立外键约束,可以指定也可以不指定约束名。
如省略约束名,则系统自动给出一个约束名。
☆建立从表emp_1时未指定约束名CREATE TABLE emp_1(empno NUMBER PRIMARY KEY,ename VARCHAR2(20) NOT NULL,email VARCHAR2(60) UNIQUE,sal NUMBER(5) CHECK(sal>1500),deptno NUMBER(4) REFERENCES dept(deptno) --无名的外键);☆建立从表emp_2时指定了约束名CREATE TABLE emp_2(empno NUMBER PRIMARY KEY,ename VARCHAR2(20) NOT NULL,email VARCHAR2(60) UNIQUE,sal NUMBER(5) CHECK(sal>1500),deptno NUMBER(4) CONSTRAINT fk_name2 REFERENCES dept(deptno) --带名的外键);为约束指定恰当的名称,可便于管理约束。
外键约束的名称,用作标识,只要是允许的标识符即可,但有人建议将涉及的表标出,如FK_从表名_主表名或FK_主表名_从表名。
顺便指出,在定义外键时,如果被引用的列是主表中的主键,可以省略被引用的列。
如上例中REFERENCES dept(deptno),因为被引用的列deptno是主表dept的主键,所以也可以写成REFERENCES dept外键(FOREIGN KEY)约束,一般用于引用其他表。
FOREIGN KEY 可以是单列键或多列键。
以下示例显示SalesOrderHeader 表上引用SalesPerson 表的单列FOREIGN KEY 约束。
对于单列FOREIGN KEY 约束,只需要REFERENCES 子句。
SalesPersonID int NULLREFERENCES SalesPerson(SalesPersonID)也可以显式使用FOREIGN KEY 子句并复述列特性。
请注意,在这两个表中列名不必相同。
FOREIGN KEY (SalesPersonID) REFERENCES SalesPerson(SalesPersonID)多列键约束作为表约束创建。
在AdventureWorks2012 数据库中,SpecialOfferProduct 表包含多列PRIMARY KEY。
以下示例显示如何从其他表中引用此键(可选择显式约束名)。
CONSTRAINT FK_SpecialOfferProduct_SalesOrderDetailFOREIGN KEY (ProductID, SpecialOfferID)REFERENCES SpecialOfferProduct (ProductID, SpecialOfferID)如果仅包含一列可以使用列约束(列级约束),也可使用表约束(表级约束);如果包含两列或更多列,就必须使用表约束。
列级约束可在定义列时指定。
对于列级外键约束只需要REFERENCES 子句;对于表级外键约束使用FOREIGN KEY 和REFERENCES 子句指定。
列约束与表约束约束的类型:PRIMARY KEY(主键)约束、FOREIGN KEY(外健)约束、UNIQUE(唯一)约束、NOT NULL(非空)约束、CHECK(检查)约束、DEFAULT(默认)约束。
当约束被定义于某个表的一列时称为列约束,定义于某个表的多列时称为表约束。
当一个约束中必须包含一个以上的列时,必须使用表约束。
·什么约束可以实现需要的数据完整性:不同的约束提供了不同的功能。
·在什么时候实施约束最合适:SQL server允许推迟或者禁用某些已经定义的约束。
外键(FOREIGN KEY)约束,也可引用同一表中的其他列。
此行为称为自引用。
引用的列在同一个表中,而非在另一个表中,这是可以的,虽然这种情况不常见。
create table Course(Cno char(4) primary key,Cname char(40),Cpno char(4) references Course(Cno), --指定自引用Ccredit smallint);或create table Course(Cno char(4) primary key,Cname char(40),Cpno char(4),Ccredit smallint,foreign key (Cpno) references Course(Cno) --指定自引用);创建外键约束时需要遵守的原则:①被外键引用的主表(父表、被参照关系、被引用表、被参照表referenced_table 、主键表)中的列名必须是主表中的候选键——主键或已建立UNIQUE约束,一般推荐用主键。