分布式系统中咱们每每须要进行分库分表,提高性能,这时候咱们就会须要一个高性能的全局惟一Id生成器,又称发号器。mysql
UUID由MAC地址、时间戳、命名空间、随机/伪随机数、时序等元素构成,JAVA自带,使用简单,一样的,它的缺点也很是的明显。redis
MySQL tries to leave space so that future inserts do not incur un-necessary page splits (and thus higher IO cost). In an "ideal" world, MySQL tries to keep the index pages at 15/16-th full, but depending on insert order, this fill factor can be as low as 1/2算法
大部分状况下,咱们使用的数据库都是mysql,使用的mysql索引都是InnoDB,而InnoDB是主键构成的B+Tree(每一个节点携带数据),因此乱序插入时Innodb须要不停的申请新的page,而且进行tree的从新分布,致使插入速度变慢,查询也有约10%的性能损失和40~50%的空间浪费。sql
利用数据库的自增,咱们也能够方便的进行惟一Id生成,简单方便,可是问题也很明显,首先我插入了一条数据,还要再查询一次才能够知道id,其次简单的自增很容易引起漏洞。若是咱们把它做为全局惟一ID的话,在分库分表的状况下,还须要一个专门的数据库表自增(相似redis),查出id,而后在分库分表,性能不好。数据库
利用incr咱们能够很容易的实现id自增且redis是原子性的,不会重号。问题的仍是引入了组件,id的生成复杂度提升。分布式
Zookeeper的话经过带有编号的节点也能够实现全局惟一id的生产,可是使用的比较少,一样的,引入了组件,提升了系统复杂度。ide
SnowFlake算法生成64位的二进制正整数,而后转换成10进制的数,性能很高,不依赖组件,性能好,适合生产使用。性能
学我者生,似我者死。-齐白石mysql索引
写程序咱们也不须要依葫芦画瓢,能够根据本身项目的需求,对64位二进制进行从新划分,从新定义。this