MYSQL主键策略(自增,UUid,雪花算法)

MYSQL主键策略(自增,UUid,雪花算法)

作为一个快要大四的学生,mysql的主键策略到底怎么选用一直很疑惑,平时也会查阅一些资料,但都没有整合思考过,今天趁着有时间就写一写我知道的一些东西。

自增的优点:
1.存储空间小
2.插入和查询性能高
自增的缺点:
1.int的范围可能不够大(但我觉得等数据到上亿级别,大部分情况下都要做分库分表了吧…)
2.当要做数据迁移的时候,会很麻烦,主键容易冲突
3.id自增,自身的业务增长情况很容易被别人掌握
4.自增在高并发的情况下性能不好
UUid的优点:
1.独一无二,几乎不会重复
2.数据合并很方便(主键不会冲突)
3.业务增长数据不会被轻易察觉
UUid的缺点:
1.生成UUid花的时间比较多
2.存储空间大
3.数据库存储UUid作为主键花的时间很多,消耗的性能也很多

自增和UUid差异的原因

mysql数据库一般我们会采用支持事务的Innodb,在Innodb中,采用的是B+数索引。Innodb的存储结构,是聚簇索引。对于聚簇索引顺序主键和随机主键的对效率的影响很大。
自增是顺序主键存储,查找和插入都很方便(插入会按顺序插到前一个的后面),但UUid是无序的,通过计算获得的hashcode也会是无序的(是按照hashcode选择存储位置)所以对于他的查找效率很低,而且因为他是无序的,他的插入有可能会插到前面的数据中,会造成很多其他的操作,很影响性能或者很多存储空间因为没有顺序的存储而被空缺浪费。

所以对于选用哪种策略,还是要看具体情况进行选择,我一般会使用雪花算法(snowflake)。
雪花算法:
大概是由时间戳+机器码+同一时间的自增组成的。
所以他会有以下优点
1.不会重复
2.有序,不会造成空间浪费和胡乱插入影响性能
3.生成很快特别是比UUid快的多
4.相比UUid更小

当然了雪花算法也有缺点:时间回拨造成错乱

以下是雪花算法和UUid分别生成1000000(一百万)个id的时间对比:

首先是生成id的代码

import java.util.UUID;

public class HelloWord {

    public static void main(String[] args)  {
        SnowflakeIdWorker idWorker=new SnowflakeIdWorker(0,0);
        /**
         *雪花算法
            * @return void
            * @author tzj
            * @date 2020/8/21 15:17
        */
        long start=System.currentTimeMillis();
        for(int i=0;i<1000000;i++){
            long id=idWorker.nextId();
        }
        long end=System.currentTimeMillis();
        System.out.println("生成1000000个id用时: "+(end-start)+" ms");
        /**
         *UUid
            * @return void
            * @author 这里写自己想展示的作者名
            * @date 2020/8/21 15:18
        */
        long startUUid=System.currentTimeMillis();
        for(int i=0;i<1000000;i++){
            UUID uuid=UUID.randomUUID();
        }
        long endUUid=System.currentTimeMillis();
        System.out.println("生成1000000个UUid用时: "+(endUUid-startUUid)+" ms");
    }


}

SnowflakeIdWorker是生成雪花算法id的工具类。

接下来是结果

在这里插入图片描述

你可能感兴趣的:(mysql)