• 自增长id/UUID/雪花算法的深层次分析比较


    说到id之前,先说一下mysql数据库的Innodb的主键索引,因为这和索引息息相关。

    我们知道,在Innodb中,采用的是B+数索引。Innodb的存储结构,是聚簇索引。对于聚簇索引,

    (1)顺序主键和随机主键的对效率的影响很大。我们分插入和查询来讲:

             插入。在磁盘中,有一个页的概念,而一页的容量是固定的,每一页按顺序存储数据,一般数据量达到一页的15/16,则开始存到下一页。但如果主键是随机的,那么每次插入之前,为了找到它的位置,首先需要进行一次比较,找到它的合适位置,再进行插入。如果是在页尾,那自然是最理想的效果。

         

    UUID和自增长在程序中怎么实现此处不讲,我们直接从性能和实际使用来分析。

         说到性能,就不等不提到索引,此处以InnoDB的BTree索引来讲。

          uuid类型是varchar(36),而自增长Id则一般是bigInt类型。

          首先,大家要知道,id作为唯一索引,并不总是能提高效率。对于非常小的表,大部分情况下简单的全表扫描效率更高,对于中大型的表,索引才非常有效。因为索引帮助存储快速查找到记录的同时,也会带来额外的消耗。

           那么索引会带来哪些额外的消耗呢?空间和时间。

    下面做了一个实验,在一个有足够内存容纳索引的服务器上插入100万条记录和300百万条记录,时间和空间上的消耗如下:

     根据上面的结果,索引是会消耗额外的物理空间的,而聚簇索引消耗的物理空间更大。当数据特别多的时候,相对于bigInt类型的自增长Id,varchar(36)类型的uuid消耗的物理空间更为明显。

            在时间上,1)uuid由于占用的内存更大,所以查询、排序速度会相对较慢;2)在存储过程中,自增长id由于主键的值是顺序的,所以InnoDB把每一条记录都存储在上一条记录的后面。当达到页的最大填充因子时(innodb默认的最大填充因子为页大小的15/16,留出部分空间用于以后修改),下一条记录就会写入新的页面中。一旦数据按照这种方式加载,主键页就会被顺序的记录填满。而对于uuid,由于后面的值不一定比前面的值大,所以InnoDB并不能总是把新行插入的索引的后面,而是需要为新行寻找合适的位置(通常在已有行之间),并分配空间,这会增加额外的很多工作。这也是为什么当索引的列过长的时候,需要采用前缀索引,或者哈希索引了。

            尽管自增长id的优点这么多,但实际大型项目中却很少采用自增长id的,这是为什么呢?uuid几乎保证了不同数据库的不同表的id唯一,可以进行数据切分合并,而自增长id只能保证一个数据库中的一张表的id唯一,进行数据库合并的话并然会因主键冲突而失败,这是一个硬伤。
    ————————————————
    版权声明:本文为CSDN博主「凌晨写博客」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/hj12312/article/details/79715632

  • 相关阅读:
    C# 读写xml
    oracle经验小节2
    解决在IE9,IE10浏览器下,程序没有任何错误,easy ui页面不加载任何数据的问题
    解决调试不能命中断点的问题
    在做和sap系统集成的一点心得
    easy ui datagrid 数据分页
    selector-item属性
    scaleType-模拟按钮加文字整天点击效果
    layout-代码中添加view
    linearlayout-weight 属性作用
  • 原文地址:https://www.cnblogs.com/it-deepinmind/p/12508955.html
Copyright © 2020-2023  润新知