目录

数据库约束

数据库约束

数据库约束是关系型数据库的一个重要功能,主要作用是保证数据的正确性,也就是数据本身是否正确,关联关系是否正确。如果人工去检查数据完整性,工作量是非常大的。我们可以通过在数据库中定义一些约束,那么数据库在写入数据时,数据库就会帮我们做校验工作

1. NULL约束

  • NOT NULL:指定某一列不能存储NULL值

在默认情况下,某一列是可以写入NULL的

https://i-blog.csdnimg.cn/direct/ea3656088f6b489da7a01b071bec6fe0.png

如果要把某一列规定为一个必填项,就可以使用NOT NULL来约束

https://i-blog.csdnimg.cn/direct/1e59bd19aa7c4e769f568f810b882782.png

当我们写入一条id为NULL的数据时,会报错,提示不能写入NULL值,相当于数据库帮我们做了一次校验

https://i-blog.csdnimg.cn/direct/7a7df9a82d224fdca746b0ac9ab301ad.png

2. UNIQUE:唯一约束

  • UNIQUE:保证某列的值在整个表中不能重复出现,比如:省份证号,学号

https://i-blog.csdnimg.cn/direct/b058710773574b98ab8a0bc678266911.png

不加唯一约束的时候,可能出现编号相同,但是人名不同的情况,这是不符合逻辑的。我们可以在创表的时候,在id字段后添加上唯一约束,加以限制

https://i-blog.csdnimg.cn/direct/32106316584c4e84b59ca1e251812db0.png


https://i-blog.csdnimg.cn/direct/70cc42785e7148ffaeb547a1ed0b4dcc.png

第二次插入同样的id字段时,就会报错,因为id字段加了唯一约束

注: NULL可以重复插入

3. DEFAULT:默认值约束

  • DEFAULT:规定没有给列赋值时的默认值

在默认情况下,字段的默认值都是NULL,我们也可以在创建表时去自定义默认值

https://i-blog.csdnimg.cn/direct/bde3b822c40a42239227bea6ed77ea95.png


比如:我们可以定义name列的默认值为‘无名氏’

https://i-blog.csdnimg.cn/direct/3748042a355c4b2799212a59fda1067f.png


当我们插入数据时只指定id字段,而不指定name字段时,name列就会使用默认值去填充

https://i-blog.csdnimg.cn/direct/93c0898bfc214454bf6b370f84053eee.png


虽然指定了默认约束,但是 当我们手动指定name列的值为NULL时,插入的值依然是NULL ,因为这个NULL是我们自己手动指定的,用户指定的优先级要高于默认约束

https://i-blog.csdnimg.cn/direct/1c04a145d7b5473c8caa48b380d5d79c.png

4. PRIMARY KEY:主键约束

  • PRIMARY KEY:NOT NULL 和 UNIQUE 的结合,即主键约束的列既是非空的也是唯一的,确保某列(或两列多个列的结合)有唯一标识,有助于更容易更快速找到表中的一个特定记录

https://i-blog.csdnimg.cn/direct/7a457d70c5e0459ba8de1b9ecb9854cc.png


为id列指定了非空和唯一约束,id列被标识为了一个PRI,表示它是一个主键。当然,也可以简写成下面的形式,更简洁

https://i-blog.csdnimg.cn/direct/2ef6a61cd2684372a8e97e373b8a629a.png


写入数据时,两个约束同时生效

https://i-blog.csdnimg.cn/direct/102a3fbd47314165af9095d1c68794bf.png

主键约束帮我们校验了非空和唯一,这两个校验在写入数据时对效率时有一定的影响的,但是比起不做校验来说,这个校验消耗还是可以承担的,而且主键对于索引起到了非常重要的作用,因此强烈建议为每一张表都定义一个主键


另外, 一个表中是不允许有两个主键的

https://i-blog.csdnimg.cn/direct/5c9ed21a57044a868294a79798f4b3d9.png


但是, 一个主键可以同时包含多个列 ,也就是 复合主键

https://i-blog.csdnimg.cn/direct/231e4213f12c40d489d618dbb7a99a4d.png


在唯一校验时,只有复合主键中的所有列都相同时,才会被判定为相同

https://i-blog.csdnimg.cn/direct/eb58f3808591497b91e2546e43e71406.png


  • **auto_increment: ** 自增类型,表示在当前表中上一条的记录上加1既可以

    https://i-blog.csdnimg.cn/direct/534a5fee8c1b4cb294a0204c41c1a2a2.png

    这个扩展可以让数据库帮我们去维护主键的增长,不用程序员自己去计算了,在插入的时候,先找到最大值,然后在这个基础上加1,生成一个新的值,作为新一个数据行主键的值

当设置了自增主键之后,发现写入NULL时,也可以成功插入数据,这里并不是说把这个NULL写入了数据库,而是说让数据库帮我们去处理这个列的值(自增操作)

https://i-blog.csdnimg.cn/direct/dbfa6b4fb0954562982d8153003a3728.png


当指定列插入时,也会自动生成ID,作为数据行的主键

https://i-blog.csdnimg.cn/direct/14f88d723f5147258d7da0894d292526.png


当然,我们也可以去指定一个主键值,只要主键值不重复即可

https://i-blog.csdnimg.cn/direct/29153f3da43a45669d7240f1cbaec6ae.png


现在,我们再尝试不指定id列,去插入一条新的数据行

https://i-blog.csdnimg.cn/direct/05139df555da46c5bf132d8f74320a70.png

我们发现,自增是在最大值的基础上加1,因此,主键值在数据表中可能是不连续的

5. FOREIGN KEY:外键约束

  • FOREIGN KEY:保证一个表中的数据匹配另一个表的值的参照完整性

    https://i-blog.csdnimg.cn/direct/cf4eea942cca4329854f58a3977cbda0.png

    表中外键对应的列的值,必须是另一张表中主键列的值,或是唯一约束列,也就是当前表中的值在另一张表中必须存在,且满足主键或唯一约束


我们先试着不使用外键,去创建这两张表

https://i-blog.csdnimg.cn/direct/0b1f5d9d92e844c3af6944f21da582b8.png


当我们去写入一条新的学生记录时,设置了不存在的班级编号,数据行依然可以写入成功

https://i-blog.csdnimg.cn/direct/3f4e0dcdf6e040e6ac5a4457150582fd.png

这是不符合要求的,因为class表中并不存在这个班级。为了使student表里的class_id字段与class表中的id字段建立关联关系,可以对student表里的class_id列使用外键约束


语法: foreign key (字段名) reference 主表(列)

https://i-blog.csdnimg.cn/direct/9d50da0373bf41388a13ab374e50b0ac.png

https://i-blog.csdnimg.cn/direct/aa655baa06f14561ba6331e122fdd472.png


这时,去插入合理的数据是可以成功的

https://i-blog.csdnimg.cn/direct/58fdd06315b54f629f7584f2ec90d723.png


如果去插入不合理的数据,就会报错

https://i-blog.csdnimg.cn/direct/eb4395a47e394064867b74fe12f4bc01.png


另外,如果这时去插入正确的数据行,会发现id是3,而不是2。这是因为虽然上一条记录未能插入成功,id字段已经自增了,因此再次去插入数据行,id是2 + 1

https://i-blog.csdnimg.cn/direct/1f2c9b38a267431981e01d6e1a047155.png


综上所述,我们可以通过外键约束,保证数据的完整性和关系的正确性


https://i-blog.csdnimg.cn/direct/bce03c5c9f4141ed9e0c5e0d8b6c05d0.png

当子表中存在对主表的依赖时,能否去删除主表中想应的记录?答案是否定的,如果这样去删除,会报一个主外键关系的错误

https://i-blog.csdnimg.cn/direct/c8591918b3494a5fac0724a456aafd2b.png


如果要删除主表中的记录,子表中不能有对该条记录的依赖,也就意味着要先删除子表中的记录,再去删除主表中的记录

https://i-blog.csdnimg.cn/direct/f579ccecf77f4b1492499ff737f1b894.png

6. CHECK约束

  • CHECK:保证列中的值符合指定的条件。对于MySQL数据库,使用时不报错,就忽略这条约束

CHECK约束在MySQL8.0中是生效的,而在MySQL5.7中是不生效的

https://i-blog.csdnimg.cn/direct/11ec7b6835074fe1b9ce165bfa0ca02d.png

https://i-blog.csdnimg.cn/direct/edfea359c3794be294b1e98db33af366.png