🚩更新(Update)
🚩删除(Delete)
🚩数据库约束
🎈约束类型
✅NULL约束
✅NNIQUE 唯一约束
✅DEFAULT:默认值约束
✅PRIMARY KEY:主键约束
✅FOREIGN KEY:外键约束
🌈"子"不能增加和更新 "父"存在相关联的列
🌈"父"不能删除和更新 "子"存在相关联的列
🌈 外键是俩个表的 列 产生关联关系 ~其他列不受影响
🌈父表中被关联的一列必须是主键或者unique
🌈不能删除父表
🌈电商网站(在线和下架商品)
上一节的内容我们讲述了 查询插入等基本操作,本章会讲述 修改 以及数据库约束。
还是进行这个表来操作。
🚩更新(Update)
update 表名 set 列名=值 where 条件;
-- 将孙悟空同学的数学成绩变更为 80 分
update exam_result set math=80 where name="孙悟空";
update exam_result set math=60,chinese=70 where name="曹孟德";
我们分步走,首先我们先将总成绩算出来,然后排序,排成升序,那么前三个就是倒数前三个了,然后数学成绩+30;
我们执行上面的语句的时候,我们到超出数据范围,我们看到math再第二行超出返回,math的数据类型是decimal(3,1),但是85.0+30=115.0超出了数字长度是3的事实,所以报错。
让数据-30是完全可以的, 因为数字长度是3, 小数点后一位长度。
-- 将总成绩倒数前三的 3 位同学的数学成绩减少 30 分
出现了同样的问题,我们看看每个学生的语文成绩。
我们看到chinese的数据范围也同样是 decimal(2,1),数字长度是2,小数点后一位。*2之后67*2=134.0超出了decimal范围,就会报错。
-- 将所有同学的语文成绩更新为原来的 1/2 倍
改变了7行,但是警告有2个,这是为什么?
如果语文成绩是空的话,是无法改变的。那么就会显示Rows matched:8 Changed:7 Warning:2
显示警告 show warnings;
数据发生截断在第2行和第5行。
由于语文成绩的范围是dcimal(2,1),数据长度是2,小数留一位小数。所以数据自动发生了截断。
🚩删除(Delete)
delect from table [WHERE ...] [ORDER BY ...] [LIMIT....];
DELETE FROM exam_result WHERE name = '孙悟空';
delete from test;只删除表中所有的数据,不删除表
drop table test; 删除所有数据和表。
这时候就没有这个表了。
🚩数据库约束
有的时候,数据库中的数据是有一定要求的,有些数据认为是合法数据,有些是非法数据,
数据库,自动的对数据的合法性进行校验检查的一系列机制——目的就是为了保证数据库中能够避免被插入/修改一些非法数据。所以这时候需要数据库约束
🎈约束类型
- NOT NULL - 指示某列不能存储 NULL 值。
- UNIQUE - 保证某列的每行必须有唯一的值。
- DEFAULT - 规定没有给列赋值时的默认值。
- PRIMARY KEY - NOT NULL 和 UNIQUE 的结合。确保某列(或两个列多个列的结合)有唯一标识,有助于更容易更快速地找到表中的一个特定的记录。
- FOREIGN KEY - 保证一个表中的数据匹配另一个表中的值的参照完整性。
- CHECK - 保证列中的值符合指定的条件。对于MySQL数据库,对CHECK子句进行分析,但是忽略CHECK子句
✅NULL约束
我们重新创建一个表,设置id是不能为空的。
我们插入数据的时候,如果给id赋值为空,那么就会报错。
✅NNIQUE 唯一约束
表示sn列为唯一的,不重复的。
✅DEFAULT:默认值约束
指定插入数据时,name列为空,默认值unkown:
当我们后续插入数据的时候,default就会在没有显式指定插入的值的时候生效了。(上面我只给id,sn,qq_mail)插入数据了,并没有给name插入数据,所以最终查看表的时候,name是defaule。
✅PRIMARY KEY:主键约束
primary_key其实是not null和unique的结合,所以我们不用再单写非空或者唯一的约束了,只需要写上主键约束的。
这个是最重要的约束,一行记录的身份标识。
一张表中只能有一个primary key,一个表里的记录,只能有一个作为身份标识的数据。
虽然只能有一个主键,但是主键不一定只是一个列,也可以多个列共同构成一个主键(联合主键)
id一行null被设置成not null,key是主键。
那么如何保证主键唯一呢?
对于整数类型的主键,常配搭自增长auto_increment来使用。插入数据对应字段不给值时,使用最大值+1。
mysql提供了一种“自增主键”这样机制,主键经常会使用int/bigint,程序员再插入数据的时候,不必手动指定主键值,由数据库服务器自己给你分配一个主键,会从1开始,依次递增的分配主键的值。
null其实是交给数据库服务器自动分配的,会自动增加。
如果我们突然加个id=10的编号学生,如果再加个id=null,那么这次的id是11。自动增加id。就是从刚才的最大的数值开始,继续往后分配的。相当于使用一个变量保存了当前表的id的最大值,后续分配自增主键都是根据这个最大值分配的,如果手动指定id,也会更新最大值。
✅FOREIGN KEY:外键约束
描述俩个表之间的关联关系。
class(classId,name)100 计科1班101 计科2班102 计科3班103 计科4班
student(id,name,classId)1 张三 1002 李四 1003 陈陈 1024 乐乐 200
外键就是用来描述这样的约束过程的。class表中的数据,约束了student表中的数据,
- 把class表称为"父表",约束别人的表,
- 把student表,称为"子表",被别人约束的表。
如果我们插入class表中加入上述数据,但是插入student表加一个classId不等同于class表中的classId,这样就不构成了关联关系。我们不能通过classId找到关联关系。
从这我们可以看到其实就是普普通通的俩个独立的表,并没有关联的表,只是这俩个表都有classId属性而已。那样再正常的创建表是没有问题,但是再运用到俩表之间的关联问题是有问题的。所以我们就得设置外键约束。
我们给学生表中的classId设置成外键,用foreign key (被约束的列) references 约束的表(约束的列).这样俩表之间就产生了联系。
🌈"子"不能增加和更新 "父"存在相关联的列
如果插入到student表中的classId是没有再class表中的classId存在的话,那么就会报错。我们分析一下报错信息。
这个错误说明正在试图插入或更新一个“子”行,但是它引用的“父”行在相关的父表中不存在。
例如,假设有一个名为 "订单" 的表和一个名为 "客户" 的表。订单表中有一个外键,指向客户表中的客户ID。如果你试图向订单表中插入一个订单,但是你提供的客户ID在客户表中不存在,那么就会出现这个错误。这个例子就和上面的例子一样的,student表有个外键,指向的是class表中的classId,如果你要给student表中插入一个学生(但是你提供的学生班级ID是在class表中不存在,这就报错了。因为上面我插入给student表中的classId是120,但是我们在class表中我们发现
为解决这个问题,你需要确保在进行插入或更新操作之前,相关的父表中存在对应的行。或者,你可以选择允许空值或者使用默认值来避免外键约束。
🌈"父"不能删除和更新 "子"存在相关联的列
如果针对父表进行 修改/删除 操作,如果当前被修改/删除的值已经被子表引用了,这样的操作也会失败。外键约束始终要保持,子表中的数据在对应的父表的列中,要存在,如果万一父表的这条数据删除的,也就打破了刚才的约束了,除非先删除子表相关联的列,再删除子表引用的列的父表。
尝试删除或更新一个“父”行,但是这个父行有一个或多个“子”行引用了它。这个错误说明正在试图删除或更新一个“父”行,但是它有一个或多个“子”行引用了它,因此数据库系统拒绝了这个操作。
例如,假设有一个名为 "作者" 的表和一个名为 "书籍" 的表。书籍表中有一个外键,指向作者表中的作者ID。如果你试图从作者表中删除一个作者,但是该作者有一本或多本书在书籍表中,这些书籍的作者ID指向了被删除的作者,那么就会出现这个错误。
为了解决这个问题,你需要先删除或更新所有子行,以确保它们不再引用被操作的父行,然后再执行删除或更新操作。或者,你可以选择在定义外键约束时指定级联选项,以便在父行被删除或更新时自动处理相关的子行。
🌈 外键是俩个表的 列 产生关联关系 ~其他列不受影响
这样是不影响,真正影响的是俩个表相关联的列产生的,不能改class表中的classId,因为和子表有关联。
🌈父表中被关联的一列必须是主键或者unique
当我们重新创建父表和子表的时候,我们看到外键不能被约束了,我们可以看到 student表关联的是class表中的classId,但是class表中的classId不是主键,我们规定指定外键约束的时候,要求父表中被关联的这一列,得是主键或者unique。
🌈不能删除父表
删除表前提是先删除记录,删表肯定是不可以的,你还有子表相关联,父表没了,子表后续添加元素,就没有参考了,正确的删除方式是先删除子表,然后删除父表即可。
此时删除成功。
🌈电商网站(在线和下架商品)
我们创建好商品表和订购单表,然后我们考虑一下,过了一段时间之后,商家想把这个衬衫下架(删除掉) 如何删除?(尝试删除父表数据的同时,如果父表的数据被子表引用了,是不能删除的,就会报错了,那么再这种情况下,如何保证外键约束存在的前提下,实现“商品下架"功能呢?
解决方法就是 :给商品表增加一列,表示是否在线(不在线,相当于下架了)
alter table 表名 add column 列名 类型(default 默认值);
我们将表增加一个列isOk默认值是1,1代表商品在线,0代表商品下线。所以我们如果需要下架商品的时候,就使用update把isOk从1-》0即可。查询商品的时候,都加上where isOk=1这样的条件。
我们向goods表中插入值。
向orders订单表中插入数据。
使用场景一:如果我们要下架"裤子"类型的商品
只需要将 更新isOk的值,条件是 类型是裤子
使用场景二: 如果要查询正在卖的商品类型(也就是isOk=1)
只需要where isOk=1即可
有些瞬间,会支撑着我。