【MySQL】表的约束

打印 上一主题 下一主题

主题 994|帖子 994|积分 2982



  
零、媒介

表中一定要有各种约束,通过约束来让用户将来插入的数据是符合要求的。约束的本质就是通过计算反过来要求用户插入准确的数据。所以站在MySQL的角度上来看,凡是插入进来的数据,一定是符合条件约束的。
约束最终的目的就是保证数据的完整性和可预期性,所以MySQL中须要更多的约束。

一、空属性



  • 两个值:null(默认的)和not null(不为空)
  • 数据库默认字段基本都是字段为空,但是现实开辟时,尽大概保证字段不为空,因为数据为空没办法参与运算。

下面我创建了一个表class,class有三个字段,class_name和class_room不能为null,而other默承认以为null,所以在下面插入数据的时候,我先尝试每个字段都填有数据,发现可以插入成功。然后再插入数据时,只填写字段class_name和class_room的对应数据,发现同样可以插入成功,这是因为字段other默承认以为null,然后我再插入时,只填写class_name对应的数据时,发现堕落了,并告诉我字段class_name没有默认值。最后我再插入数据时,只填写字段class_name和class_room的对应数据,但是class_room对应的数据填写为null,这次它又报错,并告诉我插入到字段class_room的数据不能为null。
所以当我们给一个字段添加了非空约束,用户想向当前字段插入null值,都会被MySQL拦截,这就是非空约束。


二、默认值

默认值:某一种数据会经常性的出现某个具体的值,可以在一开始就指定好,在须要真实数据的时候,用户可以选择性的使用默认值。
下面我创建了一个表t1,t1包罗三个字段name,age和sex,此中name没有默认值且不能为null,age默认为18且可以为空,sex默认为男且不能为空。
这里我先测试字段name,字段name没有默认值且不能为null。首先我先指定全部字段插入有效数据,插入成功,然后我再指定全部字段插入数据,但只有字段name的数据为null,这时候MySQL就拦截我的操纵并告诉我字段name处的数据不答应为null,最后我只指定字段age和sex插入有效数据并且我不想给字段name插入数据,这时候MySQL就拦截我的操纵并告诉我字段name没有默认值。

这里我再测试字段age,字段age默认为18且可以为空。首先我先指定全部字段插入有效数据,插入成功,然后我只指定字段name和sex插入有效数据并且我不想给age字段插入数据,照旧插入成功并且age使用的是默认值18,最后我再指定全部字段插入数据,但只有字段age的数据为null,最终照旧插入成功。

这里我最后测试字段sex,字段sex默认为男且不能为空。首先我先指定全部字段插入有效数据,插入成功,我只指定字段name和age插入有效数据并且我不想给sex字段插入数据,照旧插入成功并且sex使用的是默认值男,最后我再指定全部字段插入数据,但只有字段sex的数据为null,这时候MySQL就拦截我的操纵并告诉我字段sex处的数据不答应为null。

小结:
从这里我们就可以得出一个结论了,not nulldefault 并不是冲突,并且两者照旧相互增补的。


  • 对于 not null 来说,用户的数据会被分为两类:null 和 正当数据,not null 约束的就是用户想插入数据并且插入的数据不能为null
  • 对于 default 来说,用户被分为两类:想输入的和不想输入的,default 使得想输入的用户可以输入本身的数据,使得不想输入数据的用户使用默认值。当用户没有给字段设置default选项并不想输入数据时,MySQL就会对该操纵进行拦截。
注意:MySQL中答应 not null 和 default 同时出现,但是 not null 和 defalut 一样平常不须要同时出现,因为 default 本身有默认值,不会为空。

我们之前在建表时,没有给字段设置default和not null属性,但是用户不想插入数据的时候,它默认给他插入的值是null。这是MySQL的默认表定义举动。


三、列形貌

列形貌:comment,没有现实含义,专门用来形貌字段,会根据表创建语句保存,用来给程序员或数据库管理员来进行相识。
通过desc查看不到形貌信息,通过show可以看到形貌信息。


四、zerofill

我们知道很多类型背面都有(),并且我们也知道此中数字的意义,现实上int类型背面也可以带(),这里我们就来讲述一下int类型背面数字的意义是什么,在MySQL8.0.17版本后,默认就不显示()和内里的数字了,只有带上 zerofill 选项才会显示。

现实上int背面的数字就是int的显示宽度,当带上了zerofill选项后,用户查找表中的信息时,存储数据的宽度小于设置的显示宽度时,就会在数据的前面增补0,直到与设定的显示宽度类似,zerofill并不影响数据存储,它只影响背面的格式化显示。
下面我将表中字段num2的显示宽度调整为5,再向表中插入一些数据,然后就可以发现,当存储的数据的宽度小于显示宽度,就会在显示时在数据前面添加0,而当存储的数据的宽度即是或大于显示宽度,显示时该怎么显示就怎么显示。


五、主键

主键:primary key用来唯一的约束该字段内里的数据,不能重复,不能为空,一张表中最多只能有一个主键;主键所在的列通常是整数类型。
下面我创建了一个t5,t5包罗两个字段id和name,此中id为主键,当我查看创建表t5的命令时,发现MySQL对我的命令进行了调整,这也是一种给字段添加主键的方式,并且当一个字段为主键时,MySQL会默认给这个字段添加非空约束。

当我向表中插入一些数据的时候,当id不重复时,都可以成功插入,当重复时,MySQL就会拦截这一操纵,并告诉我主键冲突了。

当一个表中含有主键时,还可以删除主键。
  1. ALTER TABLE 表名 DROP PRIMARY KEY;
复制代码
下面我就删除了表t5的主键,当我再次查看创建表的命令时,就没有了主键的相干的内容了,并且当表中含有类似的id时,同样可以插入了。

当表创建好以后但是没有主键的时候,可以再次追加主键
下面我向表t5追加主键,但是MySQL拦截了我的操纵并提醒我字段id这个列中有重复的数据,当我删除掉此中一行数据以后,再次追加主键就成功了,之后想要插入id类似的数据,MySQL就会对该操纵进行拦截。
所以主键最好是在创建表的时候就带上,或是刚刚创建表后追加主键,不要已经使用了一段时间后再追加。

复合主键:一个表中只答应有一个主键,但是不代表主键只能是一列。在创建表的时候,在全部字段之后,使用primary key(主键字段列表)来创建主键,如果有多个字段作为主键,可以使用复合主键。
  1. ALTER TABLE 表名 ADD PRIMARY KEY (字段列表);
复制代码
在大学中就有这样的应用场景,大学生在选课时,可以一个人选多门课,也可以多个人选同一门课,但是不答应一个人多次选择同一门课。
下面我创建一个表t6,t6中有两个字段id和course,这两个字段合起来为一个复合主键。当我使用desc命令查看表t6时,发现两个字段都是pri,这并不代表有两个主键,而是两个字段合起来是主键,并且MySQL默认给主键添加了非空约束,当我向表中插入类似数据的,MySQL会对我的操纵进行拦截。


六、自增长

auto_increment:当对应的字段,不给值,会自动的被系统触发,系统会从当前字段中已经有的最大值+1操纵,得到一个新的差别的值。通常和主键搭配使用,作为逻辑主键
自增长的特点:


  • 任何一个字段要做自增长,前提是本身是一个索引(key一栏有值)
  • 自增长字段必须是整数
  • 一张表最多只能有一个自增长
下面我创建了一张表t7,t7中有两个字段,此中字段id为主键并且自增长,下面我向表中插入了一些数据,并且我不指定id的值,发现id默认是从1开始的,当我再插入一个数据并指定id为100,然后再插入数据并且不指定id的值,发现背面的id是从我指的的id背面开始增长。
当用户创建包罗自增长字段的表时,如果该字段的起始值未指定,则默认从1开始自动递增。后续插入数据时,若用户为该字段指定了值,系统将基于此值加1后保存。


七、唯一键

一张表中有往往有很多字段须要唯一性,数据不能重复,但是一张表中只能有一个主键,唯一键就可以解决表中有多个字段须要唯一性约束的问题
唯一键的本质和主键差不多,唯一键答应为空,而且可以多个为空,空字段不做唯一性比较。
举个例子:在大学中中,每个人都有身份证号码,每个人都有本身的学号,但不一定每一个人都有电话号码,身份证号码是每个人都不一样的,学号也是每个人都不一样的,电话号码也是每个人都不一样的,一个大学生的身份证号码和学号和其他人的都不一样,辅导员找学生可以使用身份证号码,也可以使用学号,在大学中通常就是使用学号来查找对应的学生,但并不是说身份证号码就不能找到这个学生,所以我们可以选择此中身份证号码和学号此中一个作为主键,但不意味着大学生其他的属性不须要维护唯一性,所以须要唯一键来维护大学生的其他须要唯一性的属性。
下面我创建了一个表student,student中有3个字段id、num和telephone,此中id为主键,其他两个为唯一键,将表创建出来后,查看具体信息,我们发现了唯一键默承认以为空。

下面向表student中插入一些数据,通过下面插入数据的信息来看,当插入数据中对应唯一键上的列数据与表中的冲突类似时,MySQL会对该操纵进行拦截,但是当我将对应的数据修改为NULL时,却插入成功了。

主键 VS 唯一键
主键通常用来标定一行数据在整表中的唯一性,唯一键是为了让插入的列值与表中其他的列值不要冲突。一个表是用来形貌对象的各种属性列的,这时候我们可以选择这个属性列作为主键,但不意味着对象其他的属性不须要维护唯一性,一个属性列是主键,仅仅是因为我们选择它为主键,并不是其他属性不能作为主键。

八、外键

外键用于定义主表和从表之间的关系:外键约束重要定义在从表上,主表则必须是有主键约束或唯一键约束。当定义外键后,要求外键列数据必须在主表的主键列存在或为null。
  1. foreign key (字段名) references 主表(列)
复制代码
例子:

首先这里我先创建主表,再插入一些班级信息,一样平常来说是先有班级后才有学生。

然后再创建学生表,并且插入一些学生消息,注意这里如今并没有使用外键约束。当我插入王中王这位同砚时,它的班级号为3,固然说插入成功了,但班级表中并没有这个班级。

最后我想删除火箭班,按理来说班级中还有人,就不应该可以或许删除这个班,所以现在来看,学生表和班级表只有外键之名,没有外键之实,外键=关系+约束


下面我重新创建两张表,让两张表形成关联关系,并使用外键约束,然后再插入一些数据。

这里我先向班级表中插入一些数据,再向学生表中插入一些数据,最后再删除班级表中的一些数据。
当我插入王中王这位同砚时,它的班级号为3,但显然班级表中并没有3号这个班级,又由于外键约束的存在,所以MySQL将我的插入操纵拦截了。

这里我想从班级表中删除火箭班,但是此时学生表中还有同砚是属于这个班的,所以又因为外键约束的缘故原由,MySQL将我的操纵拦截了,只有学生表中没有属于这个班级的学生时,MySQL才会运行我删除这个班级。

小结:
创建外键的本质其实就是把相干性交给MySQL去审核了,提前告诉MySQL表之间的约束关系,那么当用户插入不符合业务逻辑的数据的时候,MySQL不答应你插入。

末端

如果有什么建媾和疑问,或是有什么错误,大家可以在评论区中提出。
盼望大家以后也能和我一起进步!!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

王海鱼

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表