9.4 CHECK约束 9.4.1 理解CHECK约束 主键、替代键和外键都是常见的完整性约束的例子。但是,每个数据库都还有一些专用的完整性约束。 例如,score表中score字段的数值要在0~100之间,students表中出生日期必须大于1990年1月1日。这样的规则可以使用CHECK完整性约束来指定。 CHECK完整性约束在创建表的时候定义。可以定义为列完整性约束,也可以定义为表完整性约束。 语法格式如下。 CHECK(expr) ?说明 expr是一个表达式,指定需要检查的条件,在更新表数据的时候,MySQL会检查更新后的数据行是否满足CHECK的条件。 9.4.2 创建CHECK约束 【任务9.10】 在TEST为库中,创建表employees3,包含学号、性别和出生日期,出生日期必须大于1980年1月1日,性别只能是“男”和“女”。 mysql> create table employees3 学号CHAR(5) not null primary key, 性别CHAR(2) DEFAULT '男', 出生日期DATE not null , CHECK (性别='男' OR性别='女'), CHECK(出生日期>'1980-1-1') 也可以作为列的完整性约束,SQL语句如下。 mysql> create table employees3 学号CHAR(5) not null primary key, 性别CHAR(2) DEFAULT ‘男’ CHECK (性别=’男’ OR性别=’女’), 出生日期DATE not null CHECK(出生日期>’1980-1-1’) 然而,到目前为止,MySQL所有的存储引擎均能够对CHECK子句进行分析,但是忽略CHECK子句,即CHECK约束还不起作用。 【项目实践】 在YSGL数据库中,进行如下操作。 (1)通过修改表的方式创建外键,使Employees表的D_ID参照Departments表的D_ID级联更新、级联删除。 (2)通过修改表的方式创建外键,使salary表的E_ID参照Employees表的E_ID,级联更新、级联删除。 (3)用ALTER语句修改表,将Departments表的D_name字段设置为UNIQUE约束。 (4)修改Employees表,将性别的数据类型改为ENUM,取值必须为“男”或“女”,性别默认为“男”。 (5)修改SALARY表,使用CHECK完整性约束,使基本工资取值在3000~4500之间。 或者,可以作为列的完整性约束直接在字段后面设置唯一性。 mysql> create table employees employeeid char(6) not null UNIQUE, name char(10) not null primary key, sex tinyint(1), education char(4) 9.2.3 修改UNIQUE约束 【任务9.6】 设置course表的c_no为UNIQUE约束。 Mysql>ALTER TABLE course ADD UNIQUE (c_name); 分析与讨论 (1)尝试向course表中输入同名的课程,会出现什么情况?为什么? (2)一个数据表只能创建一个主键。但一个表可以有若干个UNIQUE键,并且它们甚至是可以重合的。 (3)主键字段的值不允许为NULL,而UNIQUE字段的值可取NULL,但是必须使用NULL或NOT NULL声明。 (4)一般在创建PRIMARY KEY约束时,系统会自动产生PRIMARY KEY索引。创建UNIQUE约束时,系统自动产生UNIQUE索引。 在PHPMyAdmin下分别打开score1和employees表结构,分别在界面的左下方可以很清楚地看到score1和employees的索引情况。如图9.1和图9.2所示。 图9.1 score1的主键索引 图9.2 employees表的索引 9.3 FOREIGN KEY参照完整性约束 9.3.1 理解参照完整性 在关系型数据库中,有很多规则是和表之间的关系有关的,表与表之间往往存在一种“父子”关系。 例如,字段s_no是一个表A的属性,且依赖于表B的主键。那么,称表B为父表,表A为子表。通常将s_no设为表A的外键,参照表B的主键字段,通过s_no字段将父表B和子表A建