关系数据库设计 存储模块、缓存机制、sql解析、日志管理、权限划分、容灾机制、索引管理、锁管理 平衡二叉数: 可以是空树。 假如不是空树,任何一个结点的左子树与右子树都是平衡二叉树,并且高度之差的绝对值不超过 1。 b树: 根节点至少包含2个孩子
树中的每个节点最多含有m个孩子(m>=2),m阶树
除了根节点和叶子节点,其他每个节点至少含有ceil(m/2)个孩子,ceil:向上取整
所有叶子节点都位于同一层
节点最左边的数据大于节点最左边子节点的所有数据,
节点最右边的数据小于节点最右边子节点的所有数据
非终端节点中的数据是升序的
存储个数少于指向的指针个数
中间节点的数据位于父节点的开区间中
b+树 非叶子节点的子树指针与关键字相同
非叶子节点的值小于等于该值指向的叶子节点的指针内存存储的数据
非叶子节点仅用于索引,数据保存在叶子节点中
所有叶子节点均有一个指针指向下一个叶子节点,并按顺序排列
mysql索引: 最左匹配原则遇到范围查询就停止 范围查询:大于小于,between,like Type为index需要优化 事务: ACID A:原子性:要么做,要么不做
C:一致性,数据一致性
I:隔离性:多个事务并发执行,相互之间不影响
D:持久性,事务一旦提交数据就持久化了
Rr隔离下a事务在b事务提交前读取的是旧数据
Rr隔离下a事务在b事务提交后读取的是新数据
锁:
MyISAM 默认表级锁,不支持行级锁
InnoDB默认用的是行级锁,也支持表级锁
MyISAM:
读取的时候加上读锁,此时修改,但要等待读锁释放
读锁是共享锁,一个会话拿到锁,另一个会话也能读取
当上了写锁,再上读锁是不行的(再另一个会话中读取)
写锁:排它锁(悲观锁)
for update :加入排它锁
InnoDB
lock in share mode(当前读):共享读锁,其他会话无法加读锁 (对同一行可以多次加),不走索引的时候,整张表都会被锁住
读锁:共享锁,
当前读:读取数据最新版本,会对读取的数据加锁
快照读:当前事务下的快照数据(不一定最新版本)
幻读解决方案:
快照读:通过Mvcc(版本控制)来避免幻读
当前读:通过next-key(行锁+间隙锁)来控制欢度
如果where子句里通过非索引项来查找数据,则会使用表锁。
如果通过普通索引来查找数据,则会使用间隙锁。
如果使用唯一索引来查找数据,则会降级为行锁。
如果使用唯一索引查找一条不存在的数据,则会使用间隙锁。
如果使用唯一索引范围查找,则会使用间隙锁。
间隙锁:
MySQL(主键或唯一索引)部分命中会加间隙锁,全部命中则不加
就是例如1.5.9如果删除等于3的数据,则会锁住开区间为1.5的数据 此时不能插入2.4的数据,间隙锁(gap锁)都是左开右闭的区间
列如:10.13.20,锁为(负无穷,10】,(10,13】,(13,20】,(20,正无穷,如果不是唯一索引或者主键,则会对主键列也上间隙锁
间隙锁用于非唯一索引或不走索引的当前读中
死锁:
-- 表语句
CREATE TABLE `cs` (
`id` int(11) NOT NULL,
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`age` int(11) NULL DEFAULT NULL,
`nick_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx`(`name`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of cs
-- ----------------------------
INSERT INTO `cs` VALUES (1, '2', 3, '2');
-- 产生死锁
-- 会话1
BEGIN ;
insert IGNORE INTO cs VALUES (1,'2',3,'4');
-- SELECT * FROM cs WHERE `name` ='2' LOCK IN SHARE MODE;
UPDATE cs SET nick_name ='asdasd' WHERE `name` = '2';
ROLLBACK;
-- 会话2
BEGIN;
UPDATE cs SET nick_name ='asdasd' WHERE `name` = '2';
ROLLBACK;
--- 2个会话同时启动事务,先执行会话一第一条语句,再执行会话二语句,最后执行会话1第二条语句,产生死锁