MySQL数据库操作篇2(表的增删查改约束)

news2025/1/16 20:12:35

在数据类型那篇文章里,笔者曾经提到过约束条件,但也只是简单的提了提,并没有展开来说,约束条件是MySQL为确保数据正确性,安全性,以及倒逼程序员规范操作的一大利器,这篇文章笔者详细谈谈有哪些约束条件,具体是怎样约束的,同时简单介绍如何对表中数据进行增删查改等操作

目录

表的基础插入

表的约束条件 

1.not null约束

2. default约束 

3.主键约束 

复合主键 

4.唯一键

主键和唯一键的区别 

5.comment 约束

6.zerofill

7. 自增长(auto_increment)

8.外键 

表的增删查改

表中数据的查找

表中数据的删除操作 

表中数据的更新操作 


 

表的基础插入

在了解表的约束之前,我们先看看表的插入,因为表的不少约束条件都是在创建表和插入表时起作用的,想要在表中插入数据,首先得创建一个表,这里笔者创建一个学生表

create table students(

name varchar(30),

student_id  varchar(20),

)

在表中插入数据时,要使用插入语句

insert into table_name [property_column...] values (property_value)

table_name: 指的是要插入数据的表名

property_column: 指的是要往哪些属性列里插入数据,这里我加的是方括号,说明可以省略不写,如果省略不写,那么就是默认全插入,每一个属性列都要有对应的值

column_value:圆括号就是具体要往属性列中插入的值

tip:into也是可以省略的,但是为了语意清晰,我们一般插入数据时并不将into省略掉,但这并不意味着别人不会省略,遇到了,还是要能看得懂的

接下来通过例子来演示一下

select * from students; 意思是查看表中所有数据,后面讲查询时会详细说

通过上面的程序实例,可以发现,如果只插入姓名,而不插入学号也是可以的,没有插入学号,系统默认将其值设为NULL,NULL不是0,NULL也不是'  ',NULL表示不存在,显然这是不符合逻辑的,既然是在校生,那么必然是要有学号的,那么我们之后就得设立一些约束条件来限制这种插入形式,让学生的姓名和学号都不允许为空

当然上面还有一个问题,我每插入一次数据,前面都要加上insert into table_name [property_column...] values

能不能一次插入多个数据呢,MySQL是允许这样操作的,具体做法就是用逗号把要插入的不同的数据分隔开,示例如下

 

如上图,这样就能一次插入多个数据了 

插入若存在则更新(在正常插入语句后面加上 on duplicate key update [要修改的属性值])  

这主要是针对要插入的数据与主键或是唯一键产生冲突的情况,那么更新这个主键或是唯一键的其他部分为新插入的属性值

但是要注意,除主键或是唯一键冲突外,新插入的属性值,不能再与其他属性值冲突

以下是执行命令后根据受影响行数来判断执行结果如何

插入若存在则替换(使用新语句replace)

-- 主键 或者 唯一键 没有冲突,则直接插入; -- 主键 或者 唯一键 如果冲突,则删除后再插入

replace into tabale_name (property_column) values (property_value)

--1 row affected: 表中没有冲突数据,数据被插入

--2 row affected: 表中有冲突数据,数据被删除后重新插入

表的约束条件 

还记得我们上面插入时的一些不合理的现象嘛,只插入姓名不插入学号是被允许的,但是这在我们现实中是不允许的,一个学生不仅要有姓名,还要有唯一的学号标识他,因此学号是绝对不能为空值的,我们可以通过加约束条件来解决这个问题

1.not null约束

只要某个属性列设为了not null那么这个属性列必须有具体的值,否则无法插入,这个约束条件是在创建表的时候添加的,接下来我们重新创建一个学生表演示一下

如上图,在创建表时,我将name 和 student_id都设为了not null,都不允许为空值,接着我尝试只插入姓名或者只插入学号都得到了拒绝,不许我插入,这就是not null 约束,当你有某些数据是绝对不允许为空时,可以将其设为not null,这样未来如果该数据为空,数据库会直接拒绝插入

2. default约束 

在创建表时,某一个属性列若设置了default,也就是设了一个默认值,那么未来用户在插入数据时,如果忽略了这个属性列,则数据库会自动使用默认值。

如果用户在建表的时候没有添加default值,那么数据库会优化为default值为null,这符合我们前面的那个例子,前面的学生表中,忽略了学号这一列,那么系统会默认将学号的默认值设为null,也就出现了下图学号为null的情况 

大家可以仔细想一想,default 和 not null 是不是相辅相成的

以上表为例,表中 student_id 这个属性列没有设立默认值,而且插入数据时忽略了这个属性列,那么数据库就会默认给这个属性列优化为 default 为 null,而这个属性列特别重要,是一定不能为空的,我们给加上了not null,此时default默认设立的 null 就会触发 not null条件约束,从而报错拒绝你的数据插入

 

如上图,在创建学生表时,我给姓名和学号都设置了默认值,并且在插入数据时,我什么数据都不插入,然后查看表中数据发现确实是使用了默认的值

 

使用默认值,尽管插入时忽略了student_id这一行,student_id 也不怕为空,因为可以使用默认值,等等,这好像也不对呀

学号是唯一的呀,每个学生的学号都是独一无二的,这里出现了三个同样的学号这也是不允许的,我们要确保通过学号能找到每个同学,这个问题可以通过其他约束条件来解决

3.主键约束 

primary key用来唯一的约束该字段里面的数据,不能重复,不能为空,一张表中最多只能有一个主键;

简单说就是一张表里的某个属性列如果设为了主键,那么这个属性列里的数据就不能是重复的,并且一张表只有一个主键,即只能有一个属性列被设为主键

我们把上面学生表的学号设为主键测试一下

 

如上图,我们给学号这个属性列设为了主键,然后忽略学号这个属性进行数据插入,第一次插入时没有问题,学号使用了默认值,但是第二次再次插入时就报错了,因为学号这个属性列被主键约束了,主键约束保证数据的唯一性,再使用默认值,学号这个属性列就会有两个100101,这是不被允许的,因此报错拒绝插入

上面是为了引出并解释主键,事实上很少有人会给被主键约束的属性列添加default默认值

复合主键 

如果主键是由多个属性列组成的,即复合主键,那么在建表时,就不用主键直接修饰具体的列了,而是表的最后给出 primary key (column_1, column_2, ...)

用学生表举例,设学生的姓名和学号都被主键约束

create table students(

name varchar(30) ,

student_id varchar(20) ,

primary key(name, student_id)

)

4.唯一键

解决完上面的问题,我们在学生表里再多添加一个属性列,加一个学生的手机号码

create table students(

name varchar(30) not null,

student_id  varchar(20) primary key,

telephone varchar(15)

)

然后我们插入一些数据

 

假设我不小心把每个人的电话号码都插入成一样的了,每个人的手机号码都是不同的,所以遇到这样的错误,数据库应该拒绝插入

通过上面的主键我们了解到,被主键修饰的属性列可以保证插入数据的唯一性,但是主键只能有一个呀,并且用来修饰student_id了,这个时候我们可以使用唯一键来解决这个问题

被唯一键 unique 修饰的属性列保证该列的数据都是唯一的,即不会出现重复的

接下来重新创建一个学生表,把学生的手机号码用唯一键修饰

create table students(

name varchar(30) not null,

student_id  varchar(20) primary key,

telephone varchar(15) unique

)

 

 如上图,手机号码被唯一键修饰后,当插入两个相同的电话号码时,数据库会拒绝这样的插入操作并报错

主键和唯一键的区别 

在上面的例子中,感觉主键好像和唯一键的功能是一样的呢,都是用来保证被修饰的属性列的数据唯一性,但是这两者其实还是有很大区别的

1.被主键修饰的属性列在插入数据时,该列的值不能为空,也就是被主键修饰的属性列不存在NULL

而这点和唯一键就不一样了,唯一键虽然不允许存在两个相同的值,但是允许存在空值,并且允许存在多个空值

 

2. 主键一张表中只能有一个,而一张表中可以存在多个唯一键 

3.主键能起到标识表的作用(不了解没关系,后面会提到),而唯一键则是保证表中某一列数据不能重复

5.comment 约束

comment约束,是一种软性约束,类似于编程语言的注释

 

用来告诉操作人员,该列是用来干嘛的,或者指明一些插入条件信息,从而避免一些不必要的错误 

6.zerofill

如果某一个属性列添加了zerofill,那么如果宽限小于设定的宽限,那么会用0填充直到达到了设定的宽限
主要是用于格式化显示,并不影响实际的数据
默认int的宽限是10,因为int所能表示的数据,换成十进制,用10位数就能完全表示出来

上图中,t1被zerofill约束修饰,而t2没有被修饰

查看数据时可以发现,t1未达到10位数,前面补了7位0 

7. 自增长(auto_increment)

auto_increment:当对应的字段,不给值,会自动的被系统触发,系统会从当前字段中已经有的最大值+1操作,得到一个新的不同的值。通常和主键搭配使用,作为逻辑主键。
自增长的特点:
  任何一个字段要做自增长,前提是本身是一个索引(了解即可,以后会提到)
  自增长字段必须是整数
  一张表最多只能有一个自增长
如果插入时没有设置默认值,那么默认从1开始插入,auto_increment可以设置默认起始值

 

如上图,给id这个属性类添加了自增长,随着不断插入数据,id这一列的值也会不断地增大

8.外键 

要说清楚外键,我们要明白什么是主表和从表,看看下面这个例子 

在这个例子中,我创建了两个表,一个学生表和一个班级表,通过表中的数据我们知道,班级表中只有两个班级,即4班和7班,但是学生表中出现了一个班级为5的同学,这样的数据是不符合我们的预期的,因为我们根本就没有开设5班。现实中我们插入数据难免会出现这种情况,所以我们需要一种约束条件能够做到:当学生表插入数据时,如果该学生的班级数据在班级表中不存在时,那么数据库将拒绝这个数据插入,避免无效数据

在这个过程中,明显学生表是依赖于班级表的,因为学生表在插入数据时,要看看其插入的班级数据是否在班级表中,如果存在允许插入,不存在拒绝插入,怎么实现这个过程呢

我们可以通过在学生表和班级表之间建立外键联系来实现,因为学生表依赖于班级表,我们称学生表为从表,称班级表为主表

外键强调表与表之间的关联,表与表之间的约束

外键用于定义主表和从表之间的关系:外键约束主要定义在从表上,主表则必须是有主键约束或unique约束。当定义外键后,要求外键列数据必须在主表的主键列存在或为null

语法:foreign key (column_name) references 主表(column_name)

注意一定要先创建主表,从表才能够设立外键

接下来,举例来说明

 

 创建班级表和学生表,学生表要引用课程表中的数据,是从表,所以在学生表中设立外键

 

如上图中,班级表中只有4班和7班,当学生表中含有5班的数据时,数据库会直接拦截报错,因为通过外键约束,可知5班在班级表中不存在,从而拦截报错

表的增删查改

表中数据的查找

要进行表中数据的查找,需要使用关键字select

对数据的查找是数据库中非常重要的一个功能,笔者后面会专门有一篇文章来介绍select的各种操作,这篇文章先从简单的select操作学起

SELECT column_name

FROM table_name

select:表示检索,查询

column_name: 表示查询完成后要显示的列名

FROM table_name: 表示从table_name这个表中查询数据

举个例子,看如下一个学生表

我想查找所有学生的姓名,性别和出生日期

操作语句为:select name, sex, birth_date from student;

意思是从student这个表中查找数据,并且显示name, sex, birth_date这三个属性列

如果想查找表中的全部数据该怎么办呢?这个时候我们可以使用通配符 * 

表示匹配表中所有的属性列

操作语句为:select * from student;

这查找的是所有学生的数据,现在我在查询时要进行筛选,比如查找出生日期为2000年的学生的所有数据

这个时候就要用到筛选子句where

下图是可以在where语句中进行的运算符操作

除了图中的这些运算符,还有

is null

is not null 

这两个语句用来判断是否为空的

表示等于的运算符除了' = '

还有" <=> " 两者的区别是 ' = '不能判断是否等于NULL," <=> "可以判断是否等于NULL

NULL= NULL结果为 NULL , 而 NULL <=> NULL 结果为true

回到上面的问题,查找出生日期为2000年的同学

操作语句为:select * from student where birth_date = 2000;

如果想要按照出生日期给所有同学排个序,该怎么操作呢

这个时候可以用到order by子句

-- ASC 为升序(从小到大)

-- DESC 为降序(从大到小)

-- 默认为 ASC

NULL值也参与排序,但是NULL被视为比任何值都小,如果排升序,那NULL值将在最上面

SELECT ... FROM table_name [WHERE ...] ORDER BY column [ASC|DESC], [...];

因为这里用不到where子句,所以我们直接排序即可

操作语句为:select * from student order by birth_date;

现在我不想看所有的同学,我只想看这些同学中年龄最大的三位同学,该这么操作呢

这就要用到 limit 子句

首先还是要用年龄将同学排序,接着使用limit子句

操作语句如下:select * from student order by birth_date limit 3;

limit 3 表示从头开始,只显示三条数据

limit 2, 3 表示从下标为2的数据开始,显示三条数据(下标从0开始)

也可以使用下面这种写法 limit 3 offset 2

表示读取三条数据,起始下标位2

表中数据的删除操作 

1. delete

DELETE FROM table_name [WHERE ...] [ORDER BY ...] [LIMIT ...]

delete可以清空表,但是在删除表中数据之后,auto_increment的计数器的值并不会重置

2.truncate

TRUNCATE table_name

直接将表中的数据全部清除,truncate不会被记录到SQL语句的历史记录中,truncate 删除表中数据后,auto_increment的计数器的值会重置

接下来创建一个表来演示这两个关键字的用法

 首先用delete函数来实现把表中小张给删掉

接下来我们用delete删掉表中一些同学,只留下两个年龄最大的同学

delete可以与where,order by , limit等子句配合进行细分化删除

而truncate则是直接将表中的数据全部删除掉

 

表中数据的更新操作 

update

对查询到的结果进行属性值更新

UPDATE table_name SET column = expr  [WHERE ...] [ORDER BY ...] [LIMIT ...]

update不仅可以跟where子句,还能跟order by和 limit配合使用

将学生表中小宋的性别改为男性

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/678518.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

0019-TIPS-2019-tokyowesterns-gnote : switch(jump) Doubule Fetch

漏洞源码 #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/proc_fs.h> #include <linux/string.h> #include <linux/slab.h> #include <asm/uaccess.h>…

chatgpt赋能python:Python绘制车辆轨迹图

Python绘制车辆轨迹图 在现代交通中&#xff0c;车辆轨迹图是一个广泛应用的技术&#xff0c;它可以被用于道路交通管理&#xff0c;行车安全评估等领域。Python是一种强大的编程语言&#xff0c;它提供了许多绘制数据可视化图表的库。本文将介绍如何使用Python和Matplotlib库…

10.事务消息

4.6 事务消息 4.6.1 流程分析 上图说明了事务消息的大致方案&#xff0c;其中分为两个流程&#xff1a;正常事务消息的发送及提交、事务消息的补偿流程。 1)事务消息发送及提交 (1) 发送消息(half消息)。 (2) 服务端响应消息写入结果。 (3) 根据发送结果执行本地事务(如果写入失…

Golang -> Go 语言快速开发入门

Go 语言快速开发入门 开发一个 hello.go 程序Golang 执行流程分析两种执行流程的方式区别:编译和运行说明 Go 程序开发的注意事项注释行注释多行注释 开发一个 hello.go 程序 package mainimport "fmt"func main() {fmt.Print("hello") }输出: hello对上图…

Cesium 入门

文章目录 一、了解 Cesium二、创建第一个 Cesium 地球三、案例1. Cesium 查看器、场景、实体、数据源介绍2. Cesium 的坐标与转换3. Cesium 相机系统方法一&#xff1a;setView方法二&#xff1a;flyTo方法三&#xff1a;lookAt方法四&#xff1a; viewBoundingSphere 四、案例…

【Leetcode60天带刷】day27回溯算法——39. 组合总和,40.组合总和II,131.分割回文串

​ 题目&#xff1a; 39. 组合总和 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 &#xff0c;并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一…

Redis 实战:逐步指南,让你轻松在 Linux 上安装与部署

目录 前言为什么会出现 Redis&#xff1f;磁盘、内存数据库缓存中间件 安装Redis5Redis6 使用总结 前言 Redis 中文网站&#xff1a;http://redis.cn/ Redis 是一个开源&#xff08;BSD 许可&#xff09;的&#xff0c;内存中的数据结构存储系统&#xff0c;它可以用作数据库…

【编译、链接、装载十二】动态链接2

【编译、链接、装载十二】动态链接2 四、延迟绑定&#xff08;PLT&#xff09;五、动态链接相关结构1 “.interp”段2 “.dynamic”段3 .动态符号表——dynsym、动态符号字符串表——.dynstr4、动态链接重定位表 六、动态链接的步骤和实现1、动态链接器自举2、装载共享对象3、重…

2.10 高性能异步IO机制:io_uring

一、io_uring的引入 为了方便说明io_uring的作用&#xff0c;先举一个通俗点的例子 1、通过异步提高读写的效率 假设有一批数量很大的货&#xff0c;需要分批次运到厂里处理。这个时候就有两种方式&#xff1a; 1&#xff09;同步方式&#xff1a;运送一批到厂里&#xff0c…

TypeScript ~ TS 掌握编译文件配置项 ④

作者 : SYFStrive 博客首页 : HomePage &#x1f4dc;&#xff1a; TypeScript ~ TS &#x1f4cc;&#xff1a;个人社区&#xff08;欢迎大佬们加入&#xff09; &#x1f449;&#xff1a;社区链接&#x1f517; &#x1f4cc;&#xff1a;觉得文章不错可以点点关注 &…

初识EasyX图形库

EasyX图形库 1. EasyX是什么&#xff1f;2. 入手EasyX3. EasyX函数介绍创建和关闭绘图窗口操作initgraphclosegraph 设置绘图背景setbkcolorcleardevice 画图形circlefillcirclerectanglefillrectangle 图形颜色及样式设置setfillcolorsetlinecolorsetbkcolorsetbkmodesetlines…

计算物理专题:有限差分法解决本征值问题

计算物理专题&#xff1a;有限差分法解决本征值问题 定态薛定谔方程差分形式 一维定态薛定谔方程 谐振子 解法代码 import numpy as np def householder(symmetric_matrix):M symmetric_matrixassert np.allclose(M,M.T),"matrix is not symmetric"N len(M)for …

chatgpt赋能python:用Python分析电影评分数据

用Python分析电影评分数据 Python是一种流行的数据分析和可视化工具&#xff0c;它可以让我们更深入地了解电影的评分数据。在本文中&#xff0c;我们将使用Python来分析一些电影评分数据&#xff0c;并试图找出一些有趣的模式和趋势。 数据来源 我们将使用公共数据集IMDb电…

第4章 网络层

1‌、下列关于路由算法描述错误的是&#xff08; &#xff09; A. 链路状态算法是一种全局路由算法&#xff0c;每个路由器需要维护全局状态信息B. OSPF 是一种域内路由协议&#xff0c;核心是基于 Dijkstra 最低费用路径算法C. RIP 是一种域内路由算法&#xff0c;核心是基…

采用SqlSugar的DBFirst相关功能创建数据库表对应的实体类

.NET Core官方教程中推荐使用的EF Core数据库ORM框架虽然能用&#xff0c;但是用起来并不是太方便&#xff08;或者是不习惯&#xff0c;之前用的最多的还是linq&#xff09;。之前下载的开源博客项目中使用的SqlSugar&#xff0c;后者是由果糖大数据科技团队维护和更新 &#…

基于WebAssembly构建Web端音视频通话引擎

Web技术在发展&#xff0c;音视频通话需求在演进&#xff0c;怎么去实现新的Web技术点在实际应用中的值&#xff0c;以及给我们带来更大的收益是需要我们去探索和实践的。LiveVideoStackCon 2022北京站邀请到田建华为我们从实践中来介绍WebAssembly、WebCodecs、WebTransport等…

【裸机开发】IRQ 中断服务函数(一) —— 汇编初始化

IRQ 和前面的Reset 函数不大一样&#xff0c;当一个IRQ中断产生时&#xff0c;我们也不知道这个IRQ中断来自哪个外设&#xff0c;因此&#xff0c;需要先获取到中断ID&#xff0c;随后才会跳转到真正的中断服务函数执行处理逻辑。 整个 IRQ 中断处理可以看做是包含了两个部分&…

MySQL 自增主键一定是连续的吗?

众所周知&#xff0c;自增主键可以让聚集索引尽量地保持递增顺序插入&#xff0c;避免了随机查询&#xff0c;从而提高了查询效率 但实际上&#xff0c;MySQL 的自增主键并不能保证一定是连续递增的。 下面举个例子来看下&#xff0c;如下所示创建一张表&#xff1a; 自增值保…

ORCA优化器浅析——GP数据库调用优化器流程

首先我们需要看CGPOptimizer类(src/include/gpopt/CGPOptimizer.h)为Greenplum数据库提供ORCA优化器export出来的函数的封装。Greenplum数据库主流程调用extern "C"中提供的函数&#xff0c;比如初始化ORCA优化器的函数InitGPOPT&#xff0c;优化查询树的函数GPOPTOp…

springboot+jsp农产品商城宣传网站设计与实现oo6e3

在该在线助农系统设计与实现中&#xff0c;idea能给用户提供更多的方便&#xff0c;其特点一是方便学习&#xff0c;方便快捷&#xff1b;二是有非常大的信息储存量&#xff0c;主要功能是用在对数据库中查询和编程。其功能有比较灵活的数据应用&#xff0c;只需利用小部分代码…