随着用户需求的提升和架构的复杂,我们所需要的项目也是越来越复杂。考虑到项目的性能,架构的合理性,数据主键生成也慢慢显得尤为重要起来。
今天我就介绍几种常用的主键生成方案:
一、主键自增
这是数据自带的一种特性,只需在建表语句中主键后添加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
}
我所知道的就这几种,欢迎指正与补充。
来源:oschina
链接:https://my.oschina.net/u/4418565/blog/4419121