如何设计一个数据库
RDBMS 需要2个部分组成:
- 存储(文件系统)
- 程序实例:存储管理 + 缓存机制 + SQL解析 + 日志管理 + 权限划分 + 容灾机制 + 索引管理 + 锁管理
索引
二叉树插入数据多了会变成链表,而平衡二叉查找树,左右子树高度差不得超过1,时间复杂度O(logn),会产生非常多IO次数。
B-Tree
-
根节点至少包括两个孩子。
-
树中每个节点最多含有m个孩子(m>=2)
-
除根节点和叶节点,其他节点至少有m/2个孩子
-
所有叶子节点都位于同一层
B+-Tree索引
B+树是B树的变体,区别如下。
- 非叶子节点的子树指针与关键字个数相同
- 非叶子节点的子树指针P[i],指向关键字[K[i],K[i+1]]的子树
- 非叶子节点只用来保存索引,叶子节点存储数据
- 叶子节点均有一个链指针指向下一个叶子节点(按大小顺序排序,可做范围统计)
- 磁盘读写代价低。
- 查询效率更加稳定(根节点到叶子节点)
- 有利于对数据库的扫描(频繁使用范围查询)
HASH索引
- HASH索引查询效率比B+高,满足“=”,“IN”,但不能使用范围查询。
- 无法被用来避免数据的排序操作。
- 不能利用部分索引引键查询。
- 不能避免表扫描
- 大量HASH值相等的情况性能低下
BitMap索引
oracle支持。 适用于某个字段固定几种的格式。锁的代价非常高,不适合高并发情况。
密集索引与稀疏索引
- 密集索引文件中的每个搜索码值对应一个索引值
- 稀疏索引文件只为索引码的某些值建立索引项
InnoDB
- 若一个主键被定义,该主键作为密集索引
- 若没有主键被定义,该表的第一个唯一非空索引作为密集索引
- 不满足以上条件,innodb内部生成一个隐藏主键(密集索引)
- 非主键索引存储相关键位和其对应的主键值,包含两次查找(先查自身,再差主键)。
如何定位慢查询sql:
- 根据慢日志定位sql
- explain分析sql
联合索引最左匹配原则成因
- mysql会一直向右匹配直到遇到范围查询(>,<,between,like)就停止匹配。 (例如a=3 and b=3 and c>5 and d=6)如果是(a,b,d,c)索引则可以用到。而(a,b,c,d)d用不到索引。
- =和in可以乱序,mysql有查询优化器。
- mysql创建联合索引是从左开始(相当于order by第一个字段,再去排序下一次字段)
索引越多越好吗
- 数据变更需要维护索引/空间/开销
MyISAM适合场景
- 频繁执行全表count语句
- 对数据进行增删改频率不高,查询频繁
- 没有事务
InnoDB适合场景
- 增删改频繁
- 可靠性要求高,支持事务
MyISAM与InnoDB关于锁方面区别
- MyISAM表级锁,不支持行级锁
- InnoDB默认行级锁,支持表级锁
数据库锁的分类
- 锁粒度 表级锁、行级锁、页级锁
- 锁级别 排他锁 、共享锁(lock in share mode)
- 加锁方式 自动锁、显式锁
- 操作 DML锁、DDL锁
- 使用方式 乐观锁、悲观锁