1.前言
在学习MySQL前,我们先来认识一下SQL语句.它分为以下几种:
DDL 数据操作语言,用来定义数据库对象(数据库,表,字段)
DML数据操作语言,用来对数据库表进行增删改
DQL数据查询语言,用来查询数据库表的记录
DCL数据控制语言,用来创建数据库用户,控制数据库的访问权限
学习数据库中最主要的部分就是学习 MySQL 的增删改查(CRUD)
2.SQL的通用语法
我们在学习一门计算机语言时,不过要学习对应的语法,还要学习对应的语法规范.SQL的语法规范有以下这些:
SQL语句可以单行或者多行书写,以分号作为结束
SQL语句可以通过空格或缩进来增强语句的可读性
MySQL的SQL语句不区分大小写
虽然不区分大小写,有的地方也建议使用大写,不过我个人还是习惯使用小写
2.1 注释
MySQL中的注释分为单行注释和多行注释
单行注释: -- 注释的内容 或 # 注释的内容
多行注释: /* 注释的内容 */
还有一个注释:comment 这个注释比较特殊.只能在创建数据库表的时候用.
2.2 补充内容
在MySQL的命令行中:
ctrl c可以放弃之前执行的结果,如果之前的SQL语句写错了,或者当前SQL语句的执行时间太长,就可以使用这个方法来放弃
复制: 选中,回车即为复制
粘贴:复制完后,按下鼠标右键就是粘贴
3.数据库操作语言(DDL)
DDL: 数据操作语言,用来定义数据库对象(数据库,表,字段)
3.1 创建数据库
创建数据库要使用create关键字,数据库的名字不能是SQL的关键字
create database 数据库名;
演示:
出现OK,即SQL语句成功执行,创建了一个名为"test"的数据库.
最后面有个 0.00sec,解释一下 sec 就是 second(秒)
数据库的名字不能相同,不能创建已经存在的数据库.现在已经有一个名为"test"的数据库了,如果再次进行创建,就会报错.
因此在创建数据库时,可以使用if not exists进行判断,如果不存在要创建的数据库,才会进行创建.
create database if not exists 数据库名;
进行判断之后,它就不会报错了.但是这个有 1 warning,意思是一个警告
在创建数据库时,可以指定字符集(字符编码)
create database 数据库名 charset 字符集;
字符集中最常用的就是utf8了.说一下,MySQL的默认编码是拉丁文.而且MySQL中的utf8其实是不完整的.这里的utf8无法表示enoji(表情).后面MySQL又搞了个utf8mb4,这个是完整的utf8.
3.2 查看所有数据库
SQL语句为:
show databases;
3.3 选中指定数据库
在使用MySQL时,我们可能会创建很多的数据库,如果要对某个数据库进行操作,就需要先选定指定的数据库.
use 数据库名;
3.4 删除数据库
drop database 数据库名;
可以看到名为"test"的数据库已经被删掉了
删除数据库也只是能删存在的数据库,毕竟有数据库才能删除,没有的话删除就会报错,那么此时也可以像创建数据库时那样进行判断,使用 if exists
drop database if exists 数据库名;
ps: 删库是一个危险的操作,MySQL的数据库一旦删除,数据就没了.没有回收站这一说.大家应该听过"MySQL从删库到跑路"这句话,所以删库需谨慎!
3.5 数据类型
在MySQL数据库中,数据信息是存在数据库表里面的,数据库表中的数据都要定义对应的数据类型.
MySQL中的数据类型分为:整型,浮点型,字符串类型和日期类型
数据类型 大小
BIT[ (M) ] M指定位数,默认大小为1
TINYINT 1个字节
SMALLINT 2个字节
INT 4个字节
BIGINT 8个字节
FLOAT(M,D) 4个字节
DOUBLE(M,D) 8个字节
DECIMAL(M,D) M/D最大值+2
NUMERIC(M,D) M/D最大值+2
注意: 这里浮点数有两个参数,M和D.
M是指有效数字的个数
D是指小数点后保留几位
但是float和double并不是适合保存精度的数据
而dicimal 可以精确保存浮点数(用空间和运算速度换来了更精确的表示方式)
字符串类型
数据类型 大小 说明
VARCHAR (SIZE) 0-65,535字节 可变长的字符串
TEXT 0-65,535字节 长文本数据
MEDIUMTEXT 0-16 777 215字节 中等长度文本数据
BLOB 0-65,535字节 二进制形式的长文本数据
VARCHAR(SIZE) 这里的SIZE限制了存储的最大空间
日期类型
数据类型 大小 说明
DATETIME 8个字节 范围从1000到9999年,不会进行时区的检索和转换
TIMESTAMP 4个字节 范围从1970到2038年,自动检索当前时区并进行转换。
学习完数据类型就可以进行表操作了,进行表操作前,一定要先选中数据库
3.6 创建数据库表
create table 表名(列名 数据类型,列名 数据类型,...);
注意这里是列名在前,数据类型在后. 不要把顺序搞错了
在test这个数据库里面创建一个student表,表的内容有学生id,学生姓名name:
这里的varchar(10)单位是字符,而不是字节
创建数据库表的时候,有两个注意点需要注意:
1.在同一个数据库中,不能创建两个名字相同的表.
再次创建一次student表,就会报错.
SQL的语句还是比较灵活的,语句之间可以相互搭配来达到你想要的效果.因此在创建表时,也可以使用前面介绍过的if not exists进行判断.
2.数据库表的列名不能和SQL关键字相同
例如 我要创建一个名为"table"的数据库表,就会报错.
但是如果实在想用SQL里面的关键字作为表的名字/列名,可以给这些关键字前面加上 反引号 " ` "括起来
使用反引号括起来,就可以创建成功了
3.7 显示选中数据库下的所有表
show tables;
演示:
3.8 查看指定表的结构
desc 表名;
示例:
student这个表的前面两列就是我们创建表时设置的列名和类型,一个是 id ,类型为int.一个是name,类型是varchar.
上图中可以看到int 后面有个11,这里的11指的是显示的宽度
虽然我们在创建表的时候,只是指定的前两列的内容,但是可以看到此处的表,并不是两列.接下来让我们来认识这些列
Null: 指的是 当前列的值是否可以为空 .值为YES就是可以为Null
Key: 和约束有关,后面会详细介绍
Default: 默认值,
Extra: 额外的描述信息
3.9 修改数据库表
drop table 表名;
示例:
注意: 删除数据库和删除数据库表都是非常危险的
4. 数据操作语言(DML)
DML: 数据操作语言,用来对数据库表进行增删改
4.2 新增数据
insert into 表名 values(列,列,...);
MySQL中使用insert 表示新增一条数据,这里的into 可以省略
示例:
注意:
1.在SQL中 只有字符串类型的数据,没有字符类型. 因此单引号和双引号 都可以表示字符串.
2.values后面()的内容要和表的列数和列的类型要匹配.
3. 前面说过MySQL默认字符集是拉丁文,如果插入的是汉字可能会报错.创建表的时候设置字符集即可解决这个问题,也是通过修改MySQL的配置文件来解决这个问题.详情可以看我的这篇文章➡MySQL解决字符集编码问题
以上插入的是一行完整的数据,除了这个方式,insert 还可以插入指定列的数据,其它未被指定的数据就是以默认值来填充
4.3 新增指定列数据
insert into 表名 (指定列1,指定列2,...) values(值1,值2,...);
示例:
通过查询语句,可以看到第二条就是刚才插入的数据,因为没有指定name,它就会以NULL(默认值)的方式进行填充
除了以上两中用法,insert还可以一次插入多条数据
4.4 新增多条数据
insert into 表名 values(列1,列2,...),(列1,列2,...),(...);
1
示例:
成功插入两条数据.
一次插入多条数据比一条一条插入效率高
原因:1.MySQL是服务器客户端程序,执行每条SQL语句都要通过网络发送请求和返回响应,这是有一定的时间开销的 2.数据库服务器是把数据保存再硬盘上的,在进行IO操作时,数据量时会有一定的影响,但影响不是很大,影响更大的是IO的次数
4.5 修改数据
update 表名 set 列名 = 值 where 条件;
如果要修改多个列,列名和值的键值对之间用逗号分隔开
此处的条件会在条件查询中更详细讲解.
例如因为疏忽给"张三"的语文成绩少输入20分.现在要进行修改成正确的
此时在进行查询,可以看到"张三"的成绩修改完成了
4.6 删除数据
delete from 表名 where 条件;
示例:
5.数据查询语言(DQL)
DQL: 数据查询语言,用来查询数据库表的记录
查询其实是SQL中最复杂的操作,插入/删除/修改数据的操作基本上是固定的,但是查询就比较灵活,也比较复杂.
讲讲查询中使用的是这张表:
create table grades(id int,
name varchar(10),
Chinese decimal(3,1),
Math decimal(3,1),
English decimal(3,1)
);
数据中的信息是这些:
insert into grades values
(1,"zhangsan",57,98,66),
(2,"lisi",82.5,77,90),
(3,"wangwu",69,75.5,80),
(4,"zhaoliu",82,66,98);
5.1 全列查询
全列查询就是查询表中的所有列
select * from 表名;
* 是通配符 代表所有列
可以看到当前表中的所有信息都被查出来了
注意:select * 是危险操作! 之所以危险,是不确定数据有多少,数据太多就会把硬盘IO或带宽吃满.
5.2 指定列查询
select 列名,列名,... from 表名;
这里的列名不需要按照定义表的顺序来
示例:
5.3 带有表达式的查询
带有表达式的查询大致可以分为3种, 1.带有一个字段的表达式 2.带有多个字段的表达式 3.不带字段的表达式
1.带有一个字段的表达式
例如,如果我想要得到他们的数学成绩+10分后的表
注意这里"zhangsan"的数学成绩,当时我在创建表的时候,Math的类型是 decimal(3,1).意思有效数字为3位,小数点后保留1位.但是108.0 是4位有效数字.按理来说应该会报错,但是这里为什么没有报错呢?
其实进行表达式查询的时候,得到的表是一张"临时表",并不会影响原来的表.临时表的类型可能不和原来的表的类型一致(会尽可能的把结果表示出来)
2.带有多个表达式的查询
例如上述表中它们的总分,就可以使用带有多个表达式的查询
3.不带字段的表达式的查询
例如如果给它们的成绩评定等级为"B",可以使用不带字段的表达式的查询
注意 带有表达式的查询只是列与列之间进行计算,无法进行行与行之间的计算
5.4 给查询结果列设置别名
select 字段1 [别名1],字段2 [别名2],... from 表名;
可以看到此时查询出来的结果的列名就是sum了,而不再是Chinese+Math+English
但是这种写法不太好,很容易让人误会.
建议写法:
select 字段1 [as 别名1],字段2 [as 别名2],... from 表名;
加上as容易区分这是给那一列起的别名.
5.5 去重查询(distinct)
select distinct 列名1,列名2,... from 表名;
查询的时候可以针对列进行去重
如果指定多个列,是需要这多个列都相同,才会进行去重
因为我用的这个表里面没有列的值是重复的,就不给大家演示了.
5.6 排序查询(order by)
select 字段列表 from 表名 order by 字段;
order by默认是"升序排序",它是省略了后面的"asc".若想进行降序排列,需要在最后面加上"desc"
示例:以语文成绩 升序/降序 进行排序
关于查询有一点需要注意:如果不加order by进行查询,查询的结果看似是根据插入的顺序进行依次排序的,但实际上这个顺序是不可预期的,MySQL中并没有承诺是按照插入的顺序进行排序的.
排序也可以针对 表达式和别名 进行
例如对学生的总成绩进行降序排列
排序也可以对 多个列 进行排序
多个列进行排序时,会先对后面的查询的列逐个进行排序,如果当前排序的列相同,再对后面的列进行排序. 这个类似与字符串的比较,先比第一个字符谁大谁小,如果第一个字符比较出来大小了,就直接排序.但如果第一个字符是相同的,就会去比较后面的字符.
进行多列排序时,可以分别针对每个列设置一个 升序or降序 的排序规则
5.7 条件查询(where)
select 字段列表 from 表名 where 条件;
条件查询会按行进行筛选.
要想描述条件,就需要用到"运算符"
比较运算符 说明
> 大于
>= 大于等于
< 小于
<= 小于等于
= 等于,NULL不安全,例如NULL=NULL的结果就是NULL(FALSE(0))
<=> 等于,NULL安全,例如NULL=NULL的结果就是TRUE(1)
!=,<> 不等于
between n and m 表示[n,m]的范围
in(potion,…) 是否在()中
is null 是NULL
is not null 不是NULL
like 模糊匹配,%表示任意多个(包括0个)任意字符,_表示任意一个字符
逻辑运算符 说明
and 并且,满足所有条件时结果才为TRUE(1)
or 或,只要有一个条件为true结果就为TRUE(1)
not 非, 真变假,假变真
注意:NULL与进行任何运算结果都为NULL,NULL则会被认为是false
示例:选出语文成绩大于60的人和对应的成绩
条件查询只需要根据需求设置条件即可
条件语句中如果有别名,不能对别名设置条件.
条件语句中如果同时有and和or的话,是先计算and后计算or(不建议背).最好的方法是加上()
模糊查询开销是比较大的
5.8 分页查询(limit)
之前谈到了select * 是危险操作,是因为不知道数据库表中的内容有多少,容易把硬盘IO或带宽吃满.
因此在查询操作中,引入了 limit ,通过limit来限制查询结果的数量
可以在查询语句的末尾加上 limit N,指定的N 就是查询结果的数量,无论前面的查询条件怎么写,查询的结果的数量始终不会超过N(前N条)
limit还可以搭配 offest 实现分页的效果(offest从0开始),有的时候查询的东西很多,就是全部显示出来,也不一定能看得过来.因此就可以搭配offest实现分页的效果.
limit 5: 限制查询结果最大数量为5
limit 5,offset 0: 以第1条记录开始,限制查询结果最大数量为5
limit 5,offset 5: 以第5条记录开始,限制查询结果最大数量为5
除此之外,还可以省略offest
limit 5,10 等价于 limit 10,offset 5:
5是指定的offset的值
10是指定的N的值
建议使用第一种写法,不要省略offest.这样的可读性更好,不容易出错
总体来说,SQL的语句是没有什么难度的,但是SQL语句比较灵活,可以相互搭配.因此想要掌握SQL语句,还需要多加练习.