胡咧咧之MySQL

MySQL基础知识

三大范式:

  • 每个列都不可以再拆分。(例如姓名只能有一个,不可拆分)
    前面表不符合第一范式,拆分成后面的表
  • 在第一范式基础上,非主键列完全依赖于主键,而不能是依赖于主键的一部分。(一个表只描述一件事情)

1、皮肤价格依赖于皮肤,英雄价格依赖于英雄。不满足非主键完全依赖于主键。
在这里插入图片描述
拆分之后:第一种满足第二范式,第二种通过添加皮肤id,让其他逐渐完全依赖于id
在这里插入图片描述
在这里插入图片描述

2、不同时间下了相同的单,所以主键必须是“订单号”+“产品号” ,订单时间和订单金额不完全依赖于订单号
在这里插入图片描述

  • 在第二范式基础上,非主键列只能依赖于主键,不依赖于其他非主键(消除传递依赖)。
    (每一列数与域主键直接相关,不能是间接相关,之间必须相互独立,不存在其他函数关系)
    在这里插入图片描述
    规范性和性能
    关联查询的表不得超过三张表
  • 规范性
  • 故意增加一些冗余的字段(多表查询变为单表查询)
  • 故意增加一些计算列(几百万数据从大数据量降低为小数据量)

数据类型

  • 整数类型
    包括:tinyint(1字节 极小的)、smallint(2字节 小的)、mediumint(3字节 中等的)、int(4字节)、bigint(8字节)
    加上unsigned修饰,表示数据是无符号的,即非负整数。
    int(5) 属性为unsigned、zerofill(补零):插入12,数据库实际存储数据为00012
  • 实数类型
    float、double、decimal
    decimal:压缩严格的定点数(存储比bigint还大的整数,能存储精确的小数)
    float、double 比 decimal 效率高,decimal理解为字符串处理

java中3*0.1==0.3将返回fale:因为浮点数不能完全精确的表示出来,一般会损失精度。

  • 字符串类型
    varchar、char、text、blob
    varchar:可变字符串,必定长类型更加节省空间
    使用额外1/2字节存储字符串长度(小于255 使用1字节表示)
    超出设置长度,内容会被截断
    char:定长,根据字符串长度分配内存
    根据需要填充空格方便比较
    适合存储较短的字符串/所有值都接近一个长度
    存储内存超过设长,内容会被截断
    使用策略:
    经常变更,char更好,因为不易产生碎片
    非常短的列,char在存储空间上更有效率
    只分配需要的空间,更长的排序时会消耗更多的内存
    尽量避免使用text/blob,查询时会使用临时表,导致严重性能开销
  • 枚举类型:把不重复的数据存储为预定义的集合
    有时可以enum代替字符串类型
    enum存储非常紧凑,会把列表值压缩到1-2字节
    内部存储时存的是整数,所以尽量避免数字作为enum的常量,会造成混乱
    排序使用的内部的整数
  • 日期和时间类型
    尽量使用timestamp,空间效率高于datetime,
    用整数保存时间戳通常不方便处理。
    如果需要存储微妙,可以使用bigint存储。
    year YYYY 1901~2155
    time HH:MM:SS -838:59:59~838:59:59
    date YYYY-MM-DD 1000-01-01~9999-12-3
    datetime YYYY-MM-DD HH:MM:SS 1000-01-01 00:00:00~ 9999-12-31 23:59:59
    timestamp YYYY-MM-DD HH:MM:SS 19700101 00:00:01 UTC~2038-01-19 03:14:07UTC

引擎

InnoDB:提供对数据库的ACID事务支持。提供了行级锁和外键约束。处理大数据容量的数据库系统
存储结构:所有的表存在有一个数据文件中
存储空间:需要更多的内存和存储,会在内存中建立专用的缓冲池,用于高速缓存数据和索引

文件格式:索引和数据是集中存储的,.ibd

存储顺序:按主键大小有序插入

外键:支持
事务:支持

锁支持:默认行级锁,支持表级锁,锁定力度小并发能力高

insert、update、delect:更优

索引
实现方式:B+树索引,索引组织表,
哈希索引:支持
全文索引:不支持
聚簇索引,主键索引的叶子节点存储的是行数据,主键索引非常高效、非主键索引的叶子节点存储的是主键和其他索引的列数据,查询时做到覆盖索引会非常高效
MyISAM:(原MySQL的默认存储引擎)不提供事务,不支持行级锁和外键
存储结构:每张表存放在三个文件 frm 表定义、MYD 数据文件、MYI 索引文件
存储空间:可被压缩,存储空间小
文件格式:数据和存储是分开存储

存储顺序:按记录插入顺序保存

外键:不支持
事务:不支持

锁(避免资源争用的机制)支持:表锁定

select:更优
select count(*):更快,内部维护了一个计数器,可直接调取

索引
实现方式:B+树索引,堆表,
哈希索引:不支持
全文索引:支持
非聚簇索引,索引的叶子节点存储的是行数据地址,需要再寻址一次才能得到数据
Memory:数据在内存中,处理速度快,安全性不高
InnoDB四大特征:插入缓存、二次写、自适应哈希索引、预读
存储引擎选择:
没有特殊需求,默认InnoDB即可
MyISAM:以读写插入为主的应用程序,例如博客、新闻门户
InnoDB:更新(删除)操作频率高,需要保证数据完整性;并发量高,支持事务和外键;例OA自动化办公系统

索引(数据库排序的数据结构,相当于目录,是一个文件)

**缺点:**创建索引和维护索引需要时间,对表进行增加、删除、修改的时候,索引也要动态维护,而且需要占用物理内存

创建索引方式:

  • create table 时创建:
    在这里插入图片描述

  • 使用alter table 去增加索引
    alter table 表名 add index 索引名(字段名);

  • 使用create index命令创建,增加普通索引或唯一索引,不能创建主键索引
    create index 表名 on 索引名(column)
    删除索引:
    alter table 表名 drop key 索引名

索引类型:

  • 主键索引:数据列不允许重复,不允许null,PRIMARY KEY(主键);
  • 唯一索引:数据列不允许重复,不允许null,alter table 表名 add unique(column)/unique(column,column2)唯一联合索引
  • 普通索引:允许重复,可以为null,alter table 表名 add index 索引名(索引字段)/index 索引名(字段名1,字段名2)普通组合索引
  • 全文索引:搜索引擎关键技术,alter table 表名 add 索引名(字段名)

使用场景(explain):

  • where :仅建立主键索引,可选索引只有主键索引,如果有多个会选择较优的作为检索的依据
  • order by:排序时,如果没有建立索引,会使用外部排序,很耗性能。建立索引:alter table 表名 add index(字段名),索引本身是有序的,直接按照索引的顺序和映射关系逐条取出数据。
    如果有分页,只需要取出索引表某个范围内的索引对应数据
  • join:
  • 索引覆盖:如果查询的字段都建立过索引,引擎直接会在索引表中查询而不会访问原始数据,否则只要有一个字段未建立索引就会做全表扫描。
    因此select 后只写必要的查询字段,增加覆盖索引的几率

索引的数据结构:

  • hash索引:底层树结构为哈希表,绝大多数需求为单条记录查询时,可以选择hash索引,查询性能快
    在这里插入图片描述

  • B+树索引(InnoDB默认实现):大部分场景适用于BTree索引
    在这里插入图片描述
    主键索引区:PI(关联保存的实时数据地址)按主键查询
    普通索引区:si(关联id的地址,然后在到达上图地址)所以按照主键查询,速度最快

B+tree性质:
1、n颗子tree的节点包含n个关键字,不用来保存数据而是保存数据的索引
2、所有的叶子节点包含了全部关键字信息,及指向关键字记录的指针,叶子节点本身依关键字的大小自小而大顺序链接
3、所有非终端结点可以看成索引部分,结点仅包含子树中最大(或最小)关键字
4、数据插入和删除仅在叶子节点进行
5、有两个头指针,一个是树的根节点,一个是 最小关键码的叶节点

创建索引的原则:
1、最左前缀匹配原则,mysql一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配
例如: a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d) 顺序的索引,d用不到索引,如果建立(a,b,d,c)的索引则都可以用到,因为abd顺序可以调整
2、较为频繁作为查询条件的字段才去建立索引
3、更新频繁的字段不适合建立索引
4、不能有效区分数据的列不适合做索引列(性别)
5、尽量的拓展索引,不要新建索引。
例如表中已有a的索引,要加(a,b)索引,只需要修改原来的索引即可
6、定义有外键的数据列一定要建立索引
7、对于查询中很少涉及的列,重复值比较多的不要建立索引
8、定义为text、image和bit的数据类型的列不要建立索引

百万级别或以上的数据如何删除:
MySQL官方手册告诉我们删除数据的速度和创建索引的速度是成正比的。
1、先删除索引
2、删除无用数据
3、重新创建索引
比之前删除绝对快,之前的删除中断,会回滚删除

事务

ACID 四大特征:一致性,要么做,要么不做

  • 原子性A:最小执行单位,不允许分割。确保动作要么全部完成,要么全部不起作用。
  • 一致性C:执行事务前后,数据保持一致。(多个事务读取数据结果一致)
  • 隔离性I:一个事务不被其他事务干扰,各并发事务之间数据库是独立的
  • 持久性D:一个事务提交后,对数据库中数据改变是持久的,即使数据库发生故障也不应该对其有任何影响。

脏读、幻读、不可重复读:

  • 脏读:A事务update数据,B事务读取了同一份数据。A事务RollBack后,B事务读取的不正确。
  • 不可重复读:B事务两次读取数据不一致,中间 A事务update数据并且commit了
  • 幻读:后来读取到的数据比第一次读取到的条目多。A事务查询了N条数据,B事务此时插入了N条数据之外的M条或者添加了M条符合A搜索条件的数据,导致A事务再次查询发现N+M条数据,(并且插入相同数据失败。)

不可重复读与幻读比较:前者争对update、delete,后者争对insert

事务的隔离级别:

  • 读取未提交 READ-UNCOMMITTED;最低的隔离级别,允许读取尚未提交的数据变更,会导致脏读、幻读、不可重复读
  • 读取已提交 READ-COMMITTED(Oracle默认):允许读取并发事务已经提交的数据,会产生幻读和不可重复读
  • 可重复读 REPEATABLE-READ(Mysql默认):多次读取结果一致,会产生幻读
  • 可串行化 SERIALIZABLE: 完全符合ACID,事务逐个执行互不干扰

对MySQL锁了解吗?
并发事务可能会产生数据不一致,需要锁机制来保证访问次序。
就比如酒店房间,给房间上锁,拿到钥匙的人才能入住并且锁起来,其他人只能到到使用完毕才能再次申请使用。
隔离级别与锁的关系:
Read Uncommitted级别下,读取数据不需要加共享锁,不会跟被修改的数据的排他锁冲突
Read Committed级别下,读操作需要加共享锁,但是在语句执行完以后释放共享锁;
Repeatable Read级别下,读操作需要加共享锁,但是在事务提交之前并不释放共享锁,也就是必须等待事务执行完毕以后才释放共享锁。
SERIALIZABLE 是限制性最强的隔离级别,因为该级别锁定整个范围的键,并一直持有锁,直到事务完成。

按照锁的粒度分数据库锁有哪儿些?行级锁、表级锁、页级锁

开销从大到小,并发能力从大到小

  • 行级锁:(InnoDB引擎默认,同时支持表级锁)粒度最细,表示只针对当前操作进行加锁 
    行级锁分为 共享锁和排他锁
    特点:开销大,加锁慢,锁定粒度最小,或出现死锁,发生锁冲突的概率最低,并发度最高

  • 页级锁:(BDB引擎)锁定粒度介于行级锁和表级锁中间的一种锁。
    特点:开销和加锁时间介于表锁和行锁之间,会出现死锁,锁定粒度界于行级锁和表级锁之间,并发能力一般

  • 表级锁:(MyISAM引擎)粒度最大的锁,对当前操作的整张表加锁
    表级锁分为:表共享读锁(共享锁)、表独占写锁(排他锁)
    特点:开销小,加锁快,不会出现死锁,锁粒度大,发生冲突概论最高,并发度最低

从锁的类别来讲分为:共享锁、排他锁
- 共享锁(读锁):当用户要进行数据读取时,对数据加上共享锁。可以同时加上多个

- 排他锁(写锁):当用户要进行数据的写入时,对数据加上排他锁。只可以加一个,和其他排他锁、共享锁都排斥

酒店来举例的话,多个用户一起看房可以接受,但是入住了以后,住房和看房的都不可以了。

MySQL中的InnoDB引擎的行锁是怎么实现的?
InnoDB基于索引来完成行锁:select * from tab_with_index where id=1 for update
for update可以根据条件来完成行锁 ,并且id是有索引键的列

什么是死锁?
两个或多个事务在同一资源上互相占用,并请求锁定对方的资源。

死锁解决办法:

  • 不同程序并发存取多个表,尽量约定以相同的顺序访问表
  • 同一个事物,尽可能做到一次锁定所需要的所有资源
  • 对于非常容易产生死锁的业务部分,可以尝试使用升级锁定颗粒度,通过表级锁定来减少死锁概率

乐观锁和悲观锁?

  • 悲观锁:假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作。查询完数据的时候就把事务锁起来,直到事务提交。
    实现方式:数据库锁机制
  • 乐观锁:假定不会发生冲突,只在提交操作时检查是否违反数据库完整性 。再修改数据的时候把事务锁起来,通过version的方式锁定。
    实现方式:使用版本号机制或CAS算法
    使用场景:
    乐观锁适用于写比较少情况,即冲突很少发生。
    悲观锁适用于多写的情况,即冲突经常发生。

视图

存储过程与函数

触发器

SQL优化

谈谈explain
对于查询语句,最重要的优化方式就是使用索引。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值