关于uuid:存储拆分后如何解决唯一主键问题
在单库单表时,业务 ID 能够依赖数据库的自增主键实现,当初咱们把存储拆分到了多处,如果还是用数据库的自增主键,就会呈现主键反复的状况。 所以咱们不得不面对的一个抉择,就是ID生成器,应用一个惟一的字符串,来标识一条残缺的记录。 这时候,不能应用md5或者sha1来对整个记录做摘要,因为咱们后续还要改变这个记录。也不能应用单机的计数器,因为计数器容易重启清零,也会存在多台机器上的数值反复,这违反了无状态服务的建设指标。 UUID尽管UUID在大多数语言中都有相干的类库,但除非迫不得以,咱们个别不会应用它。UUID尽管不会反复,但它十分的长,长的让人望而却步。 规范的UUID有5个局部组成:8-4-4-4-12,一共32个十六进制字符。因而,一共是128位。当把UUID作为数据库的索引时,会因为它没有程序性造成索引的随机散布和因为数据量微小造成查问性能升高。 且无序会造成每一次UUID数据的插入都会对主键的b+树进行很大的批改, 会产生离散 IO,从而产生性能瓶颈。同时,UUID也是不可读的,如果你把它打印在纸质的订单上,并不是一个好的主见。UUID同时还有信息安全的隐患,它的数据计算里有MAC地址的参加,比拟出名的是,曾被用于寻找梅丽莎病毒的制作者地位。 MySQL8当前MySQL 8.0 推出了函数 UUID_TO_BIN,它能够把 UUID 字符串: 通过参数将工夫高位放在最前,解决了 UUID 插入时乱序问题;去掉了无用的字符串"-",精简存储空间;将字符串其转换为二进制值存储,空间最终从之前的 36 个字节缩短为了 16 字节。同时还提供了 BIN_TO_UUID,反对将二进制值反转为 UUID 字符串,不必放心 UUID 的性能和存储占用的空间问题,相干的插入性能测试,后果如下表所示: 因为UUID_TO_BIN转换为的后果是16 字节,仅比自增 ID 减少 8 个字节,最初存储占用的空间也仅比自增大了 3G。 而且因为 UUID 能保障全局惟一,因而应用 UUID 的收益远远大于自增ID。在海量并发的互联网业务场景下,更举荐 UUID 这样的全局惟一值做主键。 但请牢记:分布式数据库架构,仅用 UUID 做主键仍然是不够的。 数据库自增ID当数据量宏大时,在数据库分库分表后,数据库自增id不能满足惟一id来标识数据;因为每个表都按本人节奏自增,会造成id抵触,无奈满足需要 革新工夫戳如果你是单机利用,那么应用工夫戳没什么问题,即便不必纳秒,应用毫秒也是足够的。但在分布式环境上面,工夫戳同样不是一个好的抉择。 即便你在机器装置了 ntpd 工夫同步,但因为网络和机器的差别,计算机的时钟总是存在差别,你的工夫戳总会呈现反复。为了解决这个问题,你须要减少一些其余的标识,比方机器的ID,或者更多细分的信息缩小工夫的碰撞。 这种自定义的ID生成器,只适宜特定的业务,做着做着你就会发现,它实质上是雪花算法的变种。 全局ID生成器服务能够设计一个全局 ID 生成器服务,每次找服务索要主键,这样尽管能够在业务间实现全局惟一,然而齐全依赖全局 ID 生成服务,依赖性大,服务一旦宕机,会影响所有相干依赖服务。 例如应用Redis的计数器,原子性自增,益处在于应用内存,并发性能好,但存在数据失落;自增数据量泄露的问题 雪花算法Twitter 雪花算法生成后是一个 64bit 的 long 型的数值,默认字符串长度是19位,它分为4个局部,根本放弃了自增 蕴含四个组成部分 不应用:1bit,最高位是符号位,0 示意正,1 示意负,固定为 0 ...