外键约束(20171015)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
外键约束
先要理清几个概念:
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 :更新主表记录的主键值,子表中的匹配记录的外键值改为默认值。
参照完整性属于表间规则。
对于相关的表,在更新、插入或删除记录时,如果只改其一不改其二,就可能影响数据的完整性:例如,删除父表的某记录后,子表的相应记录未删除,致使这些记录成为孤立记录;修改父表中对应列的值后,子表对应列的值未做相应改变;对于子表插入的记录,父表中没有对应列的值的记录;更改子表的外键值,父表中没有对应列的值的记录。
外键约束的例子
先创建一个主表dept
CREATE 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 NULL
REFERENCES SalesPerson(SalesPersonID)
也可以显式使用FOREIGN KEY 子句并复述列特性。
请注意,在这两个表中列名不必相同。
FOREIGN KEY (SalesPersonID) REFERENCES SalesPerson(SalesPersonID)
多列键约束作为表约束创建。
在AdventureWorks2012 数据库中,SpecialOfferProduct 表包含多列PRIMARY KEY。
以下示例显示如何从其他表中引用此键(可选择显式约束名)。
CONSTRAINT FK_SpecialOfferProduct_SalesOrderDetail
FOREIGN 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约束,一般推荐用主键。
简单的说,被外键引用的列必须是主表中的主键或唯一约束,通常是主键。
②外键约束分为列级和表级约束。
列级约束只能包含一列。
表级约束可以包含一列或多列。
③从表(子表、参照关系、引用表、参照表Referencing table 、外键表)的外键的列数和
主表中对应的列数必须相同,对应列的数据类型也必须相同,但对应列的名称不必相同。
关系(联系relationship),在数据库中指不同表之间的数据彼此联系的方法。
可分为3类:一对一、一对多、多对多。
有表A和表B两个表,如果表A中的一条记录与表B中的一条记录相匹配,反之也是一样,那么这两个表存在一对一关系(one-to-many relationship)。
如果表A中的一条记录与表B中的多条记录相匹配,表B中的一条记录只与表A中的一条记录相匹配,则这两个表存在一对多关系(one-to-many relationship)。
如果表A中的多条记录与表B中的多条记录相对应,且表B中的多条记录也与表A中的多条记录相对应,则称表A与表B是多对多关系(many-to-many relationship)。
每种关系都有一些变体,如一对一关系,若允许一方为Null着话,可以有零或者一对一关系。
创建一对一关系两个表的公共字段都必须具有唯一索引,将一个表的公共字段设置为主键或唯一约束,将另一个表的公共字段设置外键。
公共字段(相关字段、匹配字段、对应列),其名称在两个表中一般相同,也可不同,但要求是相同或相容的数据类型。
创建一对多关系“一方”表的公共字段必须具有唯一索引。
“多方”表的公共字段不应具有唯一索引。
它可以有索引,但必须允许重复。
将“多方”表的公共字段设置外键。
多对多关系不能直接建立,需要创建第三个表,形成两个一对多关系,第三个表称为“联接表[junction table]”或“链接表[linking table]”(有时也称为“Bridge Table”,“Join Table”,“Map Table”,中间表),是一个包含两个表的公用字段的表(你可以根据实际需要决定是否包括其他字段),它是与其它两个表构成的“一对多”关系的“多方”,也就是两个主表的每一个和联接表定义了一对多关系。
假设有两个“多对多”表TA与TB,表TA的主键为a,表B的主键为b,则需要创建第三个表,将a与b放入第三个表中设置成该表的外键,建立两个一对多关系:㈠TA为主表,为“一方”,第三个表是子表,为“多方”。
㈡TB为主表,为“一方”,第三个表是子表,为“多方”。
[ 第三个表中的外键还可以设置成该表的主键]。
例如,公司有多种类型的计算机和多名技术员,每名技术员均经认证负责部分(非全部)计算机。
每名技术员与多台计算机发生关联,而每台计算机相应地与多名技术员发生关联。
若要跟踪谁负责指定的计算机,请创建多对多关系,即将关系双方的主键添加至第三个表(计算机技术人员)中,该表称为“联接表”或“链接表”。
“计算机技术人员”表(“联接表”、子表、“多方”)通过其外键“计算机ID”引用“计算机”表(主表、“一方”)。
“计算机技术人员”表(“联接表”、子表、“多方”)通过其外键“技术人员ID”引用“技术人员”表(主表、“一方”)。
学习数据库知识时,常常遇到下面这些术语,尽早了解可能更好的减少学习过程中的困惑误解。
特地归纳整理如下(每一行作为同义词使用):
[注]一些文献中的“实体”(Entity)含有集合义等同于另一些文献中的“实体集”(Entity Set),含有个体义的“实体”称为“实体实例”(Entity instance)。
实体实例(Entity instance)是实体类型的一个实例,对应于数据表中的一个记录。