什么是约束
约束(constraint),在创建表的时候,我们可以给表中字段加一些约束,来保证表中数据的完整性,可靠性。
约束的分类
- 非空约束(not null)
- 唯一性约束(unique)
- 主键约束(primary key)
- 外键约束(foregin key)
- 检查约束(check)(mysql不支持)
非空约束
非空约束的字段不能为NULL
比如注册账号时,如果不输入账号就不能进行下一步,此时账号就是非空约束字段。
drop table if exists vip;
creat table vip(id int,name varchar(255) not null);
insert into vip(id,name) values(1,'zhangsan');
insert into vip(id,name) values(2,'lisi');
唯一性约束
唯一性约束字段不能重复
比如游戏中用户名只能为一个,用户名就是唯一性约束字段。
注意,唯一性约束下字段可以出现多个NULL
//单一字段约束
drop table if exists vip;
creat table vip(id int,name varchar(255) unique,email varchar(255) unique);
insert into vip(id,name) values(1,'zhangsan','123@qq.com');
insert into vip(id,name) values(2,'lisi','123@163.com');
//insert into vip(id,name) values(3,'lisi','456@qq.com');错误
//多字段联合约束(表级约束)
drop table if exists vip;
creat table vip(id int,name varchar(255),email varchar(255), unique(name,email));
insert into vip(id,name) values(1,'zhangsan','123@qq.com');
insert into vip(id,name) values(2,'lisi','123@163.com');
insert into vip(id,name) values(3,'lisi','456@qq.com');
//不同约束联合,
drop table if exists vip;
creat table vip(id int,name varchar(255) unique not null);
insert into vip(id,name) values(1,'zhangsan');
insert into vip(id,name) values(2,'lisi');
//此时name的属性被默认为主键约束(只有mysql有这特点)
//当一个字段同时为非空和唯一约束,会被修饰为主键
主键约束
主键字段中每一个值都叫做主键值。
主键值是每一行记录的唯一标识。
当几条记录相同时,通过主键值来区分(类似于身份证号)。
任何一张表都要有主键,否则表为无效状态
//单一主键
drop table if exists vip;
creat table vip(id int primary key,name varchar(255),email varchar(255));
insert into vip(id,name) values(1,'zhangsan','123@qq.com');
insert into vip(id,name) values(2,'lisi','123@163.com');
insert into vip(id,name) values(3,'lisi','123@163.com');//正确
//insert into vip(id,name) values(3,'wangwu','789@qq.com');错误
//复合主键(一般不使用)
drop table if exists vip;
creat table vip(id int,name varchar(255),email varchar(255), primary key(id,name));
insert into vip(id,name) values(1,'zhangsan','123@qq.com');
insert into vip(id,name) values(1,'lisi','123@qq.com');//正确
insert into vip(id,name) values(2,'lisi','123@163.com');
//insert into vip(id,name) values(2,'lisi','456@qq.com');错误
drop table if exists vip;
creat table vip(id int primary key,name varchar(255) primary key,email varchar(255));
//错误,主键只能有一个
//上面情况是一个联合主键,与这个不同
主键根据字段不同还可以分为自然主键和业务主键
自然主键为自然数,与业务关系不大
业务主键为业务数据中的某一种
企业中用自然主键多,因为业务变动可能导致主键重复等问题
drop table if exists vip;
creat table vip(id int primary key auto_increment,name varchar(255));
insert into vip(name) values('zhangsan');
insert into vip(name) values('lisi');
insert into vip(name) values('lisi');
//mysql对主键进行自增操作
外键约束
现在有个岗位调查数据库设计,有姓名和公司等字段
id | 姓名 | 公司 |
---|---|---|
1 | zhangsan | 深圳市腾讯计算机系统有限公司 |
2 | lisi | 深圳市腾讯计算机系统有限公司 |
3 | wangwu | 北京市字节跳动有限公司 |
4 | zhaoliu | 北京市字节跳动有限公司 |
5 | trump | 深圳市腾讯计算机系统有限公司 |
6 | Biden | 北京市字节跳动有限公司 |
按照上面这样设计会使得表存在大量冗余信息
公司编号 | 公司 |
---|---|
100 | 深圳市腾讯计算机系统有限公司 |
101 | 北京市字节跳动有限公司 |
id | 姓名 | 公司编号 |
---|---|---|
1 | zhangsan | 100 |
2 | lisi | 100 |
3 | wangwu | 101 |
4 | zhaoliu | 101 |
5 | trump | 100 |
6 | Biden | 101 |
- 这样分开设计可以减少每个表的消耗,
- 但是存在问题,可能输入的公司编号是错误的,
- 这时应该考虑用外键约束来防止错误输入 。
- 区分父表和子表跟区分C++父类子类相同,即包含其他表的信息时这个表就为子表,被包含就是父表。
- 创建和删除的过程也类似,创建时先创建父表,删除时先删除子表
drop table if exists company;
drop table if exists employee;
creat table company(companyid int primary key ,cname varchar(255));
creat table employee(id int primary key auto_increment ,name varchar(255),cid int,
foreign key(cid) references company(companyid));
//员工的cid受公司companyid的约束,只能使用companyid中的值
insert into company(companyid,cname) values(100,'**腾讯**');
insert into company(companyid,cname) values(101,'**字节**');
insert into employee(name,cid) values('zhangsan',100);
insert into employee(name,cid) values('lisi',100);
...
- 被外键约束的字段不一定是主键,但该字段必须要有唯一性,即unique修饰
- 外键可以为NULL
检查约束
详解见oracle