函数依赖:当某一列的数据必须随着另一列的数据改变而改变,表示第一列函数依赖与第二列.快速表示函数依赖的方式:T.x--->T.y,在关系表T中,y列函数依赖与x列。
部分函数依赖:非主键的列依赖于组合主键的某个部分(但不是完全依赖于组合主键)。
传递依赖:如果改变任何非主键的列可能造成其他列的改变,即为传递依赖。
传递函数依赖:任何非主键列与另一个非主键列有关联。
第一范式,或1NF:
规则一:数据列只包括具有原子性的值
规则二:没有才重复的数据组
第二范式,或2NF
规则一:符合1NF
规则二:没有部分函数依赖性。
第三范式,或3NF
规则一:符合2NF
规则二:没有传递函数依赖性。
外键约束
如果表A的主关键字是表B中的字段,则该字段称为表B的外键,表A称为主表,表B称为从表。外键是用来实现参照完整性的,不同的外键约束方式将可以使两张表紧密的结合起来,特别是修改或者删除的级联操作将使得日常的维护工作更加轻松。这里以用户表和用户组表为例,这是一个典型的多对一关系,多个用户对应于一个用户组。
首先创建用户组表:
create table t_group ( id int not null, name varchar(30), primary key (id));
插入两条记录:
insert into t_group values (1, 'Group1'),(2, 'Group2');
下面创建用户表,分别以不同的约束方式创建外键引用关系:
1、级联(cascade)方式
create table t_user ( id int not null, name varchar(30), groupid int, primary key (id), foreign key (groupid) references t_group(id) on delete cascade on update cascade);
测试
insert into t_user values (1, 'qianxin', 1);//可以插入 insert into t_user values (2, 'yiyu', 2);//可以插入 insert into t_user values (3, 'dai', 3);//错误,无法插入,用户组3不存在,与参照完整性约束不符 delete from t_group where id=2;//导致t_user中的2记录级联删除 update t_group set id=2 where id=1;//导致t_user中的1记录的groupid级联修改为2
2、置空(set null)方式
create table t_user ( id int not null, name varchar(30), groupid int, primary key (id), foreign key (groupid) references t_group(id) on delete set null on update set null);
测试:
//参照完整性测试 insert into t_user values (1, 'qianxin', 1); --可以插入 insert into t_user values (2, 'yiyu', 2); --可以插入 insert into t_user values (3, 'dai', 3); --错误,无法插入,用户组3不存在,与参照完整性约束不符 //约束方式测试 delete from t_group where id=2;//导致t_user中的2记录的groupid被设置为NULL update t_group set id=2 where id=1;//导致t_user中的1记录的groupid被设置为NULL
3、禁止(no action / restrict)方式
create table t_user ( id int not null,name varchar(30), groupid int, primary key (id), foreign key (groupid) references t_group(id) on delete no action on update no action);
测试:
insert into t_user values (1, 'qianxin', 1);//可以插入 insert into t_user values (2, 'yiyu', 2);//可以插入 insert into t_user values (3, 'dai', 3); //错误,无法插入,用户组3不存在,与参照完整性约delete from t_group where id=2; //错误,从表中有相关引用,因此主表中无法删除 update t_group set id=2 where id=1; //错误,从表中有相关引用,因此主表中无法修改
完整性约束
更新数据库时,表中不能出现不符合完整性要求的记录,以保证为用户提供正确、有效的数据。实现该目的最直接的方法,是在编写数据库应用程序时,对每个更新操作都进行完整性检查。但这种检查往往是复杂、重复、低效的。SQL把各种完整性约束作为数据库模式定义的一部分,由数据库管理系统维护,这样即可有效防止对数据库的意外破坏,提高了完整性检测的效率,又减轻了编程人员的负担。
SQL Server支持三种完整性约束:
- 实体完整性;
- 参照完整性(或引用完整性);
- 用户自定义完整性
1.实体完整性和主码
实体完整性是通过主码(PRIMARY KEY)的定义来实现的。一旦某个属性或属性组被定义为主码,该主码的每个属性就不能为空值,并且在表中不能出现主码值完全相同的两个记录。主码可以在CREATE TABLE语句中使用PRIMARY KEY定义。有两种定义主码的方法:一种是在属性后增加关键字PRIMARY KEY,另一种是在属性表中加入额外的定义主码的子句:PRIMARY KEY(主码属性名表)。如果表的主码只含有单个属性,上面的两种方法都可以使用。如果主码由多个属性组成,只能使用第二种方法。除了主码,SQL提供了类似候选码的说明方法,使用关键字UNIQUE定义(与候选码不同的是:定义为UNIQUE的属性可以定义为空值,但只能有一个记录该属性的值为NULL),说明该属性(或属性组)的值不能重复。一个表中只能有一个主码,但可以有多个“UNIQUE”定义。
3.用户自定义完整性约束
SQL提供非空约束、对属性的CHECK约束、对元组的CHECK约束、触发器等来实现用户的完整性要求。
3.1基于属性的CHECK约束(MYSQL暂时不支持check功能)
使用CHECK(检查)子句可保证属性值满足某些前提条件。CHECK子句的一般格式为:
CHECK<条件>
属性的CHECK约束既可跟在属性的定义后,也可在定义语句中另增一子句加以说明。设定StudentInfo表中age值不能小于18、大于65。只需将age属性说明为如下形式:
age int CHECK(age >= 18 and age <= 65)
3.2基于元组的约束
CREATE TABLE salary( Eno char(4), Basepay decimal(7, 2), Insure decimal(7, 2), Fund decimal(7, 2), CHECK (Insure + Fund < Basepay) );
上面例子中,CHECK约束涉及到表中多个属性,为元组约束。
3.3约束的更新
约束与数据库中的表、视图等一样,可以进行增加、删除和修改的更新操作。为了更新约束,需要在定义约束是对约束进行命名,在约束前加上关键字CONSTRAINT和该约束的名称。例如要说明StudentInfo表中的主码时,将其命名为PK_StudentInfo_ID.
CREATE TABLE StudentInfo( StudentID char(8), StudentName varchar(10), StudentSex bit, CONSTRAINT PK_StudentInfo_ID PRIMARY KEY(StudentID) );
可以使用ALTER TABLE语句来更新与属性或表有关的约束.
//删除约束: ALTER TABLE DROP CONSTRAINT 约束名 //增加约束 ALTER TABLE ADD CONSTRAINT 约束名 约束定义