dongyl
MySql 小记
Mysql梳理
1 索引简介
数据都是存放在 /usr/local/mysql 文件夹中的
Innodb 索引和数据是存放再一个文件内的
MyISAM 是存放在2个文件中的 MYI 索引 MYD 数据
2 索引分类
主键自带索引。
创建普通索引:
create index idx_name on tableA(name)
唯一索引:唯一列,列中的数据是唯一的,比普通索引性能好
create unique index idx_name on tableA(name)
联合索引:一次性为表中的多个字段创建索引 (最好不要超过5个字段)
create unique index idx_name_age on tableA(name,age)
最左前缀法则:
全文索引;
MyISAM 支持。
线性表
线性顺序表:
2个相邻的数据物理位置相邻
线性链式表:
相邻2个数据有先后的逻辑关系,和物理没有关系
\>链式
单向链表:
结点的结构 ===>> 数据内容,下一个数据的指针
双向链表:
通过当前节点找到上一个或下一个节点的位置。
结构: 上一个数据的指针+ 数据内容 +下一个数据的指针
顺序表和链式表的区别
数组:数据的查询性能 O(1) ,
增删 性能较差 。 增删一个 会造成整个数组的位置的改变。
查找快: 数组的每个元素占用空间相同,根据索引,索引*字节数,就能得到内存中的位置。
链表:查询性能 较差,时间复杂度 O (n)
增删性能较好。
栈,队列,串,广义表
- 栈: 先进先出,有顺序栈,链式栈
- 队列:先进先出,有顺序队列,链式队列
- 串: String 定长串,StringBuilder ,Buffer 动态串
- 广义表: 更加灵活的多维数组
树
- 多叉树 / 非二叉树
- 二叉树: 一个节点最多2个子节点,可以是 0,1,2 个子节点
二叉查找树: 根节点的数值,比所有左子树的节点的数值大,比右子树的节点的数值小
性能和树的高度有关。
- 平衡二叉树: 所有树及子树都应满足 => 左子树和右子树的深度差不能超过 1,如果不满足,那么平衡二叉树自己旋转。
- 红黑树
- B 树 : 允许一个节点存放多个数据,但是一个节点中到底呢个存放多少数据,决定 了树的深度
- B+ 树
非叶子节点 冗余了叶子节点中的键。
- 叶子节点是从小到大,从左到右排列的
- 叶子节点之间提供了指针,提高了区间访问的性能
- 只有叶子节点存放数据,非叶子节点不存放数据,只存放键。
哈希
使用哈希来存取数据是最快的,O(1) ,但是不支持范围查找(散列分布)
3 InnoDB 和 MyISAM 的区别
都是数据库引擎,但是在追求性能的情况下,一般使用 InnoDB。
InnoDB
将索引和数据放在一个文件中,通过找到索引后就能直接在索引树上的叶子节点中 获得完整的数据 。 ----聚集索引
可以实现行锁和表锁
MyISAM
索引和数据存放在2个文件中,查找到索引后还要去另一个文件中找数据,性能会慢一点 ---- 非聚集索引
除此之外,MyISAM 天然支持表锁。而且支持全文索引
问题:
为什么非主键索引的叶子节点存放的数据是 主键值?
如果不存放主键,而存放完整的数据那么就会数据冗余,维护麻烦
为什么 InnoDB 必要要创建主键?
如果没有主键,MySQL 会给一个虚拟的主键,普通索引会使用这个虚拟的索引 ----也会造成性能开销
为什么使用主键时推荐使用整型的自增主键?
整型?
主键索引树-树里的叶子节点和非叶子节点的键存放的是主键的值,而且这棵树是 二叉查找树,数据的存放是有大小顺序的。
整型: 大小顺序是很好比较的。
字符串: 字符串的自然顺序的比较要进行一次编码成为数值后在进行比较的。
uuid随机字符串
自增?
不用自增: 10 1 6 200 18 19,使用不规律的整数作为主键,那么主键索引树,会使用更多的自旋次数来保障索引的树的叶子节点从小到大,--从左到右排列。
4 联合索引和最左前缀法则
- 联合索引的特点:
最左前缀法则:
表示一条sql 有没有命中索引。
从mysql 8 后,全部都走索引。
5 Explain 分析SQL
id: sql 执行顺序。
type: 扫描方式 (索引,扫描全表)
possible—keys (可能用的索引)
key (真正用的索引)
ref (具体的索引)
filter 过滤的百分比
extra 会不会文件排序 (或临时表) ---- order by ,dsc ,对索引排序更高效,因为索引已经排序 了。
6 分库分表
垂直拆分:专库专用
一个数据库由很多表的构成,每个表对应着不同的业务,垂直切分是指按照业务将表进行分类,分布到不同的数据库上面,这样也就将数据或者说压力分担到不同的库上面
水平拆分:
垂直拆分后遇到单机瓶颈,可以使用水平拆分。
相对于垂直拆分的区别是:垂直拆分是把不同的表拆到不同的数据库中,而水平拆分是把同一个表拆到不同的数据库中。
相对于垂直拆分,水平拆分不是将表的数据做分类,而是按照某个字段的某种规则来分散到多个库之中,每个表中包含一部分数据。
简单来说,我们可以将数据的水平切分理解为是按照数据行的切分,就是将表中 的某些行切分到一个数据库,而另外的某些行又切分到其他的数据库中,主要有分表,分库两种模式。