2.剑指JavaOffer-数据库

三大范式

image.png

image.png

image.png

如何设计一个数据库?

程序实例:存储管理(按块、页)、缓存机制(放在内存里,LRU)、SQL解析、日志管理、权限划分、容灾机制、索引管理、锁管理等模块
存储模块(文件系统)
索引和锁管理这块比较重要,可以看这个文章:数据库两大神器【索引和锁】

常见问题:
为什么要使用索引?
答:快速查询数据

什么样的信息能成为索引?
答:主键、唯一键和普通键等。

索引的数据结构

1.建立二叉查找树进行二分查找
查询效率:O(logn)
缺点:有可能退化成链表,检索深度每增加1就会发生一次I/O,大大降低了,速度,还不如一次I/O的全表扫描快

2.建立B-Tree结构进行查找
定义:根节点至少包括两个孩子,树中每个节点最多含有m个孩子(m>=2),除根节点和叶子节点外,其他每个节点至少有ceil(m/2)个孩子,ceil向上取,所有叶子节点都在同一层。
目的树让每个索引块尽可能多的存储信息,减少I/O次数
排序规则请看图:


三阶B树

3.建立B+Tree结构进行查找
与B树的不同
非叶子节点的子树指针与关键字个数相同
非叶子节点的子树指针pi,指向关键字值[ki,ki+1]的子树
非叶子节点仅用来索引,数据都保存在叶子节点中
所有叶子节点均有一个链指针指向下一个叶子节点(方便范围统计,大于等于某个值,横向的)


image.png

优点:
B+树的磁盘读写代价更低(没有指向关键字具体信息的指针,不放数据只存索引,内部节点更小)
B+树的查询效率更加稳定(必须走一条从根到叶子,都是logn)
B+树更有利于对数据库的扫描(最底部的那个横向指针)

4.建立Hash结构进行查找
查询效率比B+还快(只需一次定位就可以查询到值),但是,缺点:
1.仅仅满足 = IN ,不能使用范围查询(哈希之后的值不代表实际的大小)
2.无法被用来避免数据的排序操作(也是哈希值问题(哈希值不一定能代表哈希前的键值),没法提升order by)
3.不能利用部分索引键查询,组合索引不行
4.不能避免表扫描,桶中的数据还要查找(哈希一样的还是要链表扫描)
5.遇到大量Hash值相等的情况后性能下降。

5.位图索引
举例:二维表: 姓名 性别 婚姻状况
如果是b+树,给性别加索引,只会分成两半,查找数据时还是会取出一半的数据
比如此时有5个人
男:10100 代表第一个和第三个是男的,女:01011
这时候 婚姻状态
已婚的:11000,两个索引一联合查询,=男 and =已婚,只有第一个人符合
身份证号这种就不能做位图索引,每个人都不一样。

缺点:值只有固定的那几个,不适合高并发的,锁的行比较多,锁比较重。

密集索引和稀疏索引的区别:
密集索引文件中的每个搜索码值都对应一个索引值,聚集索引在叶子节点存储的是表中的数据
稀疏索引文件只为索引码的某些值建立索引项,非聚集索引在叶子节点存储的是主键和索引列,非聚集索引也叫做二级索引,辅助索引
使用非聚集索引查询出数据时,拿到叶子上的主键再去查到想要查找的数据。(拿到主键再查找这个过程叫做回表)

ps:有一种情况是不会回表的:现在我创建了索引(username,age),在查询数据的时候:select username , age from user where username = 'Java3y' and age = 20。 这种查询字段和索引都全部命中的。

如图所示:

image.png

MyISAM不管是主键索引还是唯一键索引或者普通索引,其索引都是稀疏索引,而InnoDB有且仅有一个密集索引,规则如下:


image.png

InnoDB使用密集索引把主键组织到一个B+树中,行数据就存在叶子节点上,where id = 14 直接就能拿到行数据, 而使用稀疏索引检索数据,比如 name = Ellison的,先在稀疏索引的B+树中检索该键值(Ellison),定位到了主键信息14,再去主键信息的B+树中查询 = 14的。
ps:创建多个单列(非聚集)索引的时候,会生成多个索引树(所以过多创建索引会占用磁盘空间)
MyISAM
不管是主键索引还是辅助键索引使用的都是稀疏索引,结构一致,只是存储的数据不同,数据和索引树分开存储的。比如id和name两个索引树,一个是id和地址信息弄成一棵树,一个是name和地址信息弄成一棵树。使用辅助键的时候自然就不需要访问主键索引树。

image.png

如何优化慢查询sql?
1.根据慢日志定位慢查询sql
先设置: set global slow_query_log = on;
set global long_query_time = 1
慢于1秒的都会比记录到日志中

2.使用explain分析sql
explain select .......
当type出现 index和all的时候可能需要调优了,还有就是extra:


image.png

3.修改sql或者让sql走索引
可以用force index强制使用某索引

联合索引的最左匹配原则的成因:
例如:where a=xx and b=xx 走联合索引
where a=xx 也走
where b=xx 就不走联合索引


image.png

按照(col3,col2)建的索引


image.png

越多越好吗?

锁模块:


image.png

InnoDB表级锁和索引无关,行级锁与索引有关,而没有索引的话则用的是表级锁,有索引则用的是行级锁
X排他锁(增删改和for update),S共享锁(lock in share mode)
读读不阻塞,读写阻塞,写写阻塞!如图:


image.png

MYISAM适合的场景:
频繁执行全表count语句(用一个变量保存的表的行数)

对数据进行增删改的频率不高,查询非常频繁(因为非聚集索引)
没有事务
InnoDB适合的场景:
数据增删改查都相当频繁
可靠性要求比较高,要求支持事务

image.png

自动锁:MYISAM的表锁,增删改的锁都是
显示锁: for update lock in share mode这种的

DML锁:对数据上的操作,DDL锁对表结构进行变更的
乐观锁(先改后锁,改的时候比较记录的数据版本:版本号和时间戳)、悲观锁(先锁后改)

数据库事务的四大特性:
原子性:事务包含的所有操作要么全部执行,要么失败回滚。
一致性:数据库应该满足完整性约束,转账钱不能少
隔离性:多个事务并发执行,一个事务不应该影响另一个事务的执行。
持久性:一旦提交,它对数据库的修改应该永久地保存在数据库中,确保数据库的数据不会丢失,redo.log

事务隔离级别以及各级别下的并发访问问题
1.更新丢失,mysql所有事务隔离级别在数据库层面上均可避免


image.png

2.脏读(读取到另一个事务未提交的数据)--READ-COMMITTED事务隔离级别以上可避免
先把级别改为最低的 read uncommited ,才会出现脏读:
例子:事务A在执行的过程修改了数据库中的数据,这时事务B插了进来,读取到了事务A修改之后的数据并且提交了上去,这时事务A由于某些原因进行了回滚,那么事务B读取的就是事务A的脏数据。
A1000块取钱100(1000-100),未提交,B进来读取到现在900块,接着存钱200(900+200)且提交,A回滚,则目前1100,其实应该是1200;

3.不可重复读-- REPEATABLE-READ事务隔离级别以上可避免
含义:事务A多次读取同一数据,事务在A多次读取的过程中对数据进行了更新并提交,导致事务A多次读取的结果不一致。
先把级别设置为 read commited以及以下才会出现

4.幻读--SERIALIZABLE事务隔离级别可避免
含义:事务A做更新操作,先查出来3条,事务B出现增加或者删除了,结果事务A发现更新的条数与原来查出来的不一样。
比喻:假如,中午去食堂打饭吃,看到一个座位是空的,便屁颠屁颠的去打饭,回来后,发现这些座位都还是空的(重复读),窃喜。走到跟前刚准备坐下时,却惊现一个恐龙妹,严重影响食欲。仿佛之前看到的空座位是“幻影”一样。(这人的解释老子他妈笑死)
InnoDB也可以在RR隔离级别也能实现避免幻读,后面总结。
SERIALIZABLE级别每句都会上锁。

image.png

事务级别越高,串行化就越严重,并发比较差,效率低。
Oracle默认read commited,mysql默认repeatable read

image.png
什么是当前读什么是快照读

快照读(就是不加锁的非阻塞读,就是最普通的select操作)不能是 SERIALIZABLE 级别的select(退化了,都加锁了),快照读有可能在RR级别下读到历史版本,创建快照的时机(更新后再读,如果首次调用时候还没更新,然后更新,更新了之后commit,再读还是历史版本)决定了读取数据的版本。

什么是MVCC?
(Multi-Version Concurrency Control)是一种多版本并发控制机制。

MVCC可以在大多数情况下代替行级锁,使用MVCC,能降低其系统开销,MVCC是通过保存数据在某个时间点的快照来实现的(使用 MVCC 读取的是快照中的数据,这样可以减少加锁所带来的开销。)

1.版本号
系统版本号:是一个递增的数字,每开始一个新的事务,系统版本号就会自动递增。
事务版本号:事务开始时的系统版本号。

2.隐藏的列
MVCC 在每行记录后面都保存着两个隐藏的列,用来存储两个版本号:
创建版本号:指示创建一个数据行的快照时的系统版本号;
删除版本号:如果该快照的删除版本号大于当前事务版本号表示该快照有效,否则表示该快照已经被删除了。

3.Undo.log
MVCC 使用到的快照存储在 Undo 日志中,该日志通过回滚指针把一个数据行(Record)的所有快照连接起来。

非阻塞读如何实现

每次操作会记录在undo log中,而这三种数据行:

undo日志

DB_ROW_ID主键一样的东西,每次更新操作DB_TRX_ID都会加1来记录版本号,DB_ROLL_PTR记录上一次更新操作的指针。
https://www.cnblogs.com/AnXinliang/p/9955331.html

总结:
快照读在RC、RR级别中:RR下,事务在第一个Read操作时,会建立Read View(读不到数据变更),所以看时机。
RC下,事务在每次Read操作时,都会建立Read View

RR级别如何避免幻读(伪MVCC+ next-key锁)
next-key锁:
行锁:顾名思义
gap锁:间隙锁,锁定一个范围但不包含记录本身,为了防止幻读


何时会用gap锁

select语句 where in 5 6 9 并没有9,部分命中,想插入7和8都是被阻塞的


锁部分区间
不走索引都锁
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,636评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,890评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,680评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,766评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,665评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,045评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,515评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,182评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,334评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,274评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,319评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,002评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,599评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,675评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,917评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,309评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,885评论 2 341

推荐阅读更多精彩内容