以数据库为例,会出现的问题
解决方法
1.使用UUID进行处理
1.概念
UUID 是指Universally Unique Identifier,翻译为中⽂是通⽤唯⼀识别码 产⽣重复 UUID 并造成错误的情况⾮常低,是故⼤可不必考虑此问题。 Java中得到⼀个UUID,可以使⽤java.util包提供的⽅法.
2.使用方式
直接调用jdk的方法。
public class MyTest { public static void main(String[] args) {
System.out.println(java.util.UUID.randomUUID().toString()); } }
3.不足
因为uuid比较长,且包含字符串,所以可以无法为主键建立索引,在一定程度上影响效率。
2.单独建表存id
使用方式
⽐如A表分表为A1表和A2表,那么肯定不能让A1表和A2表的ID⾃增,那么ID怎么获取呢?我们可 以单独的创建⼀个Mysql数据库,在这个数据库中创建⼀张表,这张表的ID设置为⾃增,其他地⽅ 需要全局唯⼀ID的时候,就模拟向这个Mysql数据库的这张表中模拟插⼊⼀条记录,此时ID会⾃ 增,然后我们可以通过Mysql的select last_insert_id() 获取到刚刚这张表中⾃增⽣成的ID.
-- Table structure for DISTRIBUTE_ID
-- ---------------------------- DROP TABLE IF EXISTS `DISTRIBUTE_ID`;
CREATE TABLE `DISTRIBUTE_ID`
( `id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '主键',
`createtime` datetime DEFAULT NULL, PRIMARY KEY (`id`) )
ENGINE=InnoDB DEFAULT CHARSET=utf8;
当分布式集群环境中哪个应⽤需要获取⼀个全局唯⼀的分布式ID的时候,就可以使⽤代码连接这个 数据库实例,执⾏如下sql语句即可。
insert into DISTRIBUTE_ID(createtime) values(NOW());
select LAST_INSERT_ID();
缺陷
- 当主键数据库挂了,会导致整个数据库系统无法使用。
- 对本数据库的操作很频繁,且都是插入操作,性能受影响。
3.使用雪花算法
雪花算法是Twitter推出的⼀个⽤于⽣成分布式ID的策略。 雪花算法是⼀个算法,基于这个算法可以⽣成ID,⽣成的ID是⼀个long型,那么在Java中⼀个long 型是8个字节,算下来是64bit,如下是使⽤雪花算法⽣成的⼀个ID的⼆进制形式示意:
4.使用redis的incr获取全局唯一id(推荐)
为啥能获取唯一id?
redis是单线程,不会出现线程冲突,争抢等问题,所以每次生成的id都是独立且唯一的。
借助Redis的Incr命令
Redis Incr 命令将 key 中储存的数字值增⼀。如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执⾏ INCR 操作。 .incr(id) 1 2 3 4
使用方法
- 引入jar包
- 调用redis的api
jedis.incr("id"); //返回long