java分布式下mysql常见的主键唯一ID汇总

天涯浪子 提交于 2020-08-19 05:40:55

随着用户需求的提升和架构的复杂,我们所需要的项目也是越来越复杂。考虑到项目的性能,架构的合理性,数据主键生成也慢慢显得尤为重要起来。
今天我就介绍几种常用的主键生成方案:

一、主键自增

这是数据自带的一种特性,只需在建表语句中主键后添加AUTO_INCREMENT,就会在主键中按照顺序自动成主键id。
优点:
1.自增的id天然排序,对于分页查询和需要排序的查询非常友好
2.自增id的性能相对还可以


缺点:
1.在单个数据库或读写分离或一主多从的情况下,只有一个主库可以生成。有单点故障的风险。
2.在性能达不到要求的情况下,比较难于扩展。
3.如果遇见多个系统需要合并或者涉及到数据迁移会相当痛苦。
4.分表分库的时候会有麻烦。



二、UUID

这是java1.5推出的,号称是全球唯一的标识。可以这样生成:

 UUID uuid = UUID.randomUUID();

优点:
1.生成代码简单,ID全球唯一
2.数据库迁移不需要担心
缺点:
1.无法排序
2.查询效率慢




redis集群生成id

redis由于是单线程,可以生成全局唯一id。且基于内存操作,在数据性能不够时可使用。可以用Redis的原子操作 INCR和INCRBY来实现。
比如:我们的redis集群有3台redis那么我们可以这么做:
A: 1,2,3 第一次生成
B:4,5,6 第二次生成
C:7,8,9 第三次生成
集群有多少redis,那么设置生成id的步长就为几。比如这个3台redis就步长为3。保证id不重复。




MybatisPuls 默认自动生成(Twitter的snowflake算法)

使用过mybatiesPuls的小伙伴一般都感受过它的主键自增。使用inset方法插入数据库会自动生成一个19位的long型整数Id。

snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0。具体实现的代码可以参看https://github.com/twitter/snowflake。

当然MybatisPuls也可以设置其他类型的主键Id。
如果在MybatisPuls中想设置主键自增:
1.数据库开启主键自增
2.实体字段中配置 @TableId(type = IdType.AUTO)


@TableId(type = IdType.AUTO)
private Long id;

3.要想影响所有实体的配置,可以设置全局主键配置

#全局设置主键生成策略
mybatis-plus.global-config.db-config.id-type=auto

如果想用其他策略:可以参考IdType枚举类,并修改注解内的类型

@Getter
2
public enum IdType {
3
    /**
4
     * 数据库ID自增
5
     */
6
    AUTO(0),
7
    /**
8
     * 该类型为未设置主键类型
9
     */
10
    NONE(1),
11
    /**
12
     * 用户输入ID
13
     * 该类型可以通过自己注册自动填充插件进行填充
14
     */
15
    INPUT(2),
16
17
    /* 以下3种类型、只有当插入对象ID 为空,才自动填充。 */
18
    /**
19
     * 全局唯一ID (idWorker)
20
     */
21
    ID_WORKER(3),
22
    /**
23
     * 全局唯一ID (UUID)
24
     */
25
    UUID(4),
26
    /**
27
     * 字符串全局唯一ID (idWorker 的字符串表示)
28
     */
29
    ID_WORKER_STR(5);
30
31
    private int key;
32
33
    IdType(int key) {
34
        this.key = key;
35
    }
36
}

我所知道的就这几种,欢迎指正与补充。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!