约束 CONSTRAINT

时间:2021-07-27 23:32:41

约束用于限制加入表中数据的类型

约束的种类:

非空约束(NOT NULL):约束列不接受NULL值,强制字段始终包含值。

唯一约束(UNIQUE):约束一列或一组列中的数据是唯一的。表中可以有多个唯一约束。

主键约束(PRIMARY KEY):约束一列或一组列中的数据是唯一的,且不能改动,一个表中只能有一个主键约束。

外键约束(FOREIGN KEY):外键是表中的一列,其值必须列在另一个表的主键中。只有InnoDB支持。

默认值约束(DEFAULT):约束向列提供默认值。

检查约束(CHECK):用于保证一列或一组列中的数据满足一组指定的条件。用于约束列中值的合法取值范围。MySQL不支持该约束。


非空约束 NOT NULL

默认情况下列值是可以接受NULL值得。

创建表示添加非空约束:在类的类型后面添加NOT NULL

create table 表名 (
列1 数据类型 not null,
列2 数据类型 not null
);

修改表添加非空约束

alter table 表名 add 列名 数据类型 not null;
--
alter table 表名 modify 列名 数据类型 not null;

删除非空约束

alter table 表名 modify 列名 数据类型 null;

唯一约束 UNIQUE

唯一约束与主键约束的区别

--表中可以包含多个唯一约束但只能包含一个主键

--唯一约束列可以包含NULL值,但主键不可以

--唯一约束列可以修改或更新,但是主键不可以

--唯一约束列的值可删除后重复使用,但是主键不可以

--唯一约束列不可以用来定义外键

创建表示使用UNIQUE(列名) 指定唯一约束,有以下4方式

create table 表名(
列名 数据类型,
列名 数据类型 unique,
);
--
create table 表名(
列名 数据类型,
列名 数据类型,
unique(列名,列名)
);
--
create table 表名(
列名 数据类型,
列名 数据类型
unique key 唯一索引名(列名,列名,...)
);
--
create table 表名(
列名 数据类型,
列名 数据类型,
constraint 约束名 unique(列名,列名,...)
);

向已有表中添加唯一约束

alter table 表名 add unique key 唯一索引名(列名,列名,...)
alter table 表名 add unique(列名,列名, ...)
alter table 表名 add constraint 约束名 unique(列名,列名,...)

修改表中的某列为唯一索引

alter table 表名 modify 列名 数据类型 unique;

删除表中的唯一约束

alter table 表名 drop index 唯一索引名; -- 唯一索引名可通过show create table 表名查询获得 

主键约束 PRIMARY KEY

表中任意类只要满足以下条件,都可以用于主键

--任意两行的主键都不相同

--每行都具有主键值(即列中不允许NULL值)

--包含主键的列从不修改或更新

--主键值不能重用

创建表时指定主键

create table 表名(
列名 数据类型,
列名 数据类型,
[constraint [索引名]] PRIMARY KEY(列名)
);
--
create table 表名(
列名 数据类型 PRIMARY KEY,
列名 数据类型
);

向已有表中增加主键约束

alter table 表名 add 列名 数据类型 primary key;  -- 向表中增加一列,并且将其设为主键
--
alter table 表名 add primary key(列名); --将表中已有的列变为主键
--
alter table 表名 add constraint [约束名] primary key(列名); --将表中已有的列变为主键

删除主键约束

alter table 表名 drop primary key;

外键约束 FOREIGN KEY 只有InnoDB支持外键约束

在创建表示定义外键约束

create table 主表名(
列名 数据类型,
列名 数据类型,
primary key(列名)
);
create table 附表名(
列名 数据类型,
列名 数据类型,
constraint [约束名] foreign key(列名) references 主表名(主表的primary key列名)
);

向已有表中添加外键约束

alter table 表名 add constraint [约束名] foreign key(列名) references 主表名(主表的primary key列名);

删除表中的外键约束

alter table 表名 drop foreign key 外键约束名;

默认值约束 DEFAULT

create table 表名(
列名 数据类型 default 默认值,
列名 数据类型
);

向已有表添加默认值约束或修改默认值约束

alter table 表名 modify 列名 数据类型 [default 默认值];
--
alter table 表名 alter 列名 set default 默认值;

删除默认值约束

alter table 表名 alter 列名 drop default;

检查约束 CHECK

MySQL不支持CHECK约束,解决的办法有两种:

1)如果需要设置CHECK约束的字段范围小,并且比较容易列举全部的值,可考虑将该字段的类设置为枚举类型enum()或者集合类型set()。比如性别字段、爱好字段等可以这样设置。

create table checkDemoTable(
id int auto_increment,
name varchar(45),
sex enum('男', '女'), -- 使用enum()限制取值范围,进行约束
interest set('上网', '旅游', '美食', '健身', '电影', '阅读', '音乐'), -- 使用set()限制取值范围,进行约束
primary key(id)
);
insert into checkDemoTable(name, sex, interest)
values('lily', '女', '上网, 电影, 音乐'), ('Tom', '男', '旅游, 健身, 电影');
-- 超出enum()和set()范围之外值是无法插入到表中的
-- enum()和set()的区别:
-- enum()每次只能选择一个成员;而set()可以选择一个或者多个成员但是不能重复选择同一个成员

2)如果需要CKECK约束的字段是连续型的,不易列举时,可采用触发器来实现CHECK的功能

create table test(
id int auto_increment,
num int,
primary key(id)
);
-- 使用触发器来限制插入
delimiter $$
create trigger triggerTest before insert on test for each row
begin
if new.num < 0 then
set new.num = 0;
end if;
end;
$$
delimeter ;

测试

约束 CONSTRAINT