mysql表数据删除,为什么表空间大小不变

前置知识(以innodb为例子)

(1)在mysql8.0之前,表结构是存在以.frm 为后缀的文件里,而在mysql8.0之后呢,已经允许把表结构定义放在系统数据表。原因:本来表结构定义就很小

(2)mysql的表数据可以存储在共享表空间,也可以是单独的文件。这个选择是由innodb_file_per_table控制的

mysql 删除数据收缩空间 mysql删除数据后空间没变小_数据

innodb数据的删除流程

我们都知道mysql数据存储是按照页的方式存储的,页里面包含行,而当mysql删除一条数据的时候,会将这一行标志为删除。假设现在有一条数据为100的被删除了,那么在这个记录上,这个100就被标记成删除了,而当有下一个100的数据进来的时候,这个行记录空间就可以被复用。
那么当数据整页都被删除了呢?没错,那么整页就会被标记为删除。

格子衫现象(自己乱取的)

没错,聪明的你一定知道如果上述100位子的记录如果永远没有被插入数据的话,那么这个空间是不是永远都会空着,没错,理论上来说是这样的,我把这种现象取名叫做格子衫现象,寓意你懂的。
那么我们现在知道了删除一个格子,会造成格子衫现象,而更新意味着删除一个旧的格子,增加一个新的格子,那就和删除一样,也会造成这种现象。而插入一个数据的时候,假设插入的位子刚好在倒数第二格,而整个页没有空闲的位子让你插入,没错,那就会重新开一个页,那同样会造成格子衫现象

如何解决格子衫现象

简单粗暴重建表,新建一个一样的表,然后把表A的数据按主键顺序读出来塞到表B,那么格子衫现象也就不复存在了,mysql究极大法:alter table A engine=InnoDB 直接重建,没有后顾之忧。

重建表会有问题吗?

你现在数据库数据10个亿,你重建一个表,塞入需要时间,你们系统正在运行,假设淘宝现在需要重建表,你和马云说:马总啊,等我半天,把咱们淘宝先关了,我换一下表。然后第二天因为左脚踏入公司被开除。

online DDL

mysql在5.6版本后引入了online ddl
(1)先生成一个临时文件,扫描原文件中的主键数据页
(2)根据主键数据页生成b+树,存到临时文件
(3)原文件还是继续接受增删改查,只是对原文件的修改都会被记载一个日志里面
(4)生成临时文件后,将对原表在这段期间的操作通过日志重映
(5)将临时文件替换原文件‘

综上所述

不知道大家有没有做过日志系统,或者需要版本控制的系统,当你想要回到上一个版本的时候,如果做到回滚呢?
(1)将原有的数据做逻辑上的删除,有一个表字段标志是否被删除,但真实的数据没被删除
(2)做日志记录,当需要回滚的时候,将日志从第一个版本重映到上一个版本
(3)做日志记录,当需要回滚的时候,将日志从当前版本退到上一个版本
mysql就是我们所说的第一个方法,进行逻辑上的删除,所以你明白了吗

我老婆举了一个很好的例子,就相当于黑户,户口本上把你名字划掉了,但你这个人还存在着,但户口本上已经看不到了