为什么阿里巴巴编码规范建议“单表行数超过500万行或者单表容量超过2GB,才推荐进行分库分表。”?
网络上有一些资料说,数据超过500万行时就该进行分库分表,这样的说法是不严谨的,抛开容量只谈行数是错误的,接下来以一颗三层的B+树为例来分析。
B+树是由一个一个的磁盘页组成的,为了提高效率,MySQL中的数据是按行存储,按页读取的,页的大小默认是16KB,可以通过以下SQL语句查询得知:
show Global status like 'Innodb_page_size';
而每一页的结构组成如下:
由图可知,一个页真正用于存放的大小只有16384-200=16184B.
一颗三层B+树能存放的数据行数=所有磁盘页的数量 X 一页能存放的数量
假设有这样一张表:
CREATE TABLE t1(
a int(11) PRIMARY KEY,
b int(11) ,
c int(11) ,
d int(11) ,
e varchar(20) CHARACTER SET utf8mb4
) ENGINE = INNODB ;
在这张表中,一行数据大约占用了 4X4+(4X20+2)=100B.
所以,一页大概能存储161行的记录,那么一个三层的B+树一共有多少个结点呢?
B+树的一个显著特征是非叶子节点不存储数据,只存索引,索引中每个页指针6B,每个键4B,共10B.
一页能存储约1618个指针,第二层就是2617924个指针,叶子节点最终一共能存储的页数也就是这个数字。
所以,回到开头所说,一颗三层的B+树最多能存储421485764行数据。三层的B+树是一个比较理想的结构,只需要经过三次磁盘IO就能定位到数据。
阿里规范中提到的500W行数据远不及此,其考虑应该是服务器的资源性能和备份进行的可操作性。
Comments NOTHING