主键生成策略
文章目录
1.什么是主键?
主键,即主关键字,是被挑选出来,作表的行的唯一标识的候选关键字。
一个表只有一个主关键字。主关键字又可以称为主键。 主键可以由一个字段,也可以由多个字段组成,分别称为单字段主键或多字段主键。又称主码。
2.生成主键的必要性?
主键可以用来表示一个精确定位的特定的行,如果没有主键,你就无法精准定位一条记录是否就是你要的相关行记录,这样就会导致更新或删除表中特定的行很困难。
3.生成主键的策略?
- 自动增长(AUTO INCREAMENT)
- UUID
- Redis
- SnowFlake
- 利用zookeeper生成唯一ID
4.自动增长(AUTO INCREAMENT)
数据库自增长序列或字段。
4.1实现方法
在创建表的时候加入AUTO INCREAMENT语句。
4.2优缺点
优点:实现简单。
缺点:分库分表繁琐,建立新表的时候需要得知上一个表最后一个主键的id,在此基础上进行自动增长。
5.UUID
UUID是通用唯一识别码 (Universally Unique Identifier),可以生成一个长度32位的全局唯一识别码。
5.1实现方法
可以利用数据库也可以利用程序生成。
String uuid = UUID.randomUUID().toString();
5.2优缺点
优点:实现简单,代码方便
缺点:1.没有排序,无法保证趋势增长。
2.32位太长,入库性能差(涉及B+索引树的分裂)
6.Redis
主要依赖于Redis是单线程的,所以也可以用生成全局唯一的ID。可以用Redis的原子操作 INCR和INCRBY来实现。
6.1实现方法
设置步长和Redis的初始值
6.2优缺点
优点:1.不依赖数据库
2.数字ID天然排序,对分页或者需要排序的结果有帮助。
缺点:编码和配置的工作量大
7.SnowFlake
snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。
7.1实现方法
使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0。
public class IdWorker{
//下面两个每个5位,加起来就是10位的工作机器id
private long workerId; //工作id
private long datacenterId; //数据id
//12位的序列号
private long sequence;
public IdWorker(long workerId, long datacenterId, long sequence){
// sanity check for workerId
if (workerId > maxWorkerId || workerId < 0) {
throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0",maxWorkerId