MySQL数据库基础——数据库的约束
发布时间:2026/9/24 17:45:40 作者:尧图编辑部 阅读量:1,286

文章目录约束非空约束 not null唯一约束 unique默认值 default主键 primary keyprimary key主键的自增类型复合主键外键 foreign keycheck了解约束约束是关系型数据库的一个重要功能主要作用是通过加上约束的校验来保证数据的完整性也可以理解为数据的正确性数据本身是否正确数据之的关联关系是否正确人工检查数据完整性的工作量非常的大在数据表中定义一些约束那么数据库写入数据的时候数据库会帮我们做校验工作约束一般是指定在列上的对字段加上一些约束非空约束 not null作用指定某一列不可以赋值为null我们可以describe一下表结构看一下在没有非空约束时这些字段都是可以赋值为null的约束的定义语法createtablestudent(idbigintnotnull);再给id赋值时写入null就会报错唯一约束 unique作用为字段加上唯一约束保证该字段不会出现重复值createtablestudent(idbigintunique);可以看到字段id的键值Key中已经标识了UNI的唯一约束如果都是id都是null的话不算重复空值不能算是重复的默认值 default作用在一个字段没有被赋值时给上默认值createtablestudent(namevarchar(50)default无名氏);这样字段name的默认值就不再是null了而是我们指定的“无名氏”不过要是自己又手动赋值为null的也可以执行主键 primary keyprimary key作用它是 NOT NULL 和 UNIQUE 的结合所以主键约束的列既是非空的也是唯一的。确保某列或两个列多个列的结合有唯一标识有助于更准确、更快速地找到表中的一个特定的记录。分条总结唯一区分表中每条记录不会出现重复行作为其他表外键的引用目标建立表与表之间关联。MySQL会自动为主键建索引大幅加快查询速度createtablestudent(idbigintprimarykey);可以看到id的键值中标记了PRI的主键约束且null值的可否赋值是NO当然也可以使用not null和unique结合进行主键约束的定义效果是一样的createtablestudent(idbigintnotnullunique);主键约束帮我们校验了非空和唯一这两个校验在写入数据时会消耗一定的资源对效率是有一定影响的但是比起不做校验来说那这个性能消耗还是承担得起的。而且主键对索引起到了非常重要的作用所以强烈建议为每张表定义一个主键主键的自增类型createtablestudent(idbigintprimarykeyauto_increment);auto increment 的作用每次添加一条新记录时当我们并没有给这行记录中的auto increment主键字段赋值时数据库都会自动找到表中该字段的最大值然后1为该主键字段赋值当我们插入一条记录insertintostudentvalues(null,10001,张三);可以看到我们把第一个字段id的值设为null但是它是一个自增类型的主键就会出现下面的结果可以看到虽然我们插入的是null但是由于该字段是一个自增类型的主键所以数据库会自动执行自增赋值在表中原来的最大值id0的基础上1为新的id赋值一般对自增类型的主键赋值就是直接采用null为其赋值让数据库自己计算正确结果而且即使insert时不管这个自增主键也会照样自动进行自增赋值既然自增主键是自动赋值的那能不能手动赋值也是可以的只要不添加重复的值就行主键是严格非空且唯一的但是要注意一个特殊现象如果我们往一个表中insert一条数据但是由于种种原因该SQL语句报错了插入失败。但如果该表中有自增主键那么这时即使语句没有执行成功它的自增数也已经1了无法再退回去了。也就是说比如该自增主键是id插入之前的最大值为8即使插入失败该主键的自增数已经变为9了下次正常成功插入一条数据id会变为10就会出现主键值不连续的现象…7、8、10这是MySQL允许的扩展索引前面讲了数据库会为主键自动建索引那什么是索引呢只做简要介绍后面深入讲索引就是个目录保存了“该主键字段的每列数据在哪一行存着”这样的位置信息是额外存的结构占磁盘空间不是表本身的数据它可以加快 where 、排序 order by 、分组 group by 的查询速度。默认只有主键和唯一键自动建唯一索引因为唯一性约束本质上就是通过唯一索引来实现的。具体来讲就是唯一约束的本质就是“不允许重复值”数据库在插入或更新数据时需要快速检查这个值是否已经存在。没有索引数据库就得全表扫描才能判断重复效率太低。所以数据库会自动为唯一约束创建一个唯一索引用它来快速查重。其他字段不会自带索引要手动创建。当然我们也不会给所有字段建索引索引占空间还会拖慢增、删、改操作查询的时候确实靠索引提速但对数据执行增删改操作的同时要维护索引所以增删改的操作会变慢所以只给经常用来 where 、 order by 的字段建。唯一键就是被unique约束的字段全称“唯一约束键”主键是一种特殊的唯一键。不过在MySQLInnoDB中主键默认是聚簇索引数据行按主键顺序物理存储唯一键默认是非聚簇索引辅助索引。要注意auto_increment 不能随便给普通字段用一般搭配主键。auto_increment要求字段必须是唯一索引而主键本身就是唯一索引原因① 数据库重启后需要利用唯一索引快速获取字段最大值初始化自增计数器。所以没有唯一索引都找不到最大值怎么进行1赋值② 唯一索引提供唯一性约束防止你在手动为字段赋值和上面演示的类似时造成字段值重复。③ MySQL InnoDB语法硬性要求。虽然auto_increment 不是主键的专属属性它只要求必须用在唯一索引上其他非主键的唯一索引字段在语法上也可以使用auto_increment但工程实践中确实只会给主键用不会给其他字段加auto_increment复合主键一个表中不允许出现多个主键但是一个主键可以包含多个字段复合主键复合主键语法createtablestudent(idbigint,namevarchar(20),primarykey(id,name));复合主键在唯一校验时对于两行数据只有复合主键中所有的列都相同才被判定为重复。所以(1,‘张三’)和(2,‘张三’)就被认为是不重复的这两条记录都可以成功插入外键 foreign key可以看出左边学生表的主键是‘编号’右边班级表的主键也是‘编号’可以看到班级表的主键在学生表中也存在那么它就叫做学生表的外键表与表之间就是通过外键-主键进行关联的。当然上述的这个主键也可换做是具有唯一索引的字段也是一样的效果那么我们正常地创建这两个表当我们再向学生表中插入一个班级id5的学生时发现是可以成功添加的但是在班级表中查找后发现实际上并不存在班级id为5的班级insertintostudent(name,class_id)values(武松,5);手动定义外键约束就可以解决这样的问题语法foreignkey(字段名1)references主表(字段名2)意思是约束外键字段字段1它依赖/参考于主表的字段2这样一来子表student就对主表class产生了依赖数据库就会进行对该表中的外键值的校验再插入一个主表中不存在的值就会报错。这样通过外键约束保证了数据的完整性和关系的正确性当子表中存在对主表数据的依赖的时候能不能删除主表中相应的记录当然是不可以的如果要删除主表中的记录子表中不能有对该条记录的依赖也就意味要先删除子表中的外键字段值再去删除主表中对应的主键字段值check了解作用检查字段的值是否满足你写的条件不满足就拒绝插入/修改。但是MySQL8.0之后的版本才生效之前的版本都不支持该约束写了也没用不生效-- 写法1写在字段后面createtablestudent(idintprimarykeyauto_increment,ageintcheck(age0andage150));-- 写法2写在所有字段后面可以同时检查多个字段createtablestudent(idintprimarykeyauto_increment,ageint,scoreint,check(age0),check(scorebetween0and100));以及像这样的写法check(genderin(男,女))#性别只能是男/女就是因为他的版本兼容性差所以一般也不使用它可能部署到其他的数据库就失效了但是代码还在这就可能会导致错误