Mysql数据库(五)约束
文章目录
- Mysql数据库(五)约束
- 1、非空约束:not null
- 2、唯一性约束:unique
- 单个字段唯一性约束
- 联合字段唯一性约束
- unique 和not null联合约束
- 3、主键约束(primary key,简称PK)
- 4、外键约束(foreign key,简称FK)
约束:constraint
在创建表时,可以对表中的字段增加一些约束,保证表中数据的完整性、有效性。
约束类型 | 单词 |
非空约束 | not null |
唯一性约束 | unique |
主键约束 | primary key(简称PK) |
外键约束 | foreign key(简称FK) |
检查约束 | check(mysql不支持,oracle支持) |
1、非空约束:not null
非空约束not null约束的字段不能为null。
drop table if exists t_vip;
create table t_vip(
id int,
name varchar(255) not null
);
insert into t_vip(id, name) values(1, 'zhangsan');
insert into t_vip(id, name) values(2, 'lisi');
#因为name有非空约束,下面语句报错。。。
#ERROR 1136 (21S01): Column count doesn't match value count at row 1
insert into t_vip(id, name) values(3);
**技巧:**可以将上述删除并创建表,注入数据的语句放入一个sql文件中,如vip.sql,在sql数据库中通过执行source F:\databases\vip.sql 语句可以自动执行文件中所有sql语句。
2、唯一性约束:unique
单个字段唯一性约束
唯一性约束unique约束的字段不能重复,但是可以为null。
约束直接添加在列的后面,叫做列级约束。
drop table if exists t_vip;
create table t_vip(
id int,
name varchar(255) unique,
email varchar(255)
);
insert into t_vip(id, name, email) values(1, 'zhangsan', 'zhangsan@123.com');
insert into t_vip(id, name, email) values(2, 'lisi', 'lisi@123.com');
insert into t_vip(id, name, email) values(3, 'wangwu', 'wangwu@123.com');
select * from t_vip;
#因为name字段加了唯一性约束,下面语句报错
#ERROR 1062 (23000): Duplicate entry 'wangwu' for key 't_vip.name'
insert into t_vip(id, name, email) values(4, 'wangwu', 'wangwu@sina.com');
#name为唯一性约束,但可以为NULL
insert into t_vip(id) values(4);
insert into t_vip(id) values(5);
得到t_vip表中数据:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CPNMmzzZ-1639407680683)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210927224204091.png)]
联合字段唯一性约束
创建表时,两个字段联合起来具有唯一性,但是单个字段可以相同。
约束没有添加在列的后面,需要给多个字段联合起来添加约束时使用表级约束。
drop table if exists t_vip;
#如下创建表即可实现name和email联合唯一性
create table t_vip(
id int,
name varchar(255),
email varchar(255),
unique(name,email)
);
#插入数据:名字相同,但是email不同,可以插入
insert into t_vip(id, name, email) values(1, 'zhangsan', 'zhangsan@123.com');
insert into t_vip(id, name, email) values(1, 'zhangsan', 'zhangsan@sina.com');
#下面重复语句,无法插入,报错
#ERROR 1062 (23000): Duplicate entry 'zhangsan-zhangsan@123.com' for key 't_vip.name'
insert into t_vip(id, name, email) values(1, 'zhangsan', 'zhangsan@123.com');
结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DxghsMiM-1639407680685)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20210927230036371.png)]
unique 和not null联合约束
drop table if exists t_vip;
create table t_vip(
id int,
name varchar(255) not null unique
);
mysql> desc t_vip;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id | int | YES | | NULL | |
| name | varchar(255) | NO | PRI | NULL | |
+-------+--------------+------+-----+---------+-------+
在mysql中,如果一个字段同时被not null和unique约束的话,该字段自动变成主键字段。(注意:oracle中不一样!)
insert into t_vip(id name) values(1, 'zhangsan');
insert into t_vip(id name) values(2, 'zhangsan'); //error:name不能重复。
insert into t_vip(id) values(1);//error:name不能为NULL。
3、主键约束(primary key,简称PK)
主键是每行记录的唯一标识。
任何一张表都应该有主键,否则表是无效的。
主键特征:not null + unique (主键不能为NULL,同时不能重复。)
可以使用auto_increment为主键自增。
//单一主键
drop table if exists t_vip;
create table t_vip(
id int primary key auto_increment,//auto_increment表示自增,从1开始,以1递增
name varchar(255)
);
insert into t_vip(id, name) values(1,'zhangsan');
insert into t_vip(id, name) values(2,'lisi');
//复合主键:id和name联合起来做主键
drop table if exists t_vip;
create table t_vip(
id int,
name varchar(255),
email varchar(255),
primary key(id,name)
);
insert into t_vip(id, name, email) values(1,'zhangsan','zhangsan@123.com');
insert into t_vip(id, name) values(2,'lisi','lisi@123.com');
实际开发中,不建议使用 复合主键,建议使用单一主键。主键值建议使用int、bigint、char等类型,不建议使用varchar来做主键。主键一般是数字,一般都是定长的。
主键分类:
自然主键:主键值是一个自然数,和业务没关系;用的多。
业务主键:主键值和业务紧密关联,例如银行卡账号做主键值。就属于业务主键。
4、外键约束(foreign key,简称FK)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ttEANR7w-1639407680685)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20211213223855741.png)]
t_class是父表,t_student是子表,先删子表再删父表。
drop table if exists t_student;
drop table if exists t_class;
create table t_class(
classno int primary key,
classname varchar(255)
);
create table t_student(
no int primary key auto_increment,
name varchar(255),
cno int,
foreign key(cno) references t_class(classno)
);
insert into t_class(classno, classname) values(100, '河南省郑州一中高三三班');
insert into t_class(classno, classname) values(101, '河南省郑州一中高三四班');
insert into t_student(name, cno) value('jack', 100);
insert into t_student(name, cno) value('luky', 100);
insert into t_student(name, cno) value('hanmeimei', 100);
insert into t_student(name, cno) value('tome', 100);
insert into t_student(name, cno) value('zhangsan', 101);
insert into t_student(name, cno) value('lisi', 101);
insert into t_student(name, cno) value('wangwu', 101);
insert into t_student(name, cno) value('zhaoliu', 101);
//error:外键的102没有在t_class表中
insert into t_student(name, cno) value('zhaoliu', 102);
- 子表中的外键引用的父表中的某个字段,这个字段不一定是父表的主键!但是必须需具有唯一性;
- 外键可以为NULL。