MySQL一文搞懂MySQL语句(基础篇)

Posted 意愿三七

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL一文搞懂MySQL语句(基础篇)相关的知识,希望对你有一定的参考价值。

mysql

一、 数据库的操作


1.1 显示当前的数据库

大小写都可以!

show databases;

会返回一个默认的数据库,你们新安装的可能和我不一样,我的新建的有数据库;


1.2 创建数据库

主要使用:

create database [数据库名];

还有一个详细版:

CREATE DATABASE [IF NOT EXISTS] db_name [create_specification [, create_specification] …]
create_specification:
[DEFAULT] CHARACTER SET charset_name
[DEFAULT] COLLATE collation_name

说明:

  • [ ]是可选项
  • 大写的表示关键字
  • CHARACTER SET: 指定数据库采用的字符集 (ASCII码表 GBK…)
  • COLLATE: 指定数据库字符集的校验规则

IF NOT EXISTSt :如果数据库不存在就创建,如果数据库存在就什么都不干

MySQL要求,同一个MySQL服务器上,每个数据库的名字不可以重复~
如果一个数据库的名字已经存在,你再尝试创建一个同名数据库,就会报错~
加上IF NOT EXISTSt 即使同名也不会报错.


那么这玩意有没有用呢?

当然,虽然我们现在是一条条SQL语句,一个个写,但是在以后的工作中,更常见的是把一些SQL写到一个文件中,然后批量执行。
在批量执行的过程中如果个别SQL语句报错,后面的SQL就不能继续执行了


示列:

  • 创建名为 test 的数据库

1.3 使用数据库

语法:

use 数据库名;

当前可能会有许多数据库,要想具体操作,就需要先选中一个数据库,然后再操作~


1.4 删除数据库

语法:

DROP DATABASE [IF EXISTS] db_name;

示例:

说明:

  • 数据库删除以后,内部看不到对应的数据库,里边的表和数据全部被删除

课外话:

删除操作十分危险,在实际工作中,不应该使用drop命令来删除任何数据库!!!

一般测试数据库,删除问题不大,最多被领导骂一顿
如果你删除的是线上数据库问题可能非常严重!!! 极端情况可能要进去


二、 常用数据类型

2.1 数值类型:

分为整形和浮点型:

数据类型大小说明对于java类型
BIT[ (M) ]M指定位数,默认为1二进制数,M范围从1到64,存储数值范围从0到2^M-1常用Boolean对应BIT,此时默认是1位,即只能存0和1
TINYINT1字节Byte
SMALLINT2字节Short
INT4字节Integer
BIGINT8字节Long
FLOAT(M, D)4字节单精度,M指定长度,D指定小数位数。会发生精度丢失Float
DOUBLE(M,D)8字节Double
DECIMAL(M,D)M/D最大值+2双精度,M指定长度,D表示小数点位数。精确数值BigDecimal
NUMERIC(M,DM/D最大值+2和DECIMAL一样BigDecimal

扩展资料:

数值类型可以指定为无符号(unsigned),表示不取负数。

但是官方文档上面已经明确写了,不建议这样使用.unsigned已被标记为“即将弃用”的状态。

为什么呢? 因为无符号容易溢出

1U - 2U => 变成一个非常大的整数…


介绍一下 FLOAT(M, D)的M 和 D是啥意思

M:有效数的长度
D:指小数位数


实例:
FLOAT(3, 1)
45.6 : 有效数3位 ,小数位一位

插入 4.56非法,插入456也非法~


介绍一下DECIMAL(M,D)

IEEE 754 标准 约定了float和double具体咋存的,导致了有些小数是不能精确表示.
由于这是一个二进制的科学计数法,只能精确表示如:0.5,0.25,0.125,0.375…这类能够精确表示

但是如果通过float或者double表示“钱‘’ 那么可能会遇见 19.99999999998 , 35.0000000002这些数字.


deimal 类型:
优势:能够更精确的表示小数
劣势:付出很多的时间和空间的代价

要是算钱更好的办法使用int代替decimal 或者 double

因为钱一般都是精确到小数点后两位(分)
就直接使用int就行,钱的单位就是分。


2.2 字符串类型

数据类型大小说明对应类型
VARCHAR (SIZE)0-65,535字节可变长度字符串String
TEXT0-65,535字节长文本数据String
MEDIUMTEXT0-16 777 215字节中等长度文本数据String
BLOB0-65,535字节二进制形式的长文本数据byte[]

varchar(size):

size 表示这个字符串的最大长度 单位是字符(不是字节)
varchar(20),此时这个字段里面最大长度就是20个字符

汉字,一个汉字是一个字符 , 但是不一定是一个字节。


TEXT

没有参数 不是用户指定一个长度,会根据用户插入的数据来动态确定占用空间


MEDIUMTEXT :
和上面差不多,大小变大了


BLOB
一些典型的:图片 mp3 ,视频等格式,这些都属于二进制数据。

如果想把图片保存mysql 可以考虑使用blob类型~

blob类型能表示最大的是64kb.

那么图片肯定会超过64kb,如果真的要保存,一般是把图片以文件的形式放到硬盘上,然后在数据库中记录这个图片的路径。


2.3 日期类型

数据类型大小说明对应类型
DATATIME8字节范围从1000到9999年,不会进行时区的检索及转换java.util.Date、java.sql.Timestamp
TIMESTAMP4字节范围从1970到2038年,自动检索当前时java.util.Date、java.sql.Timestamp

这个两个类型也是都是非常常用的类型。用来表示时间日期(年月日时分秒)

timestamp 时间戳

2021年11月21日 17:17:00 日常生活使用一个这样的字符串表示时间日期~~

计算机这样表示吗,非常不方便(占用更多空间,不方便时间/日期的换算)

时间戳:以1970年1月1日0时0分0秒为基准时刻~

有个小知识点:我们这个时间戳类型大小是4个字节,4个字节的表述数据范围是 -21亿 -> +21亿

可以去百度看一下当前时间戳是16亿多,也就是说 2038年这个timetamp类型就使用不了了,

现在我们使用时间戳尽量使用8个字节的版本,不要使用个字节的!!


三、表的操作

需要操作数据库中的表时,需要先使用该数据库:

use 数据库名;

3.1创建表

语法:

create table [表名] (列名1 列类型,列名2 列类型);

使用括号,把若干个列给包裹起来,表名列名随便取,但是要注意不可以和SQL中的关键字冲,比如create,table,drop,show…这些都是具有特殊含义关键字

如果非要使用表名列名为关键字的话,可以通过反引号链接: ``

e:要先选中数据库

可以看见我们创建了一个 haha 表 里面的字段有 id, name


3.2查看表结构

这个可以查看一下你的表结构,比如某个字段是什么类型 等等等等

desc 表名;

示例: 先use 这个数据库 然后在操作,如果不知道怎么看表 使用 show tables; 即可

上面就是 goods表的一个结构;


3.3 删除表

语法:

drop table [表名]

例:

– 删除 stu_test 表
drop table stu_test;
– 如果存在 stu_test 表,则删除 stu_test 表
drop table if exists stu_test;

删表和危险 大家要小心使用!!!


四、表的增删改查(基础)

4.1 CRUD

CRUD 即增加(Create)、查询(Retrieve)、更新(Update)、删除(Delete)四个单词的首字母缩写

大家以后不要老是嫌弃公司的CRUD,这个是最基本的,我们还是要掌握的~~


4.2 新增(Create)

[ ] : 可有可无

语法:

INSERT [INTO] table_name [(column [, column] …)] VALUES (value_list) [, (value_list)] …

(1)单行数据 – 全列插入

案例:
为什么叫单行,是因为 省略了表名后面的列但是插入的数据要有多少列插入多少数据

括号里面的数据要和列名一 一对应,列的数目要一致,类型要匹配, 上面的 1 是id,zahngsan是name, SQL中 单引号和双引号都是字符串。

如果插入中文报错请看这个篇文章:

永久解决mysql插入中文报错

(2)多行数据 – 全列插入

多行是指数目? 来看看下面的操作吧!

语法:

– 插入两条记录,value_list 数量必须和指定列数量及顺序一致
INSERT INTO student (id, sn, name) VALUES
(102, 20001, ‘曹孟德’),(103, 20002, ‘孙仲谋’);

当我们指定了插入具体的列,如果数量不对应,就会发生报错

一一对应才可以成功:

那么没有插入的位置是什么数据呢?
这里id默认是null,所以里面是null

上面是一个语句可以插入多个数据,那我们可不可以使用多个sql插入呢?答案是可以的。

但是咱们一般认为,一条语句,一次插入多个记录,效率要比多个语句每个插入一条记录要高很多。

课外话:

  • 因为mysql是一个“客户端” “服务器”结构的程序 .用户在客户端输入的sql都会通过网络传输给服务器,由服务器来进行具操作~~


多个sql语句就会占用资源,越来越慢所以就是这个原因


4.3 查询(Retrieve)

4.3.1 全列查询

语法:查找所有的数据(所有的行和列)

查询语句有点多先讲最基本的

select * from 表名

案例:

这里可以看见刚刚使用插入语句也已经插入进去了

要注意:这个查询的结果是一个类似于"表"这样的结构,但是这这个表,是一个“临时表”,这个表仅仅是在内存里存了一下,接下来就打印,打印完了就没有了,不会持久化存储。

这个操作,如果在生产环境中,一定要注意使用,因为有可能数据太大了,拖慢服务器。

如果这些操作执行了,可以使用ctrl+c 终止操作~~


4.3.2 指定列查询

语法:

select [列名], [列名] from [表名];

案列:

这个比上面的那种要 好一点 ,但是还是架不住数据太大,所以要看下面的


4.3.3 查询字段为表达式

比如我们要查上面表的一个所有数据
语法:

– 表达式不包含字段
SELECT id, name, 10 FROM exam_result;
– 表达式包含一个字段
SELECT id, name, english + 10 FROM exam_result;
– 表达式包含多个字段
SELECT id, name, chinese + math + english FROM exam_result;

select name, chinese+math+english from exam_result;

结果就是三列相加,每一行的三个列相加~相加的结果不会影响到原来的结果。以上是针对列的操作。


4.3.4 别名

为查询结果中的列指定别名,表示返回的结果集中,以别名作为该列的名称,语法:

select [列名] [ as ] [ 别名] from 表名

案列:

也可以省略 as


4.3.5 去重:DISTINCT

针对某个指定的列,把相同的值的记录给去重~

– 98 分重复了 2个98
SELECT math FROM exam_result;
±-------+
| math |
±-------+
| 98 |
| 78 |
| 98 |
| 84 |
| 85 |
| 73 |
| 65 |
±-------+
7 rows in set (0.00 sec)

加上去重:

只有一个98.0

去重操作也可以针对多个列来去重。
不过要去重多个列的时候,要保证他们都一样

select distinct math,english from exam_result;


可以看见这个上面没有去重因为英语那一列不一样。


4.3.6 排序:ORDER BY

语法:

– ASC 为升序(从小到大)
– DESC 为降序(从大到小)
– 默认为 ASC
select … from 表名 order by 列名 【desc】;

1.没有 ORDER BY 子句的查询,返回的顺序是未定义的,永远不要依赖这个顺序

  • 什么意思呢?比如你查一下id 发现是 1 ,2 ,3 ,4 ,5 你认为他顺序的对的,是升序,但是不一定,如果后面进行了修改表,可能顺序就变了。
  1. NULL 数据排序,视为比任何值都小,升序出现在最上面,降序出现在最下面


3. 使用表达式及别名排序

查询同学及总分,由高到低

语句一:
SELECT name, chinese + english + math FROM exam_result
ORDER BY chinese + english + math DESC;

语句二:
SELECT name, chinese + english + math total FROM exam_result
ORDER BY total DESC;


4.可以对多个字段进行排序,排序优先级随书写顺序

查询同学各门成绩,依次按 数学降序,英语升序,语文升序的方式显示

SELECT name, math, english, chinese FROM exam_result
ORDER BY math DESC, english, chinese;


4.3.7 条件查询:WHERE

条件查询适用范围非常广,一个SQL语句可以使用where 找到满意的结果。

where 后面跟上一些条件表达式,相当于一个“筛选的过程”

比较运算符:

运算符说明
>, >=, <, <=大于,大于等于,小于,小于等于
=等于,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 NULLNULL
IS NOT NULL不是 NULL
LIKE模糊匹配。% 表示任意多个(包括 0 个)任意字符;_ 表示任意一个字

逻辑运算符:

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

注:

  1. WHERE条件可以使用表达式,但不能使用别名。
  2. AND的优先级高于OR,在同时使用时,需要使用小括号()包裹优先执行的部分

案列:

1. 查询英语不及格的同学及英语成绩 ( < 60 )

注意体会执行过程:执行select的时候就会先尝试遍历表中的每一条记录~ 遍历的时候会把当前的记录带入到比较条件中,来看看条件是否成立(true成立 false 不成立)放到结果的临时表里,不成立的直接pass

2. 查询语文成绩好于英语成绩的同学

SELECT name, chinese, english FROM exam_result WHERE chinese > english;

条件查询是很方便的进行列和列之间的比较的~(同一行数据)

3. 查询总分在 200 分以下的同学

where后面不可以使用as

4. 查询语文成绩大于80分,且英语成绩大于80分的同学

SELECT * FROM exam_result WHERE chinese > 80 and english > 80;

5. 查询语文成绩大于80分,或英语成绩大于80分的同学

SELECT * FROM exam_result WHERE chinese > 80 or english > 80;

注意:and 比 or 优先级高一点

范围查询:

BETWEEN … AND …

  1. 查询语文成绩在 [80, 90] 分的同学及语文成绩

使用大于小于也可以 效果一样
有人会想,既然可以搞,为什么要between and ,因为这个是一个高频的操作,我们要想SQL引擎可以很好的优化


IN

  1. 查询数学成绩是 58 或者 59 或者 98 或者 99 分的同学及数学成绩

    SELECT name, math FROM exam_result WHERE math IN (58, 59, 98, 99);


模糊查询:LIKE

% 匹配任意 多个(包括 0 个)字符

SELECT name FROM exam_result WHERE name LIKE ‘孙%’;-- 匹配到孙悟空、孙权

_ 匹配严格的 一个任意字符

SELECT name FROM exam_result WHERE name LIKE ‘孙_’;-- 匹配到孙权

如果匹配的是数值类型 也可以的 like ’ 9 %’

NULL 的查询:IS [NOT] NULL

– 查询 qq_mail 已知的同学姓名

SELECT name, qq_mail FROM student WHERE qq_mail IS NOT NULL;

– 查询 qq_mail 未知的同学姓名

SELECT name, qq_mail FROM student WHERE qq_mail IS NULL;

条件查询 不一定只在select出现 ,update delete都会出现


4.3.8 分页查询:LIMIT

查询结果比较多的时候,把结果分成许多“页”

如果一下子查出来,其实开销是很大
1.数据库服务器磁盘io
2.数据库客户端到数据库服务器的网络io

我们来看一下,下一个查询语句的意思

这个就是查看前3个的内容,下标是从0开始。

还可以使用

还可以这些简写


不过还是建议使用 offset 这样的,因为下面的这样不好区分什么是偏移量什么是页数

语法:

– 起始下标为 0
– 从 0 开始,筛选 n 条结果
SELECT … FROM table_name [WHERE …] [ORDER BY …] LIMIT n;
– 从 s 开始,筛选 n 条结果
SELECT … FROM table_name [WHERE …] [ORDER BY …] LIMIT s, n;
– 从 s 开始,筛选 n 条结果,比第二种用法更明确,建议使用
SELECT … FROM table_name [WHERE …] [ORDER BY …] LIMIT n OFFSET s;


4.4. 修改(Update)

语法:

update 表名 set 列名 = 值 ,列名 =值 where 条件;

update 会修改数据库服务器的硬盘的数据,update会把所有的符号条件修改

  1. 将孙悟空同学的数学成绩变更为 80 分
    UPDATE exam_result SET math = 80 WHERE name = ‘孙悟空’;

2.将曹孟德同学的数学成绩变更为 60 分,语文成绩变更为 70 分
UPDATE exam_result SET math = 60, chinese = 70 WHERE name = ‘曹孟德’;

3.将总成绩倒数前三的 3 位同学的数学成绩加上 30 分
UPDATE exam_result SET math = math + 30 ORDER BY chinese + math + english LIMIT

4.将所有同学的语文成绩更新为原来的 2 倍
UPDATE exam_result SET chinese = chinese * 2;

以上案例看看即可最基本


4.5. 删除(Delete)

语法:

delete from 表名 where 条件;

案列:

  1. 删除孙悟空同学的考试成绩

DELETE FROM exam_result WHERE name = ‘孙悟空’;

  1. 删除整张表数据 (如果不加条件就是删除整张表)

delete from 表名


以上是关于MySQL一文搞懂MySQL语句(基础篇)的主要内容,如果未能解决你的问题,请参考以下文章

MySQL一文搞懂MySQL语句(基础篇)

一文彻底搞懂MySQL基础:B树和B+树的区别

一文彻底搞懂MySQL基础:B树和B+树的区别

一文彻底搞懂MySQL基础:B树和B+树的区别

一文快速搞懂MySQL InnoDB事务ACID实现原理

一文搞懂MySQL数据库基础与MySQL表的增删查改(初阶)