MySQL学习笔记

199 阅读18分钟

问题

什么是数据库? 什么是数据库管理系统? 什么是SQL? 三者关系?

# 数据库
简称DB,实际上是一堆文件,这些文件中存储了具有特定格式的数据。

# 数据库管理系统
简称DBMS,专门管理数据库中的数据的 

# SQL
结构化查询语言,用它来操作数据的增删改查

# 三者关系
DBMS---执行---SQL---操作---DB

注意点

1.一定要在语句最后加分号,分号表示结束
2.数据库中的字符串都是采用‘单引号’括起来的,这是标准;双引号也行,Oracle数据库中不行
3.数据库中,只要NULL参与的数学运算,最终结果就是NULL
4.数据库中的null不能使用等号进行衡量,因为数据库中null代表什么也没有,不是一个值
5.所有关键字的指向顺序:from -- where -- group by --  having--- select -- order by-- limit

SQL语句分类

DQL:数据查询语言(凡是带有select关键字的都是数据查询语言) 

DML:数据操作语言(凡是对表当中的数据进行insert、delete、update的都是DML),主要操作的是表中的数据

DDL:数据定义语言(凡是带有create、drop、alter的都是DDL),主要操作的是表的结构,不是表中的数据

TCL:是事务控制语言(事务提交:commit,事务回滚:rollback)  

DCL:是数据控制语言(授权:grant,撤销授权:revoke)

对数据库的操作

# 查看所有数据库 
show databases;  

# 进入数据库
use 数据库名;  

# 创建数据库
create database 数据库名;  

# 查看某个数据库中的表
show tables;  

# 删除数据库
drop database 数据库名;    

# 查看数据库版本号
select version();  

# 查看当前使用的数据库
select database();

问题

什么是表?

它是数据库最基本的单元,分为字段和数据

# 字段组成
名称,数据类型,约束,长度

导入sql文件中的数据?

source 路径

查看表的结构

desc 表名

字段的数据类型

1)varchar:可变长度字符串,【会根据实际的数据长度动态分配空间,节省空间;但速度慢】
2)char:定长字符串,【不需要动态分配空间,速度快;使用不当可能会导致空间浪费】
3)int、bigint 、float 、double
4)data:短日期类型,只包括年月日【mysql默认格式:%Y-%m-%d】
5)datetime:长日期类型,包括年月日时分秒信息 【mysql默认格式:%Y-%m-%d %h:%i:%s】
6)clob:字符大对象,最多可以存储4G的字符串【比如:一篇文章】
7)blob:二进制大对象【专门用来存储图片,声音。视频等流媒体数据】

创建

# 语法
create table 表名(
   字段名1 数据类型 [约束],
   字段名2 数据类型,
   字段名3 数据类型
)

# 提醒:表名建议以t_ 或者tab_ 开始,可读性强;

查询

简单查询

1)查询一个字段:select 字段 from 表名;
2)查询多个字符:select 字段1,字段2 from 表名;
3)查询所有字符:select * from 表名; 4)列起别名:select 字段 as 字段别名 from 表名;

条件查询

# 语法
select 字符1,字段2 from 表名 where 条件

类型:
1)等于:=
2)不等于:!=或者<>
3)小于:<,大于>,小于等于<=,大于等于>=
4)范围之间:between....and....
5)并且:and,或者:or 【两个同时出现,and优先级比or优先级高】
6)是否为空:is null 【数据库中的null不能使用等号进行衡量,因为数据库中null代表什么也没有,不是一个值】
7)是否在里面:in 【不是区间,表示或】
8)模糊查询:like 【支持%或下划线匹配】

# 查出含有O的名字
select ename from emp where ename link '%O%'

# 找出以T结尾|开头的名字
select ename from emp where ename link '%T'  | ‘T%’

# 找出第三个字母是R的名字
select ename from emp where ename link '__R%' 

#  找出名字带有_的 【需要转义】
select ename from emp where ename link '%\_%'

排序查询

# 语法
select 字段 from 表名 order by 字段  // 默认是升序

分类:
1)指定降序:select 字段 from 表名 order by 字段 desc
2)指定升序:select 字段 from 表名 order by 字段 asc
3)多字段排序:select 字段 from 表名 order by 字段1,字符2 【只有字段1相等的情况下,才会按字段2排序】

分组查询

定义:在实际的应用中,可能有这样的需求,需要先进行分组,然后对每一组的数据进行操作。

# 语法
select  字段  from  表名 gruop by 字段

注意:
在一条select语句当中,如果有group by语句的话,select后面只能跟:参加分组的字段,以及分组函数,其它的一律不能跟

having:
1)使用having可以对分组后的数据进一步过滤
2)having不能单独使用,having必须和group by联合使用
3)having不能代替where
4) 优先使用where,当where无法满足时,再使用having【where-- 先筛选再分组,having-- 先分组再筛选】

连接查询【重点】

定义:多张表联合起来查询
语法分类:

# 92语法:
select 字段,字段 from 表名,表名 where 表的连接条件,筛选条件 // 结构不清晰

# 99语法(推荐使用):
select 字段,字段 from 表名 join 表名 on 表的连接条件 where 筛选条件  // 表连接的条件是独立的

分类
(1) 内连接
特点:完全能够匹配上这个条件的数据查询出来,a,b表没主次关系
分类:
1)等值连接:表连接条件等值
2)非等值连接:表连接条件非等值
3)自连接:一张表看作两张表

(2) 外连接

# 语法
select 字段 from 表名 right|left  join 表名 on 连接条件

特点:表之间产生了主次关系
分类:
1)左连接:表示将join关键字左边的这张表看成主表,主要是为了将这张表的数据全部查询出来,捎带的关联查询右边的表
2)右连接:表示将join关键字右边的这张表看成主表,主要是为了将这张表的数据全部查询出来,捎带的关联查询左边的表。

(3) 全连接
特点:a,b都是主表

多表查询:

# 格式
select 字段  from  a表名 join  b表名  on  a表和b表的连接条件  join  c表名  on  a表与c表的连接条件

# 注意
当几张表进行连接查询,没有任何条件限制的时候,最终查询结果条数,是几张表条数的乘积 (笛卡尔积现象)

子查询

定义:select语句中嵌套select语句,被嵌套的select语句被称为子查询
注意点:from语句中的子查询,可以将子查询的查询结果当作一张临时表

增加

# 语法
insert into 表名(
    字段名1,
    字段名2,
    字段名3.....
) values(
    值1,
    值2,
    值3
)  // 数量和类型一一对应

# 插入多条数据:
insert into 表名(字段,....,....)values(),(),()

注意:
1)insert语句只要执行成功了,就会多一条数据
2)插入数据时,前面的字段名省略的话,等于都写上了,所以值也有都要写上
3)指定默认值:在建表的时候,通过在字段后面添加--- default '值'

修改

# 语法
update 表名 set 字段名1=值1,字段名2=值2,字段名3=值3... where 条件

注意:没有条件限制会导致所有数据全部更新

删除

删除表

drop table 表名--- 删除表
drop table if exists 表名 --- 如果这张表存在,则删除

删除数据
1)delete方式

# 格式
delete from 表名 where 条件

注意:没有限制条件,整张表的数据都会被删除
原理:表中的数据被删除了,但是这个数据在硬盘上的真实存储空间不会被释放
优缺点:删除效率比较低;支持回滚(rollback)

2)truncate方式

# 格式
truncate table 表名

原理:表一次被截断,物理删除
优缺点:不支持回滚;效率高

处理函数

单行处理函数

特点:一个输入对应一个输出
常见:
1)lower() 转换小写 , upper() 转换大写
2)substr() 取子串 【参数:被截取的字符串,起始下标,截取长度】
3)length() 取长度
4)trim() 去除空格
5)concat() 拼接
6)round() 四舍五入 【参数:数字,保留位数】
7)rand() 随机数
8)ifnull() 可以将null转换成一个具体数据 【参数:为null字符, 0】
9)case 字段 when..then..when..then..else..end

# 当岗位是MANAGER时,工资上涨10%,当岗位为SALESMAN时,工资上涨12%
select ename,job (case job when 'MANAGER' then sal*1.1 when 'SALESMAN' then sal*1.2 else sal end) as newsal from emp;

10)str_to_date('字符串格式',‘mysql日期格式’) 将字符串varchar类型转换成date类型
11)date_fromat(日期类型数据,‘mysql日期格式’) 将date类型转换成具有一定格式的varchar字符串类型

多行处理函数(分组函数)

特点:多个输入对应一个输出
常见:
1)count() 计数
2)sum() 求和
3)avg() 平均
4)max()
5)min()

注意点:
1)分组函数在使用时,必须先进行分组,再使用;若没分组,则默认为整张表
2)自动忽略为NULL的值,不需要提前对NULL处理
3)count(*):统计表当中的总行数
4)count(具体字段):统计该字段下所有不为NULL的元素的总数
5)不能直接使用在where字句中【因为:where在group by之前执行】
6)所有分组函数可以一起使用

约束【重点】

定义

在创建表的时候,我们可以给表中的字段加上一些约束,来保证这个表中数据的完整性、有效性

分类:

1)非空约束:not null

  • 被约束的字段不能为NULL,必须插入数据
  • 只能是列级约束(添加在某个字段列后)

2)唯一性约束:unique

  • 被约束的字段不能重复,可以为NULL
  • 可以表级约束,也可以列级约束
  • 两个字段联合唯一:unique(字段1,字段2)【这就是表级约束】

3)主键约束:primary key(简称PK)

  • 重要性:是每一行记录的唯一标识(等同于身份证)
  • 记住:任何一张表都应该有主键,没有主键,表无效!!;一张表,主键只能有一个
  • 特征:不能为NULL,同时也不能重复
  • 分类1:单一主键,复合主键【建议使用单一主键】
  • 分类2:自然主键,业务主键【建议使用自然主键,因为主键只要做到不重复就行,不需要有意义】
  • 注意:如果一个字段同时被not null 和unique约束的话,自动变成主键字段

4)自增约束

  • 特点
    • 一个表只能一个自增约束
    • 自增约束的列只能是整数列
    • 自增约束的列必须是键列(主键,唯一键,外键)(一般主键自增最多)
  • 建表时指定某个列自增
create table t_vip(
    id int primary key auto_increment,
    name varchar(255),
    sex char(1)
)
  • 建表后增加自增
alter table 数据库名.表名 modify 字段名 数据类型 auto-increment;
  • 取消自增
alter table 数据库名.表名 modify 字段名 数据类型;

5)外键约束:foreign key(简称FK)

  • 相关术语:外键约束、外键字段、外键值
  • 添加了外键约束的字段,只能根据依赖的值选择,不能修改和添加其他数据值
  • 外键值可以是NULL
  • 子表中的外键引用的父表中的某个字段,被引用的这个字段:不一定的是主键,但是不能重复
create table t_class(
// 父表
   classno int primary key,
   classname varchar(255)
);
create table t_student(
// 子表
   no int primary key auto_increment,
   name varchar(255),
   cno int,
   foreign key(cno) references t_class(classno)
)

6)默认值预约

  • 建表时指定某个列为默认值
create table t_vip(
   name:varchar(255) not null default(值),
)
  • 建表后增加默认值
alter table 表名 modify 字段名 数据类型 default 值;
  • 取消默认值
alter table 表名 modify 字段名 数据类型;

distinct、limit、union

去重(distinct)

必须放在所有字段的最前面

union

特点:将查询的结果集进行合并

# 语法
select.... union select.....

注意点:
1)union的效率要高一点,对于表连接来说,每连接一次新表,则匹配的次数满足笛卡尔积, 但是union可以减少匹配的次数,在减少匹配次数的情况下,还可以完成两个结果的拼接
2)union在进行结果合并的时候,要求两个结果集的列数和列的数据类型都相同,

limit

特点:将查询结果集的一部分取出来,通常使用在分页查询中

# 语法
limit(startIndex,length)// startIndex:起始下标,从0开始;length:长度

#例如
select... from.... order by.... limit 5;  // 取前5

公式:limit (pageNo-1)*pageSize,pageSize
注意:MySQL当中limit在order by 之后执行

事务

什么是事务?

1)一个事务其实就是一个完整的业务逻辑;
2)是多条DML语句同时成功,或者同时失败
3)是一个最小的工作单元,不可再分

注意点

1)只有DML(delete/updata/insert)语句才有事务这么一说,其他语句和事务无关!!!
2)mysql默认自动提交事务,每执行一条DML语句,则提交一次
3)回滚永远只能回滚到上一次的提交点
4)关掉mysql的自动提交机制--- start transaction

事务特性

1)原子性:是最小的工作单元,不可再分
2)一致性:在一个事务当中,所有操作必须同时成功,或者同时失败
3)隔离性:A事务和B事务之间具有一定的隔离
4)持久性:事务最终结束的一个保障。(事务提交,就相当于将没有保存到硬盘上的数据保存到硬盘上!)

事务与事务的隔离级别?

1)读未提交:read uncommitted(最低级别)
定义:事务A可以读取事务B未提交的数据
存在问题:脏读现象

2)读已提交:read committed
定义:事务A只能读取事务B已经提交的数据
存在问题:不可重复读取数据(即每次读取到的数据可能不一致)

3)可重复读:repeatable read
定义:事务A开启之后,不管多久,每一次在事务B中读取的数据都是一致的
存在问题:只要事务B不结束,事务A每次读取到的数据都是幻象(一样的),不真实
mysql中默认的事务隔离级别就是这个!!

4)序列化/串行化:serialzable(最高级别)
定义:事务排队,不能并发,不能同时进行
存在问题:效率最低

事务是怎么做到多条DML语句同时成功和同时失败的呢?

在事务执行过程中,每一条DML的操作都会记录到事务性活动的日志文件中 在事务执行过程中,我们可以提交事务,也可以回滚事务

1)提交事务?
清空事务性活动的日志文件,将数据全部彻底持久化到数据库表中 提交事务标志着:事务的结束,并且是一种全部成功的标志

2)回滚事务?
将之前所有的DML操作全部撤销,并且清空事务性活动的日志文件 回滚事务标志着:事务的结束,并且是一种全部失败的结果

怎么提交事务?回滚事务?

提交事务:commit; 回滚事务:rollback;

存储引擎

什么是存储引擎,有什么用呢?

存储引擎是一个表存储/组织数据的方式
不同的存储引擎,表存储数据的方式不同

怎样查看,给表/指定“存储引擎”呢?

1)可以查看表的存储引擎:show create table 表名;
2)在建表的时候可以在最后小括号的“)”的右边使用:
ENGINE来指定存储引擎 【mysql默认的存储引擎:InnoDB】
CHARSET来指定这张表的字符编码方式 【mysql默认方式:utf8】【gbk方式可以插入中文】

create table t_product(
    id int primary key,
    name varchar(255)
) engine=InnoDB default charset=gbk;

3)怎样查看mysql支持哪些搜索引擎:show engines \G;
mysql一共支持9大搜索引擎,版本不同支持不同

mysql常用搜索引擎

1)MyISAM:可被转换成压缩、只读表来节省空间;不支持事务机制,安全性低
2)InnoDB:非常安全,支持数据库崩溃后自动恢复机制;不能压缩,不能很好的节省存储空间
3)MEMORY:查询效率最高;不安全,关机之后数据消失,因为数据和索引都是在内存里面的

索引

什么是索引?

是在数据库表的字段上添加的,是为了提高查询效率存在的一种机制,相当于一本书的目录,是为了缩小扫描范围二存在的一种机制

操作索引

# 创建
create index  索引名  on 表名(字段)  

# 删除
drop index 索引名 on 表名

注意点

1)在任何数据库表当中主键上都会自动添加索引对象,另外在mysql当中,一个字段上如果有unique约束的话,也会自动创建索引对象
2)索引实现原理:索引在mysql存储引擎当中都是一棵平衡二叉树的形式存在,缩小扫描的范围,避免全表扫描
3)在任何数据库当中,任何一张表的任何一条记录在硬盘存储上都有一个硬盘的物理存储编号

什么时候考虑添加索引呢?

1)数据量庞大
2)该字段经常出现在where的后面
3)该字段有很少的DML操作

查看一个SQL语句是否使用索引进行了检索?

explain select * from EMP where ename=‘KING’

索引失效的时候

1)模糊查询以’%‘开始
2)使用or的时候会失效,除非两边都有索引【不建议使用or】
3)复合索引的时候,没有使用左侧的列查找,索引失效

create index emp_sal_ename_index on emp(sal,ename) // 没有使用sal查找时,不会采用索引检索  

4)在where当中索引列参加了运算 5)在where当中索引列使用了函数

分类

1)单一索引:一个字段添加索引
2)复合索引:两个字段或者多个字段上添加索引
3)主键索引:主键上添加索引
4)唯一性索引:具有unique约束的字段上添加索引

视图

什么是视图

view:站在不同的角度去看待同一份数据

操作视图对象

# 只有DQL语句才能以view的形式创建
# 创建
create view 视图名 as 只能是DQL语句(select)

# 删除
drop view 视图名

特点

1)视图不是在内存当中,视图对象也是存储在硬盘上的,可以进行操作 2)对视图的操作,会影响到原表的数据

作用

将一条复杂的SQL语句查询出的东西创建成一个真实存在的表

三范式

什么是数据库设计范式

数据库表的设计依据,教你怎么进行数据库表的设计

作用

设计数据库表的时候,按照以上的范式进行,可以避免表中数据的冗余,空间的浪费

分类

1)第一范式:任何一张表必须要有主键,每一个字段的原子性不可再分
2)第二范式:建立在第一范式的基础之上,要求所有非主键字段完全依赖主键,不要产生部份依赖
3)第三范式:建立在第二范式的基础之上,要求所有非主键字段直接依赖主键,不要产生传递依赖

重点

1)口诀:一对一,外键唯一【在外键上,再添加unique约束】
2)口诀:多对多,三张表,关系表两个外键
3)口诀:一对多,两张表,多的表加外键

DBA常用命令

新建用户

# 在window下:
create user username identified by 'password'
  username--- 你创建的用户名
  password---- 该用户登陆密码

授权

# 在mysql下:
grant all privileges on dbname.tbname to 'username'@'login ip' identified by 'password' with grant option;

# 解释
all privileges---- 表示该用户可以进行任何操作
         privileges包括:create、delete、drop、index、insert、select、update、all、usage(只允许登陆)
1)dbname---- *表示所有数据库
2)tbname---- *表示所有表
3)login ip---- %表示任何 ip
4)username---- 用户名
5) password--- 用户登陆密码
6) with grant option; 表示该用户还可以授权给其他用户

回收权限

# 在mysql下:
revoke privileges on dbname[.tbname] from username;

# 例如:
revoke all  privileges on *.* from p123;【表示回收用户p123的所有权限】

删除用户

# mysql下:
drop user 'username'@'localhost';

怎样将数据导出?

# 在window的下:
mysqldump 数据库名[表名]>路径+文件名 -uroot -p123456

# 例如:导出mysql数据库 
mysqldump mysql>D:\data\mysql.sql -uroot -p123456

# 例如:导出mysql数据库下的emp表
mysqldump mysql emp>D:\data\emp.sql -uroot -p123456

数据导入

1)需要登陆到mysql数据库服务器上
2)然后创建数据库: create database 数据名
3)使用数据库:use 数据库名
4)初始化数据库:source 路径