【目标】
• 掌握约束的使⽤场景
• 掌握⾮空约束、默认约束、主键约束、唯⼀约束、外键约束、CHECK的创建
1.数据库约束
1.1 什么是数据库约束
数据库约束是指对数据库表中的数据所施加的规则或条件(其属于表结构定义,即DDL,同CREATE、DROP等属于同一层次的操作)⽤于确保数据的准确性和可靠性。这 些约束可以是基于数据类型、值范围、唯⼀性、⾮空等规则。
1.2约束类型
| 类型 | 名称 | 说明 |
|---|---|---|
| NOT NULL | 非空约束 | 指定非空约束的列不能存储 NULL 值 |
| DEFAULT | 默认约束 | 当没有给列赋值时使用的默认值 |
| UNIQUE | 唯一约束 | 指定唯一约束的列每行数据必须有唯一的值 |
| PRIMARY KEY | 主键约束 | NOT NULL 和 UNIQUE 的结合,可以指定一个列或多个列,有助于防止数据重复和提高数据的查询性能 |
| FOREIGN KEY | 外键约束 | 是一种关系约束,用于定义两个表之间的关联关系,可以确保数据的完整性和一致性 |
| CHECK | 检查约束 | 用于限制列或数据在数据库表中的值,确保数据的准确性和可靠性 |
约束语法:
字段名1 数据类型 [约束类型1]
字段名2 数据类型 [约束类型2]
......
[]表示可写可不写
2.NOT NULL约束
NOT NULL指定某列不能为NULL值,具体例子见下
结合上章所讲,id和name是可以为NULL的。我们假设一个场景,就是name为NULL没有意义。那么为了防止后续的数据插入过程中插入NULL,我们就可以限制name数据列不能填入NULL
从图上表结构可以看出,name的数据列不允许再插入NULL,接下来我们来验证:
一、正常插入:
二、非正常插入:
3.DEFAYLT约束
Default指的是默认值:
如果我们不指定默认值,那么默认值是NULL(从上图可得)
如果我们指定了默认值,那么默认值就会按照我们指定的值进行插入
需要注意的是:默认值是没有数据情况下的值,并不一定就是数据值,当我们有数据插入的时候,真实的数据值还是我们插入的值
这样,name的默认数据值就是 无名氏 ,接下来我们进行验证
一、不插入数据(会自动插入默认值)
二、插入数据(插入我们输入的数据)
4.UNIQUE约束
UNIQUE指定某列数据不能重复,具体例子见下
先说明,这个表格的key是‘键’的意思,他表示“这个字段是什么键”。这里的UNI是UNIQUE的缩写,在这里表示——唯一键,表明在id这一列不能有重复数据,演示见下。
一、正确插入
二、错误插入
这里错误的原因就是因为UNIQUE指定了id这一列的数据不能重复,而最开始我们已经成功插入了一个id为1的数据,后面再插入一个id为1的数据就会出现错误。
5.PRIMARY KEY约束
PRIMARY KEY约束是主键约束,它是NOT NULL和UNIQUE的结合,表示不能为NULL且不能有重复数据,其约束的字段称之为主键:
指定一个列时,称为单列主键(表示这一列不能为NULL,且不能有重复数据)
指定多个列时,称为复合主键(表示任意列都不能为空,且不能与已有数据完全重复)(具体的例子见下)
主键的存在是做标识。在excel中,我们把每一行的行高做为标识,分别为1、2、...。而对应到数据库中,比如下列例子中的id,我们把他作为标识。
由于 PRIMARY KEY是 UNIQUE和NOT NULL的结合 ,所以也可以这样写(了解即可):
但是需要大家明确的是,在一个表中,主键只能有一个。注意:是主键只能有一个,而不是只指定一个列的键才是主键,复合主键也是主键。具体情况见下:
一、单列主键
一个表中只能有一个主键,所以以上是错误的,但是可以这样做——复合主键:
二、复合主键
通过PRIMARY KEY(字段1,字段2,...);
上述例子中,id和name两列复合成一个复合主键,在这里的作用就是id和name两者的数据,两列数据任意一列都不能为NULL、且不能和已有数据全重复。见下:
我们先插入一行测试数据,错误示例见下:
一、不能同时和已有数据重复
但是可以这样做:
二、任意一个都不能为 NULL(注意不是不能同时为NULL,是任意一个都不能为NULL)
一、总结
对于单列主键,后进数据不能与已有数据重复、且不能为NULL
对于复合主键,后进数据不能完全和已有数据重复、且任意一列都不能为NULL
二、extra讲解
想必现在大家对这个表格,除了Extra这一列,都熟知了,这里就简单讲解一下Extra这一列啥意思:
Extra 额外的、附加的。显示的是这个字段的额外信息,比如是否自增等,常用见下:
| Extra 显示 | 含义 |
|---|---|
auto_increment | 自增 |
DEFAULT_GENERATED | 默认值由表达式生成 |
on update CURRENT_TIMESTAMP | 更新时自动更新时间 |
STORED GENERATED | 存储生成列 |
VIRTUAL GENERATED | 虚拟生成列 |
| 空 | 没有额外信息 |
举例说明:
删除原来的表,新建一个表,并且定义 id为主键自增、name不为null:
一、情况一:不定义主键
明明我们没有定义主键,可是服务器还是自动为我们加上了id,默认是从1开始
二、情况二:在主键中,定义NULL,遇到自增不报错
三、情况三:报错,但是自增值仍增加,导致插入值和预想值不一样
报错原因:指定name不为null,但是数据插入name为null,那么我们插入正确数据
但是实际上:
这是因为虽然insert into class values(null,null);没有插入,但是这里id自增值是增加了的,这时默认变成5了,而在insert into class values(null,'钱七');之后,id自增值又增加了,这时就变成了6。
这里提醒一句:当前自增值是在最大主键值(没有默认最大自增值)的基础上进行加一得到的
6.FOREIGN KEY约束
FOREIGN KEY约束是一种关系约束,用于定义两个表的关联关系
语法为:FOREIGN KEY (本表列) REFRERNCES 主表名(主表列)注意点见下:
- 外键列写的是“当前表的列”,不能带表名
- 主键列写的是“主表的列”
- 主表的主表列必须是主键或者唯一键
现在先建两个表:class(用于存放班级信息)、student(用于存放学生信息),把class当作主表
一、对于插入
分别插入数据:
这两者就是对应的,但是大家可能有一个疑问:这也没有体现主外键关系啊?那么就来给大家演示——错误数据插入:
这就没办法插入了,因为主外键对应情况下,主表class没有(5,'java5')这个班级,也就是说class没有student关联的数据。
二、对于删除
那么,在删除主表中的数据时,会发生什么呢?
不能进行删除,因为我们的从表student中还有对主表进行依赖的数据,只有我们先删除了从表中依赖的主表中要删除的数据的时候,然后才能成功删除数据。
先删除从表的依赖数据:
再删除主表的待删数据:
7.CHECK约束
CHECK约束用于限制数据库表中的值。
CHECK约束的语法:CHECK(约束条件);实例见下:
创建一个身份表:
一、插入正常数据
二、插入错误数据