什么是约束
约束(constraint)
约束是在创建表的时候我们可以给表中的字段加上一些约束来保证表中数据的完整性和有效性
非空约束
not null
非空约束约束的字段不能为NULL
drop table if exists t_user;
create table t_user(
id int,
name varchar(25) not null
);
insert into t_user(3,'zhangsan');
insert into t_user(3);//error
Filed `name` doesn't have a default value
唯一性约束
drop table if exists t_user;
create table t_user(
id int,
name varchar(25) not null,//not null 只有列级约束
email varchar(25) unique//列级约束
);
insert into t_user values(3,'zhangsan','1@qq.com');
insert into t_user values(4,'lisi','1@qq.com');//error Duplicate entry '1@qq.com' for key 't_user.email'
email虽然被unique约束了但是可以为null
insert into t_user(id,name) values(5,'han');
insert into t_user(id,name) values(6,'han');
insert into t_user(id,name) values(7,'han');
select * from t_user
需求:name和email两个字段联合起来具有唯一性
即下面是可以执行的
insert into t_user values(3,'zhangsan','1@qq.com');
insert into t_user values(4,'zhangsan','2@qq.com');
drop table if exists t_user;
create table t_user(
id int,
name varchar(25) not null,
email varchar(25) ,
unique(name,email)//表级约束
);
什么时候使用表级约束:需要给多个字段联合起来添加某一个约束的时候
在MySQL中同一个字段同时被not null和unique约束就成了主键约束
drop table if exists t_user;
create table t_user(
id int,
name varchar(25) not null unique,
email varchar(25) ,
unique(name,email)
);
desc t_user
主键约束
主键是每行记录的唯一标识
每一张表都应该有主键,没有主键,表无效
drop table if exists t_user;
create table t_user(
id int PRIMARY KEY,//使用列级约束,单一主键
name varchar(25)
//,primary key(id) 表级约束
//,primary key(id,name)复合主键
);
insert into t_user values(1,'zhangsan');
INSERT INTO t_user values(2,'lisi');
INSERT INTO t_user values(2,'wangwu');//Duplicate entry '2' for key 't_user.PRIMARY'
INSERT INTO t_user(name) values('wangwu');//Field 'id' doesn't have a default value
一个表中主键约束只能添加一个
drop table if exists t_user;
create table t_user(
id int PRIMARY KEY,
name varchar(25) PRIMARY KEY
);
//Multiple primary key defined
mysql中有一个机制帮助我们自动维护一个主键值
autoincrement
drop table if exists t_user;
create table t_user(
id int PRIMARY KEY auto_increment//auto_incremrnt 只能添加到主键上,
name varchar(25)
);
insert into t_user(name) values('nihao');
INSERT INTO t_user(name) values('nihao');
INSERT INTO t_user(name) values('nihao');
select * from t_user
外键约束
业务背景:设计两张数据库表来描述班级和学生信息
drop TABLE if exists t_student;
create table t_student(
id int primary key auto_increment,
name varchar(25),
cno int
);
drop TABLE if exists t_class;
create table t_class(
id int primary key auto_increment,
name varchar(25)
);
insert into t_student(id,name,cno)
values(1,'jack',100),(2,'lucy',100),(3,'han',101),(4,'zhangsan',101);
insert into t_class(id,name)
values(100,'三班'),(101,'八班');
select * from t_student;
select * from t_class;
但是这样存在问题如果学生表插入
insert into t_student values(5,'cxk',102);
但是没有这个班
为了防止这样的事情发生我们给t_student的cno添加外键约束让其引用t_class的id
注意t_class是父表,t_student是子表
-
删除表的顺序:先删除子表,再删除父表
-
创建表的顺序:先创建父表,再创建子表
-
删除数据顺序:先删除子表数据再删除父表
-
插入数据顺序:先插入父表数据再插入子表
这个顺序没有必要记,很容易理解,如果没有父表,子表外键引用谁?如果先删除父表,子表之前的引用 就无效了;如果先给子表插入数据,就没有它对应的父表的数据;如果删除了父表中的数据, 子表引用的父表数据也无效
drop TABLE if exists t_student;
drop TABLE if exists t_class;#先删除子表在删除父表
create table t_class(
id int primary key auto_increment,
name varchar(25)
);
create table t_student(
id int primary key auto_increment,
name varchar(25),
cno int,
FOREIGN key(cno) references t_class(id)
); #先创建父表再创建子表
insert into t_class(id,name)
values(100,'三班'),(101,'八班');
insert into t_student(id,name,cno)
values(1,'jack',100),(2,'lucy',100),(3,'han',101),(4,'zhangsan',101);
#先给父表插入数据再给子表插入数据
select * from t_student;
select * from t_class;
此时如果执行
insert into t_student(id,name,cno)
values(5,'jack',102)
就会报错
Cannot add or update a child row: a foreign key constraint fails (`test`.`t_student
`, CONSTRAINT `t_student_ibfk_1` FOREIGN KEY (`cno`) REFERENCES `t_class` (`id`))
可以保证我们插入的数据不能随便写,这就是外键约束的作用
外键引用的字段不一定是主键但至少具有唯一性
被引用的字段可以为null
insert into t_student(id,name,cno)
values(5,'jack',null)