在mysql中,咱们要查询一条或多条数据,都会经过索引来更快的查询数据,一般每条数据都会有一个主键ID用来构建索引方便查询。
因为
那么主键ID该选怎么选呢?java
自增主键ID一般都会选择int类型或者long类型。mysql
它的优势是:
简单方便,有序递增,方便排序和分页等。算法
缺点:
1.随着业务的增加,当id达到int最大值或者long最大值时,服务将不可用,存在上限问题。
2.简单递增容易被其余人猜想利用,经过id数来判断新增多少条数据或是用作他途。
3.根据业务须要分库分表时,会有id重复等问题。sql
试用场景:比较适合数据量很少,并发量比较小的状况下使用。数据库
UUID是通用惟一识别码(Universally Unique Identifier)的缩写,开放软件基金会(OSF)规范定义了包括网卡MAC地址、时间戳、名字空间(Namespace)、随机或伪随机数、时序等元素。利用这些元素来生成UUID。安全
UUID是由128位二进制组成,通常转换成十六进制,而后用String表示。
java中自带UUID类,有4种不一样的UUID的生成策略:网络
randomly : 基于随机数生成UUID,因为Java中的随机数是伪随机数,其重复的几率是能够被计算出来的。
time-based : 基于时间的UUID,这个通常是经过当前时间,随机数,和本地Mac地址来计算出来,自带的JDK包并无这个算法的咱们在一些UUIDUtil中,好比咱们的log4j.core.util,会从新定义UUID的高位和低位。
DCE security : DCE安全的UUID。
name-based :基于名字的UUID,经过计算名字和名字空间的MD5来计算UUID。并发
UUID的优势:
经过本地生成,没有通过网络I/O,性能较快
无序,没法预测生成顺序(也是缺点之一)。
不会出现重复dom
缺点:
使用字符串进行存储,占用必定的存储空间,须要排序的时候会比较麻烦,查询相对较慢分布式
适用场景:能够为不须要担忧过多的空间占用的状况下,以及不须要生成有递增趋势的数字的场景
该算法是推特开源的snowflake(雪花)算法,用来生成分布式ID的。
其目的是生成一个64bit的整数:
1bit:通常是符号位,不作处理
41bit:从开始用的时间开始算,用来记录时间戳,这里能够记录69年。若是真用完了呢。。。那也是年轻人去解决的事了。。。
10bit:10bit用来记录机器ID,总共能够记录1024台机器,通常用前5位表明数据中心,后面5位是某个数据中心的机器ID
12bit:循环位,用来对同一个毫秒以内产生不一样的ID,12位能够最多记录4095个,也就是在同一个机器同一毫秒最多记录4095个,多余的须要进行等待下毫秒。
优势:
总体上按照时间自增排序,而且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID
做区分),而且效率较高,经测试,SnowFlake每秒可以产生26万ID左右
缺点:
1.过度依赖机器时钟,若是机器时钟回拨,会致使重复ID生成
2.根据雪花算法,在单机上是绝对递增的,可是因为设计到分布式环境,每台机器上的时钟不可能彻底同步,有时候会出现不是全局递增的状况(通常分布式ID只要求趋势递增,并不会严格要求递增。我以为正常配置雪花算法的状况下国内并发量使用雪花算法出问题的公司不会有太多。。)
适用场景:应用在分布式系统中,适用于并发量大的场景。
根据自身系统服务的状况来选择生成的主键ID。上面三种咱们公司都有用到,看了看数据库里的表,感受头有点大。。