住房建设部官方网站专家注册,电商网站设计培训,企业做不做网站的坏处,设计一个品牌参考#xff1a;
#x1f525;我说MySQL每张表最好不超过2000万数据#xff0c;面试官让我回去等通知#xff1f; - 掘金 考虑到磁盘IO是非常高昂的操作#xff0c;计算机操作系统做了预读的优化#xff0c;当一次IO时#xff0c;不光把当前磁盘地址的数据#xff0c;… 参考
我说MySQL每张表最好不超过2000万数据面试官让我回去等通知 - 掘金 考虑到磁盘IO是非常高昂的操作计算机操作系统做了预读的优化当一次IO时不光把当前磁盘地址的数据而是把相邻的数据也都读取到内存缓冲区内因为当计算机访问一个地址的数据的时候与其相邻的数据也会很快被访问到。
每一次IO读取的数据我们称之为一页(page)具体一页有多大数据跟操作系统有关一般为4k或8k也就是我们读取一页内的数据时候实际上才发生了一次IO。MySQL每个节点大小默认为16KB也就是每个节点最多存16KB的数据可以修改最大64KB最小4KB。
如果某一行数据太大了超过16KB怎么办
如果行超过最大行长度 则将可变长度列用外部页存储直到该行符合最大行长度限制。 就是说把varchar、text这种长度可变的存到外部页中来减小这一行的数据长度。只在该列上保留一个 20 字节的指针指向溢出页。 索引页就是存索引的节点也就是非叶子节点。
每一条索引记录当中都包含了当前索引的值 、 一个 6字节 的指针信息 、一个 5 字节的行标头用来指向下一层数据页的指针。
假设我们的主键id为 bigint 型也就是8个字节那索引页中每行数据占用的空间就等于 8651986519 字节。每页可以存 15232÷19≈80115232÷19≈801 条索引数据。
那算上页目录的话按每个槽平均6条数据计算的话至少有 801÷6≈134801÷6≈134 个槽需要占用 268 字节的空间。
把存数据的空间分一点给槽的话我算出来大约可以存 787 条索引数据。
如果是主键是 int 型的话那可以存更多大约有 993 条索引数据。 前两层非叶子节点计算
在 B 树当中当一个节点索引记录为 N 条时它就会有 N 个子节点。由于我们 3 层B树的前两层都是索引记录第一层根节点有 N 条索引记录那第二层就会有 N 个节点每个节点数据类型与根节点一致仍然可以再存 N 条记录第三层的节点个数就会等于 N * N。
则有
主键为 bigint 的表可以存放 787 * 787619369 个叶子节点约等于62w主键为 int 的表可以存放 993 * 993986049 个叶子节点约等于99w 分析一下这张表的行记录
行记录头信息肯定得有占用5字节。可变长度字段列表表中 title占用1字节description占用2字节共3字节。null值列表表中仅school_code、cover_image、release_time3个字段可为null故仅占用1字节。事务ID和指针字段两个都得有占用13字节。字段内容信息 id、author_id、school_code 均为bigint型各占用8字节共24字节。create_time、release_time、modified_time 均为datetime类型各占8字节共24字节。status、is_delete 为tinyint类型各占用1字节共2字节。cover_image 为char(32)字符编码为表默认值utf8由于该字段实际存的内容仅为英文字母存url的结合前面讲的字符编码不同情况下的存储 故仅占用32字节。title、description 分别为varchar(50)、varchar(250)这两个应该都不会产生溢出页不太确定字符编码均为utf8mb4实际生产中70%以上都是存的中文(3字节)25%为英文(1字节)还有5%为4字节的表情则存满的情况下将占用 (50250)×(0.7×30.25×10.05×4)765(50250)×(0.7×30.25×10.05×4)765 字节。
统计上面的所有分析共占用 869 字节则每个叶子节点可以存放 15232÷869≈1715232÷869≈17 条算上页目录仍然能放 17 条。
则三层B树可以存放的最大数据量就是 17×61936910,529,273约一千万条数据再次没想到吧。 以下是粗略估算
InnoDB存储引擎中页的大小为16KB一般表的主键类型为INT占用4个字节或BIGINT占用8个字节指针类型也一般为4或8个字节也就是说一个页BTree中的一个节点中大概存储16KB/(8B8B)1K个键值因为是估值为方便计算这里的K取值为〖10〗^3。
也就是说一个深度为3的BTree索引可以维护10^3 * 10^3 * 10^3 10亿 条记录。这种计算方式存在误差而且没有计算叶子节点如果计算叶子节点其实是深度为4了