MySql个人总结

MySql

数据库的基础知识

数据的存储方式

存储位置优点缺点
内存(集合,实体类对象数据是放在内存中)存取速度很快不能永久的保存
文件(IO流,把数据存在文件中)可以永久操作数据数据的管理和维护不方便
数据库可以永久保存数据
数据库管理系统对数据有专门的操作命令,方便我们对数据进行维护和管理
数据库通常是要花钱的

数据库的概念

  1. 数据存储的仓库,称为数据库。
  2. 在计算机中本质上还是一个或多个文件组成
  3. 由统一的SQL语句来管理和维护数据库, 我们今天要学的就是SQL语句怎么编写,每条SQL语句的作用是什么

数据库的分类

  1. 关系型数据库:MySQL,Oracle,SQL Server,SQLite,它们有一个共同的特点,都支持SQL语句的操作。如果你会一种关系型数据库的SQL语句,你就可以操作其它所有的数据库。不同的数据库也是有差异的,大同小异。
  2. 非关系数据库:差异比较大,不同的数据库之间操作几乎都不相同,做为关系型数据库有益的补充。

DBMS:DataBase Manager System 数据库管理系统

Relational DBMS:关系型数据库

常见的数据库

MySQL:开源免费的数据库,中型的数据库。MySQL6.x版本也开始收费。最早是MySQL开发,后来Sun公司收购了MySQL,而Sun公司又被Oracle收购。

在这里插入图片描述

Oracle:收费的大型数据库,Oracle公司的产品。
在这里插入图片描述

数据库管理系统、数据库和表的关系

在这里插入图片描述

什么是SQL

SQL:Structured Query Language 结构化查询语言,它是一种在各个关系型数据库中通用的语言,但不同的关系型数据库也有不同的语法结构。

SQL语句分类

  1. Data Definition Language

    简称为DDL,数据定义语言,主要用于数据库和表的管理

  2. Data Manipulation Language

    简称为DML,数据操纵语言,主要用于表的增删改操作

  3. Data Query Language

    简称为DQL,数据查询语言,主要用于表的查询操作

  4. Data Control Language

    简称为DCL,数据控制语言,主要用于用户权限的管理

MySQL的语法

  1. 结尾:每条SQL语句必须以分号结束,但在SQLyog中可以不写,可以选中一部分代码执行,建议都加上分号。
  2. 大小写: MySQL不区分大小写,关键字中select和SELECT是一样的。
  3. 在MySQL中注释有以下三种写法:
注释的语法说明
–空格单行注释
/* */多行注释,与Java相同
#单行注释,不建议,这种是mysql特有,不是通用的方式。

MySQL数据类型

常使用的数据类型如下

数据类型关键字
整型int或integer
浮点型double, float
decimal(5,2) 整个小数长5位,小数位占2位
字符串型char定长:char(2) 最长存储2个字符,无论有没有使用2个,都是占用2个。
varchar可变长:如:varchar(100),最长可以保存100个字符
如果只使用了3个,占3个字符的空间。
日期类型date或time,datetime

常用数据类型说明

在这里插入图片描述

/*
 创建表的语法:
 create table 表名(
      字段名 字段类型 约束,
      字段名 字段类型 约束
  )
  
*/
-- 创建数据库
create database day18;

-- 创建student表包含id整数,name变长字符串长20,sex性别定长型1,birthday字段日期类型
create table student(
     id int,   -- 编号
     name varchar(20),  -- 姓名
     sex char(1),   -- 性别
     birthday date  -- 生日
);

DDL:查看表结构

-- 查看某个数据库中的所有表
show tables;
use mysql;
show tables;

-- 查看表结构,表结构创建好,表中没有任何数据,这是一个空表
use day18;
desc student;

--  查看创建表的SQL语句,看到的是mysql生成的语句,并不是我们写的,功能是一样的。
show create table student;

-- 创建s1表,s1表结构和student表结构相同。复制表结构,没有其中记录
-- 语法:create table 新表 like 旧表
create table s1 like student;

-- 查看s1表的结构
desc s1;

逻辑运算符

逻辑运算符说明
and 或 &&全真为真
or 或 ||见真为真
not 或 !

关键字

查询关键字作用
AS给列或表定义别名,可以省略
DISTINCT去重复的值
<>不等于
AND/OR/NOT与,或,非
BETWEEN…AND在一个指定的范围之内,包头包尾
IN(多个值)多个值匹配其中任何一个
LIKE ‘张%’模糊查询,两个通配符:%, _
IS NULL比较是否是空

in关键字

语法

select 列名 from 表名 where 列名 in(值1,值2…)
in里面的每个数据都会作为一次匹配条件,只要满足条件的就会显示

操作

-- 使用in关键字查询效率更高,如果使用or不会使用索引,in可以使用索引
select * from student3 where id in (1,3,5);

范围查询

select 列名 from 表名 where 列名 between 小值 and 大值
表示从值1到值2范围,包头又包尾。小值必须放在前面,大值必须放在后面

操作

-- 查询english成绩大于等于77,且小于等于87的学生
select * from student3 where english >=77 and english<=87;
-- 可以使用between关键字实现同样的功能
select * from student3 where english between 77 and 87;

like关键字

作用:用于字符串的模糊查询
语法:select 列名 from 表名 where 列名 like 关键字
如果关键字没有使用通配符,功能与等于相同

MySQL通配符

通配符说明
%匹配0~n个字符
_匹配一个字符

操作

-- 查询名字是马的同学,查询不到记录的,如果要模糊查询必须使用通配符
select * from student3 where name like '马'

-- 查询姓马的学生
select * from student3 where name like '马%'

-- 查询姓名中包含'德'字的学生
select * from student3 where name like '%德%'

-- 查询姓马,且姓名有2个字的学生
select * from student3 where name like '马%'   -- 所有姓马的
select * from student3 where name like '马_'    -- 只匹配1个字符
select * from student3 where name like '马__'    -- 只匹配2个字符

查询为空的列

关键字

IS NULL 查询值是NULL的记录,注:不能写成=NULL
语法:
select 列名 from 表名 where 列名 is null  -- 查询指定列的值为空
select 列名 from 表名 where 列名 is not null  -- 查询指定列的值为不空

操作

-- 查询英文成绩为NULL的学生
select * from student3;
-- 错误写法:
select * from student3 where english = null;
-- 正确写法:
select * from student3 where english is null;

-- 查询英语成绩不为NULL的学生
-- 错误写法:
select * from student3 where english != null;
-- 正确写法:
select * from student3 where english is not null;

-- 查询姓名和英语成绩,如果英语为null,则显示为0分
select name,english from student3;

-- 函数: ifnull(字段名, 默认值) 如果这一列不为空,就显示它原来的值,如果为空,就显示后面这个默认值
select name,ifnull(english,0) from student3;

相关的函数说明

mysql函数说明
IFNULL(字段名,默认值)如果这一列不为空,就显示它原来的值,如果为空,就显示后面这个默认值

order by 按指定的列名进行排序,列名可以指定1列或多列

select 列名 from 表名 where 列名 order by 列名 [asc/desc], 列名 [asc/desc]
升序: asc 默认可以省略
降序: desc

多列排序

-- 默认是升序,不会影响数据库的物理顺序,只是显示的结果不同
select * from student3 order by age;   

-- 查询所有数据,使用年龄降序排序
select * from student3 order by age desc;

-- 查询所有年龄大于20岁的学生,在年龄降序排序的基础上,如果年龄相同再以数学成绩升序排序
select * from student3 where age>20 order by age desc, math asc;

五个聚合函数

SQL中的聚合函数作用
count(列名)求这一列所有的记录数
sum(列名)求这一列所有值的总和
max(列名)求这一列中最大的值
min(列名)求这一列中最小的值
avg(列名)求这一列所有值的平均值
-- 查询学生总数
-- 列名可以是所有列,也可以指定列
select count(id) 总记录数 from student3;

select count(*) 总记录数 from student3;

-- 可以写成0,查询效率比较高
select count(0) 总记录数 from student3;

-- 查询年龄大于40的总数
select count(id) 总记录数 from student3 where age>40;

-- 查询数学成绩总分
select sum(math) 数学总分 from student3;

-- 查询数学成绩平均分
select avg(math) 数学平均分 from student3;   -- 不能整除就是小数

-- 查询数学成绩最高分
select max(math) 数学最高分 from student3;

-- 查询数学成绩最低分
select min(math) 数学最低分 from student3;

-- 如果要知道最高分或最低分是谁,目前还做不到,通过子查询来实现

分组查询

select 列名 from 表名 where 条件 group by 列名 having 过滤条件
group by 按指定的列进行分组
having 指定分组后的过滤条件

GROUP BY将分组字段结果中相同内容作为一组,并且返回每组的第一条数据,所以单独分组没什么用处。分组的目的就是为了统计,一般分组会跟聚合函数一起使用。

-- 按性别进行分组,求男生和女生数学的总成绩
select sex, sum(math) 数学总分 from student3 group by sex;  -- 同时显示性别这一列

-- 求男生和女生各是多少个人
select sex, count(*) 人数 from student3 group by sex; 

-- 求男生和女生数学平均分是多少
select sex, avg(math) 数学平均分 from student3 group by sex; 

对分组过后的结果过滤:

-- 查询年龄大于25岁的人,按性别分组,统计每组的人数,并只显示性别人数大于2的数据。
-- You have an error in your SQL syntax;   SQL语法错误
SELECT sex, COUNT(*) FROM student3 WHERE age > 25 GROUP BY sex WHERE COUNT(*) >2;
-- having是先分组,再过滤
SELECT sex, COUNT(*) FROM student3 WHERE age > 25 GROUP BY sex having COUNT(*) >2;

having与where的区别

关键字功能
where子句1. 放在group by的前面
2. 先过滤,再分组
3. 后面不能使用聚合函数
having子句1. 放在group by的后面
2. 先分组,再过滤,对分组以后的结果再次进行过滤
3. 后面可以使用聚合函数

limit的作用:

作用:中文意思是限制的意思。

语法:select 列名 from 表名 limit 起始索引(从0开始), 返回的行数

select的关键字顺序

select 字段 from 表      查询所有行
where 条件 							指定行过滤的条件
group by 分组列 					按指定的列进行分组
having 过滤条件 				先分组,再过滤
order by 排序列 					排序,asc/desc
limit 跳过行, 返回行			分页查询

先后顺序是固定的

约束种类

约束名约束关键字
主键primary key
非空not null
唯一unique
外键foreign key … references
检查约束check 注:mysql不支持

修改主键自增的起始值

-- 将主键的起始值设置为1000
alter table st2 auto_increment = 1000;

-- 表中已经存在的记录不会有影响,只会对新插入的记录有影响
insert into st2 values (null, '王五', 22);  

外键约束:级联更新和删除

目标

多表中级联更新和删除

为什么要级联操作

-- 要把部门表中的id值2,改成5,能不能直接更新呢?
select * from department;
-- Cannot delete or update a parent row:  不能更新主表中行
update department set id=5 where id=2;

-- 要删除部门id等于1的部门, 能不能直接删除呢?
-- Cannot delete or update a parent row: 不能删除主表中行
delete from department where id=1;

-- 如果有外键约束,主表中主键不能随意更新或删除

什么是级联操作

在更新或删除主键中主键的同时,级联更新或删除从表中外键值

语法

以下语句写在创建外键的后面,就可以实现级联更新或级联删除

级联操作语法
级联更新on update cascade
级联删除on delete cascade

操作

-- 删除外键约束,通过约束的名字来删除
alter table employee drop foreign key fk_emp_dept;

-- 添加外键约束,级联更新和级联删除,可以2个都写,也可以只写一个
alter table employee add constraint fk_emp_dept foreign key(dep_id) references department(id) on update cascade on delete cascade;

-- 把部门表中id等于2的部门改成id等于5
select * from department;
update department set id=5 where id=2;
select * from employee;

-- 删除部门号是1的部门
delete from department where id=1;  -- 不建议使用级联删除,导致整个部门所有的员工都被删除

第一范式

概念

第一范式:表中的每一列都是原子的,不可再拆分成更小的列,看实际的业务需求来定,这一列是否做为一个整体来使用。

第二范式

概念

在满足第一范式的前提下,表中每一列都完全依赖于主键。主要是因为存在复合主键。

复合主键:表中一行有2列以上共同做为主键。

单一主键:表中只一列是主键,单一主键都是符合第二范式。

不存在局部依赖的问题,表中有些列是依赖于复合主键中一列,其它列依赖于复合主键的另一列。一张表只描述一件事情,如果描述了2件事情以上,则不符合第二范式。

第三范式

概念

在满足第二范式的前提下,表中每一列都直接依赖于主键,而不是通过其它列来间接依赖于主键。

依赖关系

所谓传递依赖,指的是如果存在"A → B → C"的决定关系,则C传递依赖于A。

满足第三范式的数据库表应该不存在如下依赖关系:主键列 → 非主键列x → 非主键列y

表连接:笛卡尔积和内连接

表连接的分类

表连接查询:

分为内连接和外连接

内连接:隐式内连接和显式内连接

外连接:左外连接(左连接)和右外连接(右连接)

笛卡尔积现象

什么是笛卡尔积

在这里插入图片描述

隐式内连接语法

语法:
select 列名 from 左表 ,右表 where 主表.主键 = 从表.外键;  -- as省略
隐藏内连接没有join关键字

显式内连接语法

无论是隐式还是显式,它们的查询结果是一样的,只是语法不同

左边 inner join 右表 on 表连接条件

语法
select 列名 from 左表 inner join 右表 on 主表.主键 = 从表.外键

-- 显式内连接
select * from dept d inner join emp e on d.id = e.dept_id;

左连接

语法

select * from 左表 left join 右表 on 主表.主键=从表.外键
-- 需求:在部门表中增加一个销售部,需要查询所有的部门和员工,将部门表设置成左表,员工表设置成右表
select * from dept;

insert into dept values(null,'销售部');

-- 使用内连接查询,新加的销售部没有
select * from dept d inner join emp e on e.dept_id = d.id;   
-- 因为销售部不符合条件,如果要显示销售部怎么办

-- 使用左外连接查询
select * from dept d left join emp e on e.dept_id = d.id;

-- 因为销售部没有员工,所以员工使用空对应
-- 左连接好处:保证左表中的数据全部出现,在内连接的基础上让左表中的数据全部出现

右外连接

语法

select * from 左表 right join 右表 on 主表.主键=从表.外键

案例

-- 希望员工的信息全部显示出来
-- 使用内连接查询 
select * from dept d inner join emp e on e.dept_id = d.id;

-- 使用右外连接查询 
select * from dept d right join emp e on e.dept_id = d.id;

-- 右连接的好处:保证右表中的数据全部出现,左边没有对应的数据使用NULL
-- 要保证左右表中所有的数据都出现,使用全连接
-- select * from dept d full join emp e on e.dept_id = d.id;
-- 全连接在mysql中不支持,Oracle中支持

子查询的概念

  1. 一个查询的结果做为另一个查询的条件
  2. 子查询是存在查询的嵌套,内部的查询称为子查询,外部的查询就是父查询
  3. 子查询必须要使用括号
    在这里插入图片描述
  4. 单行单列:父查询使用比较运算符
  5. 多行单列:父查询使用in, any, all
  6. 多行多列:父查询会做为一张虚拟表,再次进行查询

多表查询的规律

  • 确定查询哪些表
  • 确定表连接的条件
  • 确定查询哪些列
  • 如果还有条件,使用where进行过滤

索引查询数据方式

索引使用的是B树或B+树来存储,查询效率更高

  1. 索引表其实就是从原始表中抽取每个区域的一些数据组成一张表
  2. 查询的时候,先查询索引表,就可以确定记录在原始表中位置
  3. 再去查询原始表,通过2次查询可以找到记录

只要创建了索引表,在增删改原始表数据的时候,也可同时更新索引表中记录,如果一张表中索引表太多,维护成本也会更高,建议每表不超过5个索引

-- 对联系人的姓名列创建索引
create index ix_name on contact(name);

-- 显示指定表中所有的索引
show index from contact;

-- 删除上面创建的索引
drop index ix_name on contact;  -- 本质上是删除了索引表

-- 显示指定表中所有的索引
show index from contact;  -- 发现少了一个索引了

-- 创建名字和年龄的复合索引
create index ix_name_age on contact(name,age);
show index from contact; 

-- 删除复合索引
drop index ix_name_age on contact;

-- 只要创建了索引,我们查询相应列的时候,就会自动使用索引去查询

索引的使用原则和不足

使用原则

  1. 要在数据量大的表上创建索引才有意义
  2. 在经常查询的字段(列)上使用索引,如:where子句后面的条件,或表连接on后面的条件上
  3. 如果一张表的修改频率非常高,有大量的增删改的操作,而很少有查询操作,不建议创建索引。

不足

  1. 表中不建议创建太多的索引,索引过多会导致增删改的效率降低,因为它需要同时更新所有的索引表。
  2. 因为索引也是一张表,每创建一个索引都会占用一定的硬盘空间。

索引失效的几种情况

失效的几种情况

  1. 如果查询条件中有or,即使其中有些条件创建了索引,索引也不起作用,除非你对or中每个查询列都创建了索引。(mysql中测试也是无效的)
  2. 模糊查询like,查询以’%xxx’开头的不使用索引,以’xxx%'结尾会使用索引
  3. 使用了比较运算符<>或!= 不等于的运算符,不使用索引
  4. mysql如果发现不使用索引更快,则不使用索引。

函数

目标

  1. 字符串函数
  2. 数学函数
  3. 日期函数

字符串函数

-- 字符串函数
-- 返回字符串的长度,所有的函数以玫瑰红显示
select char_length('Hello');   -- 5个

-- 用于拼接一个或多个字符串
select concat('I ', 'Love ', 'Java');

-- 将字符串转成小写
select lower('HELLO WORLD');

-- 将字符串转成大写
select upper('hello world');

-- 取子字符串:字符串, 开始位置(从1开始),长度
select substr('Hello World', 7, 3);

-- 去掉前后的空格
select trim(' Hello Java ');

数学函数

-- 返回[0,1) 的随机小数,包头不包尾
select rand();

-- 四舍五入保留几位小数
select round(1.2345,3);

-- 返回一个列表中最小值
select least(30,4,28,10,9);

-- 返回一个列表中最大值
select greatest(30,4,28,10,9);

日期函数

-- 日期函数
-- 计算某个时间加多少天以后得到一个新的日期
select adddate('2019-02-28', 7);
select adddate('2019-02-28', -7);

-- 返回当前日期
select curdate();

-- 两个日期之间相差多少天,用前面的减后面的
select datediff('2001-1-1', '2001-1-5');

-- 计算你到现在活了多少天
select datediff(curdate(), '1999-11-11');

-- 得到当前的日期和时间
select now();

事务的概述

什么是事务

如果一个业务操作需要执行多条SQL语句,必须使用事务。事务就是这多条SQL语句必须是一个整体,每条SQL语句都要执行成功,这个事务才提交。如果其中有任何一条SQL语句出现了异常执行失败,整个事务都要进行回滚。回到没有执行前的状态。

事务就是要么所有的SQL语句全部执行成功,要么全部执行失败。

事务的四大特性(ACID)

事务特性含义
原子性(Atomicity)一个事务所有的SQL语句是一个整体,不可分割。要么全部成功,要么全部失败。
一致性(Consistency)对数据库中数据的操作状态在事务执行前后必须是一致的,
如:转账前2个人的总金额与转账后2个人的总金额是一致的
隔离性(Isolation)每个表中同时有多个事务在执行,事务与事务之间是隔离的,不能相距影响
持久性(Durability)如果一个事务执行成功,对数据库的影响是持久的,服务器关闭也是存在的。

事务操作

事务的操作MySQL操作事务的语句
开启事务start transaction
提交事务commit
回滚事务rollback
设置回滚点savepoint 名字
回到回滚点rollback to 名字
查询事务的自动提交情况select @@autocommit
设置事务的手动提交方式set @@autocommit

并发访问的问题

目标

  1. 哪三种并发访问问题
  2. 哪四种隔离级别

并发访问的三个问题

什么是事务的并发访问:在同一个时间段,有多个用户开启了事务,并且同时访问同一个表中记录,称为事务的并发访问。指多个事务在并行的执行。

事务在操作时的理想状态是: 不存在并发访问的问题,在实际的应用过程中,因为事务隔离级别不同,会出现以下三种并发访问的问题。

并发访问的问题含义
脏读一个事务读取到了另一个事务没有提交的数据
不可重复读正常来说,一个事务多次读取同一条记录结果应该是一致的,
如果出现多次读取不一致的情况,称为不可重复读。通常是
因为一个事务在读取数据,另一个读取更新了这条记录导致。
幻读一个事务在统计或查询的时候,2次出现查询的记录数不同。
通常是因为一个事务在统计,另一个事务插入或删除了记录导致。

因为会出现上面的三种并发访问的问题,所以我们需要避免这些问题的发生,避免的方式就是设置事务的隔离级别。

隔离级别越高,并发出现的问题就越少。在关系型数据库中一共有四种隔离级别。

在这里插入图片描述

隔离级别与安全性、性能的关系

隔离级别越高:安全性越高,性能就越低。

  1. 什么是不可重复读,如何解决?

    一个事务多次读取的数据不同,解决方式就是提高隔离级别到repeatable read。

  2. 什么是幻读,如何解决幻读?

    一个事务多次统计数据,得到数据条数不同。通常是由其它事务进行插入或删除操作导致。解决方式就是提高隔离级别为serializable。

  3. 什么是脏读?如何解决脏读的问题?
    一个事务读取到另一个事务未提交的数据,解决方法就是提高事务的隔离级别为read committed。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值