草庐IT

【MySQL】数据库中表的增删查改操作详解

安苒_ 2023-04-21 原文

文章目录

前言

对于表,据我目前了解的情况而言,实际开发中常见的操作也是增删查改,也就是经常说的CURD。【create增、update改、retrive改、query查】但是可能会跟我们想象的有所出入,具体看下边的解释。

增加操作:也就是创建表、以及如何向表中增加记录

删除操作:也就是删除整张表,或者删除已经插入的记录

查询操作:也就是查询数据库中是不是有这张表,或者这张表中有没有我们想要的记录

更改操作:按照我们所想的,应该有对表名更改的操作、对表中字段名更改的操作、对表中已经插入的记录更改的操作,但是由于实际开发中“对表中已经插入的记录更改”这一操作使用的比较少,所以我们这里重点介绍前边两种更改操作。

【使用的mysql服务器为5.7版本】

为了方便理解,我们这里整篇文章均围绕下边这个例子来讲解。

SQL的通用语法

  1. sql语句以分号为结尾

  2. 可以通过过缩进和空格增强可读性

  3. 不区分大小写

  4. 注释:单行注释用–(减号)或者#(井号),多行注释用/**/

    --  第一种单行注释
    # 第二种单行注释
    /*
    多行注释
    */
    

一、表的创建与表的新增

语法

创建表

#创建表操作
create table [if not exists] tableName(字段名1 类型,字段名2 类型……)[comment '……'];
#新增记录操作
#第一种对所有列插入一条数据
insert into table_name values(1,值2……);
#第二种,对指定列插入一条数据,
insert into table_name(属性1,属性2……)values(1,值2……);
-- 补充未插入的列为默认值,不指定为Null【怎么设置默认值,在约束的地方会讲】

#第三种,一次插入多条数据
insert into table_name values(1,值2……),(1,值2……)……;

说明:

  1. 创建表最简单最常用的书写方式为create table tableName(字段名1 类型,字段名2 类型……);
  2. 插入记录使用比较多的是第一条和第三条。
  3. comment+引号表示的意思是注释,我们可以为整张表添加注释,也可以为表中的单个字段添加注释。【字段也,简而言之就是列名】
  4. if not exists跟它的中译的结果差不多,就是如果不存在的话创建这个表。但是由于这个子句主要起着检查的作用,我们很多时候在创建表的时候就已经知道它是否存在了,所以就很少用。
  5. 另外,对于容易写错的sql语句,除了直接在客户端的命令行窗口写,我们还可以通过记事本比如windows自带的记事本或者sublimeText、idea等来写,之后再复制到命令行上边。

数据类型的介绍

整体语法我们知道的差不多了,我们具体看看表中的内容怎么写。可以看到我们要想成功创建出来一张表,就必须先知道它的数据类型。那么sql中到底有哪几种数据类型呢?主要有数值类型、字符串类型、日期类型,这些我们详细讲,当然除此以外很多类型比如复合类型、二进制类型,这里我们作为补充知识了解即可。

下边的了解即可

当然,对于这些数据类型,我们并不建议背,而是通过具体的实践来掌握。

说明

  1. 可以看到对于字符串类型我们是需要指定字符的个数的。这里我们是采用尝试的方法尝试出来的,具体工作中会有产品经理进行约束。
  2. 一般来讲,对于钱我们要求的比较高,不会像实际生活中用浮点数表示,而是通过整形存储到底有多少分【元–》分】

演示

看到Query OK……就算是创建成功了。

下边,我们借助查询语句select * from 表名来看看效果。

这里,我想提几个初学者容易犯的错误

  1. 日期类型是date不是data
  2. 建表语句中,最后一个字段后边没有逗号

二、表的删除

语法

删整张表的语法

drop table [if exists] table_name;

删记录的语法

delete from table_name [where 条件子句];

说明

  1. 与建表语句是一样,虽然有if exists这个用法,但是实际应用应用中很少用到。
  2. 删表语句这里涉及到where子句的用法,我们在表的查询那里会具体讲。

演示

因为表记录的删除的前提是首先这个表需要有记录,不是空表,所以这个我们会在讲完表记录的增加和修改之后,一起进行演示。

这里主要演示表的删除,把刚刚建好的那张表删除。

三、表的查询

查询使用的结构是select ……from。查询一般分为单表查询和多表查询,而单表查询和多表查询本身又分为很多种,相较于单表查询,多表查询会比较稍微复杂一点,这里我们先学习单表查询,先用起来,之后再进阶学习。

特别注意:查询的结果都是临时表!!!

查询整张表

语法:desc 表名;

这里的desc是英文describe描述的缩写

下边是对表中记录的查询。

(一)全列查询

语法:select * from 表名;

(二)指定列查询

语法:select 列名/列名序列 from 表名

(三)带表达式的查询

语法:select (列名,/列名序列)表达式/表达式序列 from 表名;

(四)带别名的查询

语法:select 表达式/列名 as 别名 from 表名;

除了可以给表达式/列名起别名,我们还可以给用聚合计算表达式起别名,还可以给表起别名,这些我们具体用到的时候再进行解释。

其中as关键字可以省略,但是考虑到语句的可读性,我们并不建议省略as关键字。

(五)去重查询

语法:select distinct 字段名 from 表名;

一般来讲,我们去重就是针对某列对查询出来的记录进行去重。

(六)排序查询

语法:select 列名/列名序列 form 表名 order by 字段名 asc/desc;

如果不指定排序规则,默认是升序。

这里的asc是英文ascend上升的缩写,desc是英文descend下降的缩写,注意与查询表的desc进行区别。

(七)条件查

条件查询使用的关键字是where,where放在表名的后边,where后边跟上条件子句。

语法:select 列名(序列)/表达式(序列) from 表名 where 子句(序列);

在正式介绍条件查询之前,我们先介绍条件查询需要用到的几种运算符,分别是比较运算符、逻辑运算符。

比较运算符

运算符说明
=等于,判断字段之间的值是否相等,但是NULL不安全
<=>等于,判断字段之间的值是否相等,NULL也安全
is null是NULL
is not null不是NULL
>=,<=,>,<大于等于、小于等于、大于、小于
!=,<>不等于
between a and b范围匹配,[a,b],在范围,结果为true
like模糊匹配,%匹配任意个字符,_严格匹配一个字符

逻辑运算符

运算符说明
and同时为true才为真
or任意为真则为真
not值本身为false才为真

基本查询

查询年龄小于等于18岁的员工信息

查询年龄大于等于18岁的女员工信息

范围查询

查询年龄在18到25岁之间的员工的信息

模糊查询

语法:select 列名 from 表名 like '条件%条件';

select 列名 from 表名 like '……_……';

*使用like关键字,%可以模糊0或者多个字符,只能模糊并严格匹配一个字符。

这里为了方便演示,我再插入一条杨过的记录。

首先,我们来看_的例子【严格匹配一个字符】

其次,我们来看%的例子【匹配任意个字符,包括0个】

null查询

是null:is null、<=>null

不是null:is not null

注意:不能通过!=来判断不是null,这是有sql标准决定的。

查询名字不是null的员工信息

查询年龄是null的员工的信息

(八)分页查询

语法:select * /字段名/字段序列 from 表名 limit 页数 offset 个数;

页数从0开始。

查询年龄第二大的员工的信息

(九)聚合查询

前边的查询都是针对列跟列的,聚合查询时针对同一列中的不同行的元素。

一般聚合查询的时候,我们会用到聚合函数。

注意:

  1. 不可以直接嵌套使用,比如: max(count(*))但是可以嵌套子查询使用(先分组取出count值, 再将count值倒序排列,取第一个值就是最大的)
  2. 对于聚合函数而言,不是数字没有意义
  3. 使用 GROUP BY 进行分组查询时,SELECT 指定的字段必须是“分组依据字段”,其他字段若想出现在SELECT 中则必须包含在聚合函数中
  4. HAVING 可以包含聚合函数。HAVING 子句可以引用选择列表中显示的任意项

关于

四、表记录的修改

语法:update 表名 set 值1=,…… [where条件] ;

注意:

  1. 如果不指定where条件,upadate会修改整张表中的列名。与之类似的是delete不指定条件,也会默认删除整张表中记录。
  2. 这个关键字只能针对表记录中具体具体记录进行修改,不能对表名/列名进行修改。
  3. 如果需要对表名/列名进行修改的话,需要使用alter关键字,但是因为实际开发过程中这个使用的频率并不是特别高,所以我们这里就不介绍了。

将杨过的id改成10,workno改成10,gender改成男,age改成16

一定要指定条件

为了做这个演示,我删表,重新建表了= _ =,下边是正确的更新操作。

除此之外,我们再演示一下,之前没有演示的删除记录的操作。

五、多表查询

我们已经知道mysql是一个关系型数据库,内部是一些有关联的表。那么这些表是怎么联系在一起的呢?

试想,我们如果想要把我们的专业的学生信息以及他们的成绩放到数据库中,我们并不是在任何时候都看到学生的成绩的,那就意味着我们要能够只拿到学生的信息而不包含成绩,而有时候我们又只看成绩,有的时候又只看班级。

此时,我们一般会建立三张表,一张是班级表,里边有班级id和属于这个班级的学生,一张是学生信息表,每个学生的信息又都至少包含一项班级id信息,一张是成绩表,这张表又至少包含了学生的id和对应班级的id。

那么如果不加限制的允许人们往里边输入数据,我们在进行多表查询的时候会不会出错?答案是肯定的。那么我们该怎样解决甚至避免这个问题呢?

这也就是我们接下来要谈的约束的问题,有了约束,表与表之间就会相互制约,过滤掉不符合要求的数据。所以,在正式讲解多表查询之前,我们先来看看什么是约束,约束的用法有哪些?

约束

约束是一种限制,是用来对表中的行或者列做出限制,来确保表中数据的完整性、唯一性

not null约束

作用:使用not null指定列不为空。

效果:再向表中这一列进行插入记录时就不能为空了,否则就会语法错误。

unique约束【唯一键约束】

作用:指定列的值必须是唯一的,不重复的,可以是多个null值。

效果:再向表中这一列进行插入记录时不能和以前的这一列的值重复,否则就会语法错误。

primary key【主键约束】

作用:唯一标识这张表,等价于not null+unique的合体

注意:每个表最多只允许一个主键

除此以外,主键修饰的属性一般是id,我们还会用auto_increment自增约束进行修饰。当插入第一条记录时,自增字段没有给定一个具体值,可以写成DEFAULT/NULL,那么以后插入字段的时候,该自增字段就是从1开始,每插入一条记录,该自增字段的值增加1。当插入第一条记录时,给自增字段一个具体值,那么以后插入的记录在此自增字段上的值,就在第一条记录该自增字段的值的基础上每次增加1。

如果中间插入,断开了(id值),那么就跟枚举一样会随着这个值增长

foreign key约束【外键约束】

语法:foreign key (子表的关联字段) references 主表名(主键/唯一键)

这里的父/主表也就是驱动表,子表也就是被驱动表

效果:①父表对子表有约束作用。生成id不能那么随意②子表其实对父表也有约束作用的。父表不能轻易删除,必须先删子表,再删父表也就是说约束是双向的。③父表必须有唯一键/主键。

注意:这里的括号不可省略

讨论完主键的基本用法,我们来讨论另外一个问题,为什么父表中必须要有主键呢?

原因:每次给子表插入数据时,必然需要再父表查询id是否存在,默认情况下,查询是需要遍历表的,在数据量非常的情况下,遍历的效率非常的低,需要使用索引,这时外键和主键其实就相当于一个索引,加快了查找速度。

对于约束的个数问题,同一个表中主键只能有一个,其他的个数没有限制,同时大部分可以自由组合。

default约束【默认约束】

作用:指定列为空时的默认值,人为规定了就是我们规定的值,没有人为规定就是null

例如:例如:age int default 20

check约束【check约束】

作用:保证列中的值符合指定的条件

例如:sex char check (sex =‘男’ or sex=‘女’)

(一)内连接

语法:

​ 写法一:直接用from 将表名分开

​ 写法二:用表一 (inner) join表二 on条件(join 表三 on条件)

作用:求两个或者多个表的交集

效果:生成表的行数是被连接表行数的乘积,列数是被连接表列数的和。

方式一:

方式二:

(二)外连接

左外连接

语法:

​ 写法:用表一 left join表二 on条件(join 表三 on条件)

作用:左外连接【表一全集并上两个的交集】,

右外连接

语法:

​ 写法:用表一 right join表二 on条件(right join 表三 on条件)

作用:右外连接【表二全集并上两个的交集】

(三)自连接

作用:自连接是指在同一张表连接自身进行查询。

例如:select 表别名.属性 from 表名 as 别名1,表名 as 别名2;

(四)子查询

子查询就是将表的查询结果作为另一个表的来源进行查询。相当于是一个数据查询的小技巧——把一个子查询当做一个临时表使用。

单行子查询:返回一行记录的子查询,可以用=接收

多行子查询:返回多行记录的子查询,可以用(not)in接收。当然也可以用exists,但是这个只有内层查询有结果的时候外层才执行。

(五)合并查询

合并多个查询是合并多个select的执行结果。一般使用union和union all这两种集合操作符比较多。

前提:两个表查询得到的临时表字段是一致的

union:该操作符用于取得两个结果集的并集。当使用该操作符时,会自动去掉重复行

union all:该操作符用于取得两个结果集的并集。当使用该操作符时,不会去掉结果集中的重复行

有关【MySQL】数据库中表的增删查改操作详解的更多相关文章

  1. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  2. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  3. ruby - 我如何添加二进制数据来遏制 POST - 2

    我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_

  4. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  5. FOHEART H1数据手套驱动Optitrack光学动捕双手运动(Unity3D) - 2

    本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01  客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02  数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit

  6. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

  7. ruby-on-rails - 创建 ruby​​ 数据库时惰性符号绑定(bind)失败 - 2

    我正在尝试在Rails上安装ruby​​,到目前为止一切都已安装,但是当我尝试使用rakedb:create创建数据库时,我收到一个奇怪的错误:dyld:lazysymbolbindingfailed:Symbolnotfound:_mysql_get_client_infoReferencedfrom:/Library/Ruby/Gems/1.8/gems/mysql2-0.3.11/lib/mysql2/mysql2.bundleExpectedin:flatnamespacedyld:Symbolnotfound:_mysql_get_client_infoReferencedf

  8. STM32读取串口传感器数据(颗粒物传感器,主动上传) - 2

    文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,

  9. SPI接收数据异常问题总结 - 2

    SPI接收数据左移一位问题目录SPI接收数据左移一位问题一、问题描述二、问题分析三、探究原理四、经验总结最近在工作在学习调试SPI的过程中遇到一个问题——接收数据整体向左移了一位(1bit)。SPI数据收发是数据交换,因此接收数据时从第二个字节开始才是有效数据,也就是数据整体向右移一个字节(1byte)。请教前辈之后也没有得到解决,通过在网上查阅前人经验终于解决问题,所以写一个避坑经验总结。实际背景:MCU与一款芯片使用spi通信,MCU作为主机,芯片作为从机。这款芯片采用的是它规定的六线SPI,多了两根线:RDY和INT,这样从机就可以主动请求主机给主机发送数据了。一、问题描述根据从机芯片手

  10. 微信小程序通过字典表匹配对应数据 - 2

    前言一般来说,前端根据后台返回code码展示对应内容只需要在前台判断code值展示对应的内容即可,但要是匹配的code码比较多或者多个页面用到时,为了便于后期维护,后台就会使用字典表让前端匹配,下面我将在微信小程序中通过wxs的方法实现这个操作。为什么要使用wxs?{{method(a,b)}}可以看到,上述代码是一个调用方法传值的操作,在vue中很常见,多用于数据之间的转换,但由于微信小程序诸多限制的原因,你并不能优雅的这样操作,可能有人会说,为什么不用if判断实现呢?但是if判断的局限性在于如果存在数据量过大时,大量重复性操作和if判断会让你的代码显得异常冗余。wxswxs相当于是一个独立

随机推荐