在开始以前,笔者介绍一下笔者使用的数据库版本为5.7。全部的关系型数据库都支持对数据表使用约束,经过约束能够更好的保证数据表里数据的完整性。约束是在表上强制执行的数据校验,约束主要用于保证数据库里数据的完整性。除此以外,当表中的数据存在相互依赖性时,能够保护相关的数据不被删除。java
大部分数据库支持以下5种完整性约束。数据库
虽然大部分数据库都支持上面5种约束,但MySQL不支持CHECK约束,虽然MySQL的SQL语句也可使用CHECK约束,但这个约束不会有任何做用。大部分约束均可以采用列级约束或者表级约束语法。spa
在MySQL的information_schema数据库里的table_constraints表来保存该数据库实例中全部的约束信息,用户能够经过查询table_constraints表来获取该数据库的约束信息。code
非空约束用于确保指定列不容许为空,非空约束是比较特殊的约束,它只能做为列级约束来使用,只能使用列级约束语法来定义。这里要介绍一下SQL中的null值,SQL中的null值不区分大小写。orm
create table hehe( #创建了非空约束,这意味着hehe_id不能为null hehe_id int not null, #MySQL的非空约束不能够指定名字 hehe_name varchar(255) not null default 'xyz', #下面列能够为空,默认为空 hehe_gender varchar(2) null );
除此以外,也能够在使用alter table修改表时增长和删除非空约束,SQL命令以下:blog
#增长非空约束 alter table hehe modify hehe_gender varchar(2) not null #取消非空约束 alter table hehe modify hehe_name varchar(2) null #取消非空约束,而且指定默认值 alter table hehe modify hehe_name varchar(225) default 'abc' null
惟一约束用于保证指定列或指定列组合不容许为出现重复值。虽然惟一约束的列不能够出现重复值,但能够出现多个null值(由于在数据库中null不等于null)。索引
同一个表内能够建立多个惟一约束,惟一约束也能够由多个列组合而成。ci
#建表时建立惟一约束,使用列级约束语法建立约束 create table unique_test( #创建了非空约束,这意味着test_id不能为null test_id int not null, #unique就是惟一约束,使用列级约束语法自动建立惟一约束 test_name varchar(255) unique );
若是想为多列组合创建惟一索引,或者想自行指定约束名称,则须要使用表级约束语法。表级约束的语法为:rem
[constraint 约束名] 约束定义
表级约束的语法格式既能够放到create table语句中,也能够放到alter table 语句中用add关键字来添加。io
#建表时建立惟一约束,使用表级约束语法创建约束 create table unique_test2( #创建了非空约束,这意味着test_id不能够为null test_id int not null, test_name varchar(255), test_pass varchar(255), #使用表级约束创建惟一约束 unique(test_name), #使用表级约束语法创建惟一约束,并且指定约束名 constraint test2_uk unique(test_pass) );
上面的建表语句为test_name,test_pass分别创建了惟一索引,这意味着这两列都不能出现重复值。除此以外,还能够为这两列组合创建惟一索引。
#建表时建立惟一索引,使用表级约束语法创建索引 create table unique_test3( #创建了非空约束,这意味着test_id不能够为null test_id int not null, test_name varchar(255), test_pass varchar(255), #使用表级约束语法创建惟一约束,指定两列组合不容许为重复 constraint test3_uk unique(test_name,test_pass) );
也能够在修改表结构的时候使用add关键字来增长惟一索引,
#增长惟一约束 alter table unique_test3 add unique(test_name,test_pass);
还能够在修改表时,指定modify关键字
#为unique test3表的test_name列增长惟一约束 alter table unique_test3 modify test_name varchar(255) unique;
主键约束至关于非空约束和惟一约束,即主键约束的即不运行出现重复值,也不运行出现null值。主键的列值用于惟一标识表中的一条记录。
每一个表中最多容许有一个主键,但这个主键约束能够由多个数据列组合而成,主键是表中能惟一肯定一行记录的字段或是字段组合。
注:MySQl运行在创建主键约束时为该约束命名,但这个名字没有任何做用,这是为了保持与标准的SQL的兼容性。但部分数据库都容许自行指定主键的名字,可是MySQL无论用户为主键约束命名,它老是把全部的主键约束命名为PRIMARY。
不少数据库对组件列都支持一种自增加的特性,若是某个数据列的类型是整型,并且该列做为主键列,则可指定该列为具备自增加功能。指定自增加功能一般用于逻辑主键列,该列没有任何物理意义,仅仅为了标识每一行。MySQl使用auto_increment来设置自增加。
create table primary_test4( #创建主键列,使用自增加 test_id int auto_increment primary key, test_name varchar(255), test_pass varchar(255) );
外键约束主要用于保证一个或两个数据表之间的参照完整性,外键是构建一个表的两个字段或是两个表的两个字段之间的参照关系。外键确保了相关的两个字段的参照关系:子(从)表外键列的值必须在主表被参照列的值范围以内,或者为空(也能够经过非空约束来约束外键列不容许为空)。
当主表记录被从表记录参照时,主表记录不容许被删除,必需先把从表里参照该记录的全部记录都删除后,才能够删除主表的该记录。还有一种方式,删除主表记录时级联删除从表中全部参照该记录的全部记录。
从表外键参照的只能是主表主键列或者惟一键列,这样才能够保证从表记录能够准肯定位到被参照的主表记录。同一个表内能够拥有多个外键。
创建外键约束时,MySQL也会该列创建索引。
外键约束一般用于定义两个实体之间的一对多,一对一的关联关系。对于一对多的关联关系,一般在多的一端增长外键列,列如老师-学生(假设一个老师对应多个学生,但每一个学生只有一个老师,这是典型的一对多的关联关系)。为了创建他们之间的关联关系,能够在学生表中增长一个外键列,该列中保存此条学生记录对应老师的主键。对于一对一的关联关系,则能够选择任意一方来增长外键列,增长外键列的表被称为从表,只要为外键列增长惟一约束就能够表示一对一的关系了。对于多对多的关联关系,则须要额外增长一个链接表来记录他们之间的关联关系。
创建外键约束一样能够采用列级约束语法和表级约束语法。若是仅对单独的数据列创建外键约束,则可使用列级约束语法便可:若是须要对多列组合建立外键约束,或者须要为外键约束指定名字,则必须采用表级约束。
#为了保证从表参照的主表存在,一般应该先创建主表 create table teacher_table{ #auto_increment:表明数据库的自动编号策略,一般用作数据表的逻辑主键 teacher_id int auto_increment, teacher_name varchar(255), primary key(teacher_id) } create table student_table{ #为本表创建主键约束 student_id int auto_increment primary key, student_name varchar(255), #指定java_teacher 参照到 teacher_table的teacher_id列 java_teacher int references teacher_table(teacher_id) }
值得提出,虽然MySQL支持使用列级约束语法来创建外键约束,但这种约束语法创建的外键约束不会生效,MySQL提供这种约束语法仅仅是为了和标准的SQL保持兼容。所以在MySQl要使用外键约束,应该使用表级约束。
#为了保证从表参照的主表存在,一般应该先创建主表 create table teacher_table{ #auto_increment:表明数据库的自动编号策略,一般用作数据表的逻辑主键 teacher_id int auto_increment, teacher_name varchar(255), primary key(teacher_id) } create table student_table{ #为本表创建主键约束 student_id int auto_increment primary key, student_name varchar(255), #指定java_teacher 参照到 teacher_table的teacher_id列 java_teacher int, foreign key(java_teacher) references teacher_table(teacher_id) }
若是使用表级约束语法,则须要使用foreign key 来指定本表的外键列,并使用references来指定参照那个主表,以及参照到主表的那个数据列。使用表级约束语法能够为外键约束指定约束名,若是建立外键约束时没有指定约束名称,则MySQL会为该外键约束命名为table_name_ibfk_n,其中table_name是从表的表名,而n是从1开始的整数。
若是须要显式指定外键约束的名称,则应该使用constraint来指定名字。
#为了保证从表参照的主表存在,一般应该先创建主表 create table teacher_table{ #auto_increment:表明数据库的自动编号策略,一般用作数据表的逻辑主键 teacher_id int auto_increment, teacher_name varchar(255), primary key(teacher_id) } create table student_table{ #为本表创建主键约束 student_id int auto_increment primary key, student_name varchar(255), #指定java_teacher 参照到 teacher_table的teacher_id列 java_teacher int, constraint student_teacher_fk foreign key(java_teacher) references teacher_table(teacher_id) }
若是须要创建多列组合的外键约束,则必须使用表级约束的语法
#为了保证从表参照的主表存在,一般应该先创建主表 create table teacher_table2{ teacher_name varchar(255), teacher_pass varchar(255) primary key(teacher_name,teacher_pass) } create table student_table2{ #为本表创建主键约束 student_id int auto_increment primary key, student_name varchar(255), java_teacher_name varchar(255), java_teacher_pass varchar(255), #使用表级约束语法,创建外键约束 foreign key(java_teacher_name,java_teacher_pass) references teacher_table2(teacher_name,teacher_pass); }
删除外键约束的语法也很是简单,在alter table后增长“drop foreign key 约束名”便可。
alter table student_table2 drop foreign key student_teacher_ibfk_1;
增长外键约束,一般使用add foreign key命令。
alter table student_table2 add foreign key(java_teacher_name,java_teacher_pass) references teacher_table2(teacher_name,teacher_pass);
值得提出的是,外加约束不只能够参照其余表,并且还能够参照自身,这个参照自身的状况一般被称为自关联。列如,使用一个表保存某个公司的全部的员工,员工之间有部门经理和普通员工之分,部门经理和普通员工之间存在一对多的关联关系,但他们都是保存在同一个数据表里的记录,这就是典型的自关联。
#使用表级约束语法创建外约束键,参照自身 create table foreign_test( foreign_id int auto_increment primary key, foreign_name varchar(255), refer_id int, foreign key(refer_id) references foreign_test(foreign_id) );
若是想定义删除主表记录时,从表记录也会随之删除,则须要在创建外键约束后添加on delete cascade或添加 on delete set null,第一种删除主表记录时,把参照该主表记录的从表记录所有级联删除;第二种是指定当删除主键记录时,把参照该主表记录的的外键都设为null。
#为了保证从表参照的主表存在,一般应该先创建主表 create table teacher_table3{ teacher_name varchar(255), teacher_pass varchar(255) primary key(teacher_name,teacher_pass) } create table student_table3{ #为本表创建主键约束 student_id int auto_increment primary key, student_name varchar(255), java_teacher_name varchar(255), java_teacher_pass varchar(255), #使用表级约束语法,创建外键约束 foreign key(java_teacher_name,java_teacher_pass) references teacher_table3(teacher_name,teacher_pass) on delete cascade; #也可使用on delete set null }
当前版本的MySQL支持建表时指定CHECK约束,但这个CHEKC约束不会起任何做用。创建CHECK约束的语法很是简单,只要在建表列定之后添加check(逻辑表达式)便可。
create table check_test( emp_id int primary key auto_increment, emp_name varchar(255), emp_salary decimal, check(emp_salary>0) );
而后使用以下的命令:
insert into check_test(emp_name,emp_salary) values('jame',10); insert into check_test(emp_name,emp_salary) values('jame',-10);
会发现这两条数据均可以成功插入。
到这里MySQL的约束就介绍完了,MySQL做为一开源、免费的的数据库系统,对有些功能的支持确实不太好。若是但愿MySQL建立有CHECK约束的表或是具备跟复杂约束的表,能够借助MySQL的触发机制来实现。