数据库约束
- 1. NULL约束
- 2. UNIQUE:唯一约束
- 3. DEFAULT:默认值约束
- 4. PRIMARY KEY:主键约束
- 5. FOREIGN KEY:外键约束
- 6. CHECK约束
数据库约束是关系型数据库的一个重要功能,主要作用是保证数据的正确性,也就是数据本身是否正确,关联关系是否正确。如果人工去检查数据完整性,工作量是非常大的。我们可以通过在数据库中定义一些约束,那么数据库在写入数据时,数据库就会帮我们做校验工作
1. NULL约束
- NOT NULL:指定某一列不能存储NULL值
在默认情况下,某一列是可以写入NULL的
如果要把某一列规定为一个必填项,就可以使用NOT NULL来约束
当我们写入一条id为NULL的数据时,会报错,提示不能写入NULL值,相当于数据库帮我们做了一次校验
2. UNIQUE:唯一约束
- UNIQUE:保证某列的值在整个表中不能重复出现,比如:省份证号,学号
不加唯一约束的时候,可能出现编号相同,但是人名不同的情况,这是不符合逻辑的。我们可以在创表的时候,在id字段后添加上唯一约束,加以限制
第二次插入同样的id字段时,就会报错,因为id字段加了唯一约束
注: NULL可以重复插入
3. DEFAULT:默认值约束
- DEFAULT:规定没有给列赋值时的默认值
在默认情况下,字段的默认值都是NULL,我们也可以在创建表时去自定义默认值
比如:我们可以定义name列的默认值为‘无名氏’
当我们插入数据时只指定id字段,而不指定name字段时,name列就会使用默认值去填充
虽然指定了默认约束,但是当我们手动指定name列的值为NULL时,插入的值依然是NULL,因为这个NULL是我们自己手动指定的,用户指定的优先级要高于默认约束
4. PRIMARY KEY:主键约束
- PRIMARY KEY:NOT NULL 和 UNIQUE 的结合,即主键约束的列既是非空的也是唯一的,确保某列(或两列多个列的结合)有唯一标识,有助于更容易更快速找到表中的一个特定记录
为id列指定了非空和唯一约束,id列被标识为了一个PRI,表示它是一个主键。当然,也可以简写成下面的形式,更简洁
写入数据时,两个约束同时生效
主键约束帮我们校验了非空和唯一,这两个校验在写入数据时对效率时有一定的影响的,但是比起不做校验来说,这个校验消耗还是可以承担的,而且主键对于索引起到了非常重要的作用,因此强烈建议为每一张表都定义一个主键
另外,一个表中是不允许有两个主键的
但是,一个主键可以同时包含多个列,也就是复合主键
在唯一校验时,只有复合主键中的所有列都相同时,才会被判定为相同
- **auto_increment: ** 自增类型,表示在当前表中上一条的记录上加1既可以
这个扩展可以让数据库帮我们去维护主键的增长,不用程序员自己去计算了,在插入的时候,先找到最大值,然后在这个基础上加1,生成一个新的值,作为新一个数据行主键的值
当设置了自增主键之后,发现写入NULL时,也可以成功插入数据,这里并不是说把这个NULL写入了数据库,而是说让数据库帮我们去处理这个列的值(自增操作)
当指定列插入时,也会自动生成ID,作为数据行的主键
当然,我们也可以去指定一个主键值,只要主键值不重复即可
现在,我们再尝试不指定id列,去插入一条新的数据行
我们发现,自增是在最大值的基础上加1,因此,主键值在数据表中可能是不连续的
5. FOREIGN KEY:外键约束
- FOREIGN KEY:保证一个表中的数据匹配另一个表的值的参照完整性
表中外键对应的列的值,必须是另一张表中主键列的值,或是唯一约束列,也就是当前表中的值在另一张表中必须存在,且满足主键或唯一约束
我们先试着不使用外键,去创建这两张表
当我们去写入一条新的学生记录时,设置了不存在的班级编号,数据行依然可以写入成功
这是不符合要求的,因为class表中并不存在这个班级。为了使student表里的class_id字段与class表中的id字段建立关联关系,可以对student表里的class_id列使用外键约束
语法:foreign key (字段名) reference 主表(列)
这时,去插入合理的数据是可以成功的
如果去插入不合理的数据,就会报错
另外,如果这时去插入正确的数据行,会发现id是3,而不是2。这是因为虽然上一条记录未能插入成功,id字段已经自增了,因此再次去插入数据行,id是2 + 1
综上所述,我们可以通过外键约束,保证数据的完整性和关系的正确性
当子表中存在对主表的依赖时,能否去删除主表中想应的记录?答案是否定的,如果这样去删除,会报一个主外键关系的错误
如果要删除主表中的记录,子表中不能有对该条记录的依赖,也就意味着要先删除子表中的记录,再去删除主表中的记录
6. CHECK约束
- CHECK:保证列中的值符合指定的条件。对于MySQL数据库,使用时不报错,就忽略这条约束
CHECK约束在MySQL8.0中是生效的,而在MySQL5.7中是不生效的