Mysql存储引擎之TokuDB以及它的数据结构Fractal tree(分形树)
在目前的Mysql数据库中,使用最广泛的是innodb存储引擎。innodb确实是个很不错的存储引擎,就连高性能Mysql里都说了,如果不是有什么很特别的要求,innodb就是最好的选择。当然,这偏文章讲的是TokuDB,不是innodb,相比innodb,TokuDB有着自己的特点。
BTree和Fractal tree的比较:
目前无论是SQL Server,还是MySQL的innodb,都是用的B+Tree(SQL Server用的是标准的B-Tree)的索引结构。从理论上来说,这个结构在查询过程中应该是不会慢的,此类基于比较的数据结构查询复平均杂度都是logn。B类树就是对于这个进行了优化,让它更适应磁盘,降低树的深度。
随机IO几乎是令所有DBA谈虎色变的一个问题,当数据量小的时候,所有数据都能到内存中那就没有这个问题(其实这个时候也就没有必要用B-Tree的这种块结构了),但是一旦数据量大于内存的话这个问题就出现了。其实从本质来说,k-v存储要解决的问题就是这么一个:尽可能快得写入,以及尽可能快的读取。
这也是设计数据结构时考虑最多的问题,在分析解决方法之前,我们讨论几个极端。走一个极端的话,如果我每次写数据都顺序写,那么对Insert来说的话是最快的,但是每次Query就需要Scan一遍整个表。那么如果我想获取最佳的读性能,那么方法就是像B-Tree那样全部排个序呗。但是因为B-Tree有那样的随机IO,这样我们有没有办法得到顺序写的写性能,
所以,TokuDB中使用了一个称之为Fractal tree(分形树)的索引结构来解决随机IO的问题。它主要是能让随机IO变成顺序IO。
| Structure | Inserts | Point Queries | Range Queries |
| B-Tree | Horrible | Good | Good (young) |
| Append | Wonderful | Horrible | Horrible |
| Fractal Tree | Good | Good | Good |
Fractal tree(分形树)简介
我们假设有这样一种集合的结构,相邻行空间加倍。每一行要么全满要么全空,全满行的数据都是排好序的。
数据插入:

以上图的数据存储状态为例,如果再写一个值的时候,会写在第一行,比如写了3,这个时候第一行是空的,所以就放到第一行。
再写一个值11的时候,因为第一行已经写满了,所以将3取出来,和11做排序,尝试写第二行。
又因为第二行也满了,所以将第二行的5和10也取出,对3,11,5,10进行排序。写入第三行。
最后的结果:

总体来看:

可以看出,这个数据结构能保证数据块都是满的。如果前面都满了,就会一层层合并下去,直到找到可以写入的块。
没明白的:
插入复杂度为O(log(N)/B),B是一个块存储的数据行数,N是数据量。但是我只想到O(N/B)的复杂度。据说是进行了优化得到的,不过没看懂。
提一下:BTree的复杂度为O(log(N)/log(B)),这是树的深度。B其实就是树的度,树的度越大,深度越低,成对数关系。
总结下Fractal Tree结构特点
- 由多个有序的数组构成,大小呈指数级增长
- 数组要么全空,要么全满
- 数据插入到最小的数组,如果空间不够就将数据进行Merge
查询性能:
如果不进行优化,查询性能并不好。我们需要扫描每一层,最坏情况下IO次数达 log2N。
为了提高查找的性能,TokuDB在每个数据上加了一个forwardpointer,指向下一行中第一个比它大的数据的位置(这个叫做Fractional Cascading)。平均地看,上一级的每个数都把下一级搜索范围限制到了常数个,所以磁盘IO的次数最差应该为O(logN)。

看到的另一种优化办法:

总结:
TokuDB主要的优点在于把随机的IO转换成顺序的IO写入。因此获得很好的写入速度,也因为这个,有很好的数据压缩效果。但如果是顺序写入,性能不如BTree。
因此,它适用于存档,大量随机插入的场景。
整个分形树设计感觉有点像二进制优化的逆向处理。是个挺有意思的数据结构。
参考资料:
How TokuDB Fractal Tree Databases Work Presentation
转载请注明:旅途@KryptosX » Mysql存储引擎之TokuDB以及它的数据结构Fractal tree(分形树)
Mysql存储引擎之TokuDB以及它的数据结构Fractal tree(分形树)的更多相关文章
- MySQL 高性能存储引擎:TokuDB初探
在安装MariaDB的时候了解到代替InnoDB的TokuDB,看简介非常的棒,这里对ToduDB做一个初步的整理,使用后再做更多的分享. 什么是TokuDB? 在MySQL最流行的支持全事务的引擎为 ...
- MySQL-TokuDB:MySQL 高性能存储引擎:TokuDB
ylbtech-MySQL-TokuDB:MySQL 高性能存储引擎:TokuDB 1.返回顶部 1. 在安装MariaDB的时候了解到代替InnoDB的TokuDB,看简介非常的棒,这里对ToduD ...
- 7.Mysql存储引擎
7.表类型(存储引擎)的选择7.1 Mysql存储引擎概述 mysql支持插件式存储引擎,即存储引擎以插件形式存在于mysql库中. mysql支持的存储引擎包括:MyISAM.InnoDB.BDB. ...
- MySQL存储引擎对比
MySQL存储引擎对比 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.MySQL的存储引擎 大家应该知道MySQL的存储引擎应该是表级别的概念,因为我们无法再创建databas ...
- MySQL存储引擎InnoDB大量数据下的问题
MySQL如果只有MyISAM一个引擎的话,那你们黑真的也有道理,但问题是InnoDB现在已经是MySQL默认的引擎,而且这个引擎综合能力很强,能用好这个引擎其实就已经能解决大多数需要数据库的业务逻辑 ...
- mysql基础之-mysql存储引擎概述(八)
0x01 mysql 存储引擎:存储引擎也通常被称作“表类型” mysql> show engines; --- 查看当前所有所支持的存储引擎 mysql> show table st ...
- Mysql存储引擎及选择方法
0x00 Mysql数据库常用存储引擎 Mysql数据库是一款开源的数据库,支持多种存储引擎的选择,比如目前最常用的存储引擎有:MyISAM,InnoDB,Memory等. MyISAM存储引擎 My ...
- Mysql存储引擎比较
Mysql作为一个开源的免费数据库,在平时项目当中会经常使用到,而在项目当中我们的着重点一般在设计使用数据库上而非mysql本身上,所以在提到mysql的存储引擎时,一般都不曾知道,这里经过网上相关文 ...
- MySQL存储引擎之Myisam和Innodb总结性梳理
Mysql有两种存储引擎:InnoDB与Myisam,下表是两种引擎的简单对比 MyISAM InnoDB 构成上的区别: 每个MyISAM在磁盘上存储成三个文件.第一个 文件的名字以表的名字开始 ...
随机推荐
- [Basic Information Theory] Writen Notes
- POJ 3608 Bridge Across Islands --凸包间距离,旋转卡壳
题意: 给你两个凸包,求其最短距离. 解法: POJ 我真的是弄不懂了,也不说一声点就是按顺时针给出的,不用调整点顺序. 还是说数据水了,没出乱给点或给逆时针点的数据呢..我直接默认顺时针给的点居然A ...
- AC日记——阶乘和 openjudge 1.6 15
15:阶乘和 总时间限制: 1000ms 内存限制: 65536kB 描述 用高精度计算出S=1!+2!+3!+…+n!(n≤50) 其中“!”表示阶乘,例如:5!=5*4*3*2*1. 输入正整 ...
- Concurrency::task(C++)
先看一个例子 #include <ppltasks.h> #include <iostream> using namespace Concurrency; using name ...
- SQL部分 数据库的建立 增删改查
数据库: 结构化查询语言(Structured Query Language)简称SQL: 数据库管理系统(Database Management System)简称DBMS: 数据库管理员(Data ...
- Java线上应用故障排查之二:高内存占用
搞Java开发的,经常会碰到下面两种异常: 1.java.lang.OutOfMemoryError: PermGen space 2.java.lang.OutOfMemoryError: Java ...
- poj2632 Crashing Robots
Crashing Robots Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9859 Accepted: 4209 D ...
- javascript删除元素节点
1.删除元素父节点 function removeElement(_element){ var _parentElement = _element.parentNode; if(_parentElem ...
- 机器学习实战--logistic回归
#encoding:utf-8 from numpy import * def loadDataSet(): #加载数据 dataMat = []; labelMat = [] fr = open(' ...
- html中label宽度设置、非替换元素和替换元素
<label ></label> 单独对label设置一个width:100px的属性石不起作用的,和float:left或者display:inline-block配合的话 ...