MySQL基础知识(万字实例详解)

一、什么是MySQL?

首先,MySQL是最常用的关系型数据库操作语言,其次,MySQL是一个客户端服务器,主要实现客户与服务器之间的交互,我们平时的消费记录、收到的vx消息等都是通过数据库相关产品来操作,而MySQL便是用来操作数据库的一种最常用语言,话不多说,我们直接进入主题!

二、MySQL 常用数据类型

1.字符串类

VARCHAR(n)	   字符/字符串。可变长度。最大长度 n
TEXT           长文本数据 
MEDIUMTEXT     中等长度文本数据 
BLOB           二进制形式的长文本数据                //varchar最为常用                      

2.数值类

BIT[ (M) ]    M指定位数,默认为1
TINYINT       1字节整形  
SMALLINT      2字节整形
INT           4字节整形
BIGINT        8字节整形
FLOAT(M, D)   4字节   单精度,M指定长度,D指定小数位数。会发生精度丢失
DOUBLE(M,D)     
DECIMAL(M,D)   M/D最大值+2  双精度,M指定长度,D表示小数点位数。精确数值
NUMERIC(M,D)   M/D最大值+2DECIMAL一样 

注意:可以指定无符号型unsigned

3.日期类型

DATETIME	8字节  范围从10009999年,不会进行时区的检索及转换。YYYY-MM-DD XX:XX:XX
TIMESTAMP    4字节  范围从19702038年,自动检索当前时区并进行转换。

三、基本操作

1.MySQL语句常识

  • 巨大多数MySQL语句后需要加;我们在使用时无脑用;就行
  • MySQL指令不区分大小写,怎么舒服怎么来
  • 为提高可读性,我们要善用空格分开书写
  • MySQL通常用- - 来进行注释,也可以使用#

2.学前必知——基础操作

库层次操作

SHOW DATABASES;                                    //显示所有数据库
CREATE DATABASE [IF NOT EXISTS] 库名;         //创建数据库(if语句:查找数据库,如果有,则不创建,可以省略)
USE  数据库名                                      //使用数据库
DROP DATABASE [IF EXISTS] 库名;                    //删除数据库
//这里比较简单,就不做实例演示啦~~~

表层次操作

show tables                                           //查看当前库里的表
desc  表名                                                 //查看表结构
drop  table [if exists]  表名;                            //删除表

3.进入正题——增删查改

创建表
在增删查改之前我们得先有一张自己的表,我们在这里以创建student表为例,语法如下:

create table + 表名 + (属性名称 属性类型,名称 类型,名称 类型...//创建

实例如下:
在这里插入图片描述
解释: 先选择我们要操作的库,我们这里是在text库里创建表,因此我们先进入数据库,然后通过create语句创建一个具有属性id、name的student表~

插入数据——增

当我们创建好一张表的时候,他是一张空空荡荡的表,这时候就需要我们来插入数据,来让数据库发挥他的作用——存储以及管理,对于插入,主要使用的插入语句如下:

insert into 表名 values (值,值...);                                               //全表插入
insert into 表名 (列名,列名....) values (1,值2....//指定列进行插入
values+多个括号,括号之间要用,隔开                                               //一次插入多行

实例如下:在这里插入图片描述
注意: 当我们针对表中某列插入时,未赋值的列会有一个默认值NULL,这个默认值是可以修改的,我们后续介绍;

查询数据——查

要说MySQL最重要的是什么,那查询是当之无愧的,只有用户能查找,看到这些数据,这些数据才会有价值,同时查询也是MySQL里最重要的且多变的语法,那么我们来一起看吧,查的基础语法如下:

select * from 表名                                                //查询全表  通配符*表示所有的列
select 列名,列名  from 表名                                      //指定表中的列进行查询
//查询时可以对列进行运算,比如列+10,列1+列2....          //表达式查询(只在显示查询结果时生效一次,不会改变我们存储的值)
selectas 别名,列 as 别名  from 表名                          //查询时指定别名,可以但不推荐省略as 

我们刚刚对student表进行了插入操作,接下来我们进行实例一下查询操作:
在这里插入图片描述
说明: 如此的查询肯定是不能满足我们日常的查询需求,因此我们会衍生许多子句来帮助我们的查询操作,比如where、group by等等数种子句帮助我们查询以及下文的修改,更多查询操作我们在下文介绍,本文较长,请大家耐心看完~

修改数据——改

我们存储的数据说白了就是一种信息,这种信息绝大多数是随时改变的,这时候我们就需要重新修改之前那些过时的数据,修改数据的语法如下:

update 表名 set 列名=修改值,...   where/order by/limit等子句               //修改
//修改超出范围SQL会报错,且不生效
//修改小数点位数不够会发生截断(四舍五入)

在这里插入图片描述
解释 这里表示根据id=2这个条件去修改name=xxx,where表示条件查询子句,我们先了解修改语法即可,我们会在后续详细介绍~

删除数据——删

有些数据会因为时间等的推移变得不再有意义,我们需要进行删除,具体语法如下:

delect  表名  from  子句                                            //删除操作某行或者整张表

删除操作同修改操作,都需要where/order by/limit等子句来协助使用,我们在下文查询详细介绍!

四、再看查询

1.查询常用关键字

去重——distinct

select distinct 列名 from 表名                                                    //去重查询,重复的行只保留第一个
//distinct 指定多个列时要求值都相同才视为重复

实例:在这里插入图片描述

说明 这里是基于我们之前的student表新增了一个id=5,name=wangwu的数据,我们用distinct对name列去重,结果表里只显示一个wangwu,值得注意的是,这些操作都是在结果表上的操作,不是对存储的数据进行的修改~

别名——as

selectas 别名,列 as 别名  from 表名                          //查询时指定别名,可以但不推荐省略as 

在这里插入图片描述

模糊查找——like

.like     模糊查找                                  //%算该位置处放0~n个字符模糊查找,_算该位置处一个字符 

在这里插入图片描述

2.逻辑运算符与条件运算符

运算符操作主要是使用在where、having等子句(后续都会介绍)中,如果结果是真也就是TURE(1),则会出现在结果表中,反之则不会出现!

逻辑运算符

AND: 多个条件必须都为 TRUE(1),结果才是 TRUE(1)
OR : 任意一个条件为 TRUE(1), 结果为 TRUE(1)
NOT : 条件为 TRUE(1),结果为 FALSE(0)

注意:优先级and要大于or,同时使用时,需要使用小括号()包裹优先执行的语句,以防错误使用

算术运算符

">, >=, <, <= "" 大于,大于等于,小于,小于等于
= :等于,NULL 不安全,例如 NULL = NULL 的结果是 NULL
<=>: 等于,NULL 安全,例如 NULL <=> NULL 的结果是 TRUE(1)
!=, <>: 不等于
BETWEEN a0 AND a1: 范围匹配,[a0, a1],如果 a0 <= value<= a1,返回 TRUE(1)
IN (option, …) "如果是 option 中的任意一个,返回 TRUE(1) IS
NULL:是 NULL
IS NOT NULL: 不是 NULL
LIKE :模糊匹配。% 表示任意多个(包括 0 个)任意字符;_ 表示任意一个字符,前文已经介绍

3.查询排序——order by

我们有时候需要使查询得到的结果有序,以便于实现我们的需求,于是MySQL提供了order by来实现对结果的排序
语法如下:

-- ASC 为升序(从小到大)
-- DESC 为降序(从大到小)
-- 默认为 ASC
select */列名,列名... from 表名  order by 依据排序的列 [ASC/DESC];         //null在比较大小时默认是最小的~

我们另外创建一个含有成绩的学生表,以便于展示,实例如下:
在这里插入图片描述
说明 :我们先展示我们新创建的学生表,然后使用grade列**默认asc排序(升序)查询,可以看到结果是从上到下依次递增,第二张结果表表则是指定desc(降序)**查询,也符合我们的需求实现~

不该错过的细节——指定多列排序

在这里插入图片描述

说明 :这张结果表我们选择id为主列(写在前面的列比写在后面的列优先级高,因此id为主列),因为id之间排序好后,没有相同的id列,不需对次列进行排序,所以结果表中,尽管我们用id,grade两个列排序,但只有主列id列有序,次列grade还是无序的

4.条件查询——where

条件查询可以说是最关键的一种查询方法,不管是在查询时,还是在修改以及删除时,我们都在前面的篇度中已经见过where,相信大家也多少对他的作用看出点门道了,我们来详细查看他的使用吧~首先,语法如下:

select */列名,列名... from 表名  where 判断条件语句;   //这里的条件语句就是前边的运算符组成的语句,真则选择展示到结果表中
//这里要注意null与任何表达式计算结果都是null,因此用专用的<=>以及<>来判断是否值为空,才能使判断有意义

实例如下:
在这里插入图片描述
我们在这里举一些使用其他语句例子:

-- 查询语文成绩在 [80, 90] 分的同学及语文成绩
SELECT name, chinese FROM student WHERE chinese BETWEEN 80 AND 90;
-- 查询数学成绩是 58 或者 59 或者 98 或者 99 分的同学及数学成绩
SELECT name, math FROM student WHERE math IN (58, 59, 98, 99);
-- % 匹配任意0~n字符
SELECT name FROM student WHERE name LIKE 'z%';
-- 查询 qq_mail 已知的同学姓名
SELECT name, qq_mail FROM student WHERE qq_mail IS NOT NULL;

篇幅原因,一一展示的话可能会导致篇幅太长,我们就不截图展示了,以上语句都是博主实验过得,绝对正确!

where子句执行规则

其次,where子句的判断条件语句不能使用别名,这个对很多刚入坑的小白来说非常不友好,不能使用是因为执行where子句规则如下:

  • 首先:会遍历表的每一行
  • 其次,把遍历到的每一行带入where子句中进行判断
  • 最后,把结果为真的列带入select进行相关的列进行查询或者相关操作

5.分页查询——limit

分页查询——简单实用

我们在日常生活中,一张表不可能展示所有的信息,我们就会分成一页一页的表格去查询,为实现这个需求,我们用得是limit语句实现,语法如下:

//默认从 0 开始,筛选 n 条结果
SELECT ... FROM 表名  LIMIT n;
// 从 s 开始,筛选 n 条结果
SELECT ... FROM 表名  LIMIT s, n;
// 从 s 开始,筛选 n 条结果,比第二种用法更明确,建议使用
SELECT ... FROM 表名  LIMIT n OFFSET s;

实例如下:
在这里插入图片描述

==说明:==第一张结果表是默认从0下标开始分页查询,第二张结果表则是从1下标开始查询两个结果;

6.使用必备——子句的连续使用

有时候单一的查询方式不能实现我们多方面的需求,因此我们管where、limit以及order by为子句,配合select来使用,当然偶尔也会配合update、delect来使用,一个主旁边自然可以有多个子,我们规定使用顺序如下:

SELECT ... FROM 表名 [WHERE ...] [ORDER BY ...] [LIMIT ...];
UPDATE 表名 SET 列名=xx,列名=xx [WHERE ...] [ORDER BY ...] [LIMIT ...];
DELETE FROM  表名 [WHERE ...] [ORDER BY ...] [LIMIT ...]

执行顺序

目前我们掌握的查询有关关键字执行顺序from——where——select——distinct——as——order——limit;
这也说明,where不能使用别名,而ordery可以使用

五、进阶必备知识

1.常用约束一览

我们要存入数据,从管理上来说也是必须要遵守一些规则,比如一个学生有且仅有的就是学号,成绩可以未知,但学号姓名等确实必须知道的,因此数据库制定了约束,他代表我们针对数据库里的数据能写啥,做出的一组“检验规矩”

:这里以sql5.7举例,不同版本可能略有不同,例如:sql5.7不支持check约束

  • NOT NULL - 值非空。
  • UNIQUE - 唯一值。
  • DEFAULT - 默认值。
  • PRIMARY KEY - 主键 (not null + unique)
  • FOREIGN KEY - 外键

以下实例都是先删student表,然后根据约束内容重新创建一个有约束的student表!!!

非空约束——NOT NULL

NOT NULL:选定的列在新增数据时要求不能为空 ,用法举例如下:

//要求在填入学生信息时,id为必填项 其他项为选填项
CREATE TABLE student (
   id INT NOT NULL,
   sn INT,
   name VARCHAR(20),
   qq_mail VARCHAR(20)
);

实例如下:
在这里插入图片描述
说明:第一次插入时没有插入被设置了非空约束的id列,插入报错1364,错误信息如图也很明显,是因为id列引起的,第二次插入id,即使是未插入qq_email列也不会报错,而qq_email列被填入默认值null

唯一约束——UNIQUE

我们在日常生活中,一些数据是为了唯一的去标识某事物,比如人民币编码、身份证号码、学号等等,这些数据在新增时要求不能重复已经有点,因此我们用unique来约束这一项增加操作,用法举例如下:

CREATE TABLE student (
 id INT NOT NULL,
 sn INT UNIQUE,
 name VARCHAR(20),
 qq_mail VARCHAR(20)
);

用法类似not null,我们就不过多叙述

默认值约束——DEFAULT

当我们在统计一些无法准确获得的数据时,null有时候不能很好地表述特征,例如,学生表插入时,如果有班级职务一览,我们可以设置未填就默认普通学生等等,便于我们管理,而我们的MySQL已经默认未填的默认值为null,同时提供default来修改默认值
用法举例如下:

CREATE TABLE student (
 id INT NOT NULL,
 sn INT UNIQUE,
 name VARCHAR(20) DEFAULT 'unkown',
 qq_mail VARCHAR(20)
);

实例如下:
在这里插入图片描述
说明: 这里设置默认name增加数据时未填为unknown

主键约束——PRIMARY KEY

学到这里你有没有尝试同时使用前三种约束呢?当然前两种约束和第三张约束在逻辑上就无法一起使用,只有非空约束以及唯一约束才有同时使用的可能,而sql提供的下一种主键约束其实就是not null + unique 的结合版,用以确保某列(或两个列多个列的结合)有唯一标识,这样有助于更容易更快速地找到表中的一个特定的记录。具体使用方法举例如下:

CREATE TABLE student (
 id INT PRIMARY KEY,
 name VARCHAR(20)
);

主键要求唯一,且不能为空,可以一个列作为主键,也可以多个列作为主键(复合主键)

我们看下列运行结果:
在这里插入图片描述
解释 这里可以看到是先创建了一个student表,其中id设置为主键,当我们指定列插入时,id为插入数据,报错代码1364,以及重复插入id相同列时报错1062,进一步说明他是not null与unique的结合版~

自增主键:有的时候数据量大,而我们用的主键是以数字递增排列,我们就想着有没有一种语法可以让他自己就给主键编号,于是万能的SQL提供了自增主键:

// 从前一个序号开始+1作为下一个新增数据的主键内容添加,如果是第一个数据则从1开始
//我们在书写代码时,可以在添加主键时书写null,系统就自动实现主键的添加了
//如果不希望新插入的以自增方式添加,可以忽略自增主键,当普通主键手动添加~
id INT PRIMARY KEY auto_increment,

在这里插入图片描述
在这里插入图片描述

外键约束——FOREIGN KEY

我们在创建学生表时,难免会插入课程之类的相关内容,而这类内容我们不是凭空而添加,我们必须确保添加的有意义,比如另外有一个课程类,我们学生表在添加的过程中就必须保证添加的课程列属于课程表,当然需求远不止如此,因此诞生了外键约束foreign key,语法如下:

foreign key (字段名) references 主表()

下面举一个实例

//关于外键约束语法举例如下:
eg:
CREATE TABLE classes (
id INT PRIMARY KEY auto_increment,
name VARCHAR(20)
);
//插入数据,让classes表非空,不然其他表不能与空表建立外键约束
insert into classes values(null,'mysql');
//创建含有外键约束的student表
create table student (id int primary key,
 class_id int,
 foreign key (class_id) references classes(id)
 );

在这里插入图片描述
解释:在我们创建好好相应表后,为student表增添数据时,第一次插入的class_id在classes表中id列未找到相同的,因为外键约束作用,增加失败,详情我们可以看报错信息,第二次student表增添数据时,student表的class_id列在classes表中id列找到了相同的,因此满足外键约束,可以添加!

关于外键约束的一些说明:

  • 建立外键约束的表称为子表,例如:student表受到class表约束,则class表为student表的父表,反之为子表
  • 父表与子表的约束是相互的,子表非空时,父表不能被删除,小伙伴们可以去尝试一下
  • 子表建立约束时,父表不能为空,否则会报错

2.聚合函数查询

我们有时候需要一些特定的方式去查询,比如一个班20个同学,我们知道这20个同学的成绩,如何快速的得出班级的平均分、最高分等等,聚合查询:查询过程中,表的行和行之间进行一定的运算,依赖聚合函数, MySQL提供了的这种叫做聚合函数的语法来协助我们查询,聚合函数主要有以下几种:

COUNT([DISTINCT] expr) 返回查询到的数据的数量
SUM([DISTINCT] expr) 返回查询到的数据的 总和,不是数字没有意义
AVG([DISTINCT] expr) 返回查询到的数据的 平均值,不是数字没有意义
MAX([DISTINCT] expr) 返回查询到的数据的 最大值,不是数字没有意义
MIN([DISTINCT] expr) 返回查询到的数据的 最小值,不是数字没有意义

聚合查询使用实例

创建一个包含学生数学信息的表:
在这里插入图片描述
插入信息:
在这里插入图片描述
依次使用聚合函数查询:

在这里插入图片描述
注意事项:

  • select count(*/列名) from 表名 如果使用列名,则对应列为null的不会算到数量和里
  • sum操作类似count,sum相加时会跳过null 其余针对数字的聚合函数也类似
  • 使用聚合函数时,要注意函数名与()之间不能有空格
  • 聚合函数默认聚合的是全表,可以使用group by 子句,进行部分表运算,接下来就会讲到group by子句

3.查询子句的再介绍

分组查询——group by

分组查询主要作用是:将相同列的分到一个组,比如比较男女生的语文成绩平均分,我们将男生分为一组,女生分为一组~
关于分组查询有以下说法:

SELECT 中使用 GROUP BY 子句可以对指定列进行分组查询。需要满足:使用group 子句时,select 后跟的列名必须带有聚合函数或者指定的group by 的列,否则查询得到的结果无意义,我们可以想一想为什么没意义~

分组查询类似条件等查询,语法上较为相似,:

select ... from ... group by 列名  //将列中相同的分到一个组~~

实例如下:
我们先创建一张新的学生表,已经插入数据,此处表如下:
在这里插入图片描述
我们需要查询男生与女生数学成绩的平均分分别为多少,如下:
在这里插入图片描述

含有条件查询的group by子句——HAVING、WHERE

having:

这是一个专门和group by 搭配的子句,其作用类似于where

我们可以在分组前先进行条件查询,将查询得到的结果进行分组;也可以先分组,在分组的结果里进行条件筛选,也可以条件1——分组——条件2;以上我们使用where、having、group by来实现,我们举例如下:

//条件筛选——分组      
where 子句 group 子句
//分组————条件筛选
group 子句 having 子句  
//条件筛选1——分组——条件筛选2        
where 子句  group 子句  having 子句       

我们继续再上一张表新增数据:
在这里插入图片描述
查询成绩大于60的男女生的平均成绩:
在这里插入图片描述
查询男女生的平均成绩大于70分的平均成绩:
在这里插入图片描述
查询成绩大于60的男女生的平均成绩,再查其平均分大于80的平均分数:
在这里插入图片描述

六、查询重头戏——表的联合查询

在我们实际的生活中,一张表不可能解决所有问题,往往需要几张表的联合使用,于是根据笛卡尔积诞生了一种叫做联合查询的查询方式也可以叫做多表查询,笛卡尔积用下图理解:
在这里插入图片描述
注:关联查询可以对关联表使用别名。

//m*n行,m+n列;
select * from1,表2

1.内连接

内连接:表示的结果集为两张表的交集,其语法如下:

//多表查询会有部分数据无效,利用 where子句来使表有意义,若两表列名重复,需要表名.列名的方式来访问 
//多表查询中:表1 join 表2 on 连接条件 join 表2 on 连接条件  等价于where子句
select 字段 from1 别名1 [inner] join2 别名2 on 连接条件 and 其他条件;
select 字段 from1 别名1,2 别名2 where 连接条件 and 其他条件

我们先准备数据,如下:
在这里插入图片描述
用where查询成绩:
在这里插入图片描述
用join on 查询成绩:
在这里插入图片描述

2.外连接

外连接分为左外连接和右外连接。如果联合查询,左侧的表完全显示我们就说是左外连接;右侧的表完全显示我们就说是右外连接。 主要语法如下:

// 左外连接,表1完全显示
select 字段名  from 表名1 left join 表名2 on 连接条件;
// 右外连接,表2完全显示
select 字段 from 表名1 right join 表名2 on 连接条件;

查询成绩及同学的个人信息,如果该同学没有成绩,也需要显示
在这里插入图片描述
多张表联合查询: 以3张表举例,先考虑左中得到的临时表,在临时表与右进行外连接

3.自查询

自查询:自己与自己做笛卡尔积;主要目的:我们的操作都是执行在列上的,把行换成列有利于我们的查询。
就以上述表为例:查询math成绩比mysql成绩低的同学:
在这里插入图片描述
说明: 因为笛卡尔积的性质,我们需要利用
distinct
做去重处理

4.子查询

子查询说白了就是套娃查询,指嵌入在其他sql语句中的select语句,也叫嵌套查询

  • 单行子查询: eg:select 语句 查询子句[列名 = (select语句)] //注意可读性,善用()
  • 多行子查询:where 列 in (select语句)

比如我们在不知道同学名字的情况下查询math=58的同学的mysql成绩:
在这里插入图片描述

5.合并查询

**合并查询:**将多次查询的结果合并为一张表,类似or但作用范围广。注意:使用union和union all时,前后查询的结果集中,字段需要一致。

  • nuion:自动去重重复列
  • union all:不会自动去重
  • union 针对多张表进行查询且自动去重,or只能针对一张表

比如,从上述student表与grade表查找id<2或者math>60的同学名字
在这里插入图片描述

使用不去重的结果表:
在这里插入图片描述

七、还需说明的一些事项

1.如何在SQL里输入汉字

数据库默认字符集"拉丁文",不能表示汉字, 通过创建库时:建库语句+ charset utf8 来匹配

2.SQL的安全性

简单来说,SQL没有安全的操作,在工作中使用需要谨慎,在学习中也有可能因为删除等操作奔溃~

3.int(11)是什么

int(11)                     //表示int型,在查询时最多显示11个字符,与存储无关

4.SQL执行顺序总览——重点

这个是比较重要的,知道了执行顺序才能正确的使用SQL,执行顺序大概如下:
from ——on ——join ——where ——group by(开始使用select中的别名,后面的语句中都可以使用)—— 聚合函数——having ——select ——distinct ——order by——limit

八、最后的最后

很感谢大家看到了这里,SQL的使用我们掌握这么多基本就是结束了,但是大家一定还好奇网上是如何用Java、c++等语言来使用mysql吧,关于这些,博主会在后续更新JDBC编程,以及会拓展mysql的索引与事务相关以及利用多线程等完成mysql底层的一些操作,不妨关注博主,我们一起期待mysql后续精彩内容~

猜你喜欢

转载自blog.csdn.net/m0_65038072/article/details/130226306