目录
联合查询
把多个表联合到一起进行查询 使用 笛卡尔积将 所有数据的排列组合 然后再进行条件筛选
笛卡尔积的两种方式:
1,表名与表名之间使用逗号隔开
2,表名 join 表名 on 条件
上述这样的联合查询其实都称为内连接
mysql中其实还有一种外连接
左外连接
左外连接以左侧表为准
右外连接
右外连接是以右侧表为准
三张表进行联合查询
select * from 表一 join 表2 on 条件1 join 表3 on 条件2
自连接
一张表自己和自己连接
自己和自己做笛卡尔积
把"行"转成"列"
SQL中进行条件查询,都是指定某一列/多个列之间进行关系运算,无法行和行之间关系运算,有时候为了实现这种行之间的比较就需要把行关系转换成列关系
自连接需要指定表的别名
与正常的查询一样 后面where 跟条件就好了
子查询
把多个查询语句合并成一个 (这个SQL语句会很长 建议有全部查出来之后再进行合并成一句)
合并查询
把两个查询语句的结果合并到一起
union 关键字 来完成
or和union的区别
or只能针对一个表,但是union可以把多个表的查询结合合并
union all 和 union 的区别
union all 不会去重 ; union会自动去重
MySQL索引事务
索引
索引存在的意义,就是为了加快查找速度
查找速度是快,但是付出了一定的代价
1,需要付出额外的空间代价来保存索引数据
2,索引可能会拖慢新增,删除,修改的速度
1,查看索引
show index from 表名
2,创建索引
create index 索引名 on 表名(列名)
删除索引
drop index 索引名称 on 表名;
索引后面的数据结构
B+树,索引的数据结构
B+ 树和B- 树的区别?
B+树的特点:
1,一个节点可以存储N个key,N个key 可以划分出N个区间
2,每个节点的key值在子节点中都会存在 并且key是子节点中的最大值
3,B+树的叶子节点,是首位相连的,类似一个链表
4,由于叶子节点是完整的数据的集合,叶子节点这里存储数据表的每一行的数据(在硬盘中),而非叶子节点,只存key值本身(在内存中)
B-(B)树的特点:
1,一个节点,可以存储N个key,N个key划分出N+1个区间
2,每个节点的key不存在于子节点
B+树的优点:
1,一给节点保存更多的Key,最终树的高度是相对更矮的,查询的时候减少了IO的访问次数(和B树是一样的)
2,所有的查询最终都会落到叶子节点上(查询任何一个数据,经历的IO访问次数都是一样的) B树相当稳定
3,B+树所有的叶子节点,构成链表,比较方便进行范围查询
4,由于数据都在叶子节点上,非叶子节点只存储Key,导致非叶子节点,占用空间是比较小的,这些非叶子节点就可能在内存中缓存(或者缓存一部分),又进一步减少了IO的次数
事务:
事务就是为了解决"执行一半"这样的问题
事务的本质就是把多个sql语句给打包成一个整体,要么全部执行成功,要么一个都不执行 ,而不会出现"执行一半"这样的中间状态
把sql语句打包成一个整体:就称为原子性 就表示不可分割的基本单位
一个都不执行:不是真的没执行,而是"看起来好像没执行一样",执行了,执行一半出错了,出错之后,选择恢复成未执行之前的状态了,这个恢复数据的状态就称为"回滚"
进行回滚的时候,那怎么知道回滚是恢复到什么样子的状态呢?
此处是需要额外的部分来记录事务中的操作步骤
使用事务的时候,执行sql的开销是更大的,效率是更低的
开启事务:
start transaction ;
提交事务:
commit
数据库的事务,四个关键的特性:
原子性
sql语句打包成一个整体
一致性
事务执行前后,数据得是靠谱的
就比如转账之前总和是1000,转账之后总和也得是1000
持久性
事务修改的内容是写在硬盘上的,持久存在的,重启也不会丢失
隔离性
隔离性是为了解决"并发"执行事务引起的问题
并发 : 一个服务器给多个客户端同时提供服务
引起的问题:如果并发的这些事务,是修改不同的表/不同的数据,那是没啥问题
如果修改的表是同一个/同一个数据,可能会存在问题
比如 多个客户端一起尝试同时对同一个账户进行转账,此时就有可能会把这个数据给搞乱了
并发处理事务,可能会有哪些问题,以及这些问题 数据库的隔离性是怎样解决的
并发处理事务,可能会有哪些问题,
一,脏读问题 (写操作加锁)
一个事务A正在对数据进行修改的过程中,并且在还没提交之前,另外一个事务B,也对同一个数据进行了读取,此时B的读操作就称为"脏读",读到的数据也称为"脏数据" 脏的意思是"无效"
就比如 考试的时候同学A瞄到了同学B的试卷,但是同学B故意写了一个错误的答案,让同学A抄走了,同学B再偷偷改正回来,同学A这个行为就称为脏读 那么读到的答案也称为脏数据
解决脏读问题,mysql引入"写操作加锁"
写操作加锁:写的时候不能看,写完了才能看
这个给写加锁操作,就降低了并发程度(降低了效率),提高了隔离性(提高了数据的准确性)
二,不可重复读(给读操作进行加锁)
第一次读到的数据和第二次读的数据不一样就称为不可重复读
事务1已经提交了数据,此时事务2开始读数据,在读取过程中,事务3又提交了新的数据,此时意味着同一个事务2之内蛮多次读数据,读出来的结果是不相同的
就比如 两个人一起存钱,其中A已经存了1000块钱,然后就告诉B说已经存了1000块钱了,你去看看,然后B就去看余额,然后一打开余额发现是1000块钱,然后他又打开了一次,发现变成了500,原来是因为A又取了500块钱
解决不可重复读问题 给读操作加锁
读操作加锁 :读的时候不能改,读完了才能改
通过这个读加锁,又进一步就降低了并发程度(降低了效率),提高了隔离性(提高了数据的准确性)
三,幻读(使用串行化 一个接一个的串行的处理事务)
当前已经约定了读加锁和写加锁,解决了不可重复读和脏读问题
在读加锁和写加锁的前提下,一个事务两次读取同一个数据,发现读取的数据值是一样的,但是结果集不一样
就比如,老师已经提交 了一份A代码,然后我们在读取A代码的时候,老师又提交了B代码,那么就有可能出现读着读着突然就冒出来一个B代码
幻读解决 数据库使用"串行化",彻底放弃并发处理事务,一个接一个的串行的处理事务
这样做并发程度是最低的(效率是最低的),隔离性是最高的(准确性也是最高的)
对应上述问题 mysql 提供了
4种隔离级别
read uncommitted 没有进行任何锁限制 效率最高
read commited 给写加锁 并发程度 降低,隔离性提高
repeatable read 给写和读都加锁 并发程度又降低,隔离性又提高
serializable 彻底串行化 并发程度最低,隔离性最高