在我们的开发过程中,只要你是涉及到高并发的领域,那么”怎么为你的系统生成一个高效、可靠、友好的ID”就是你的一个永远绕不开的问题。
本文档部分内容非原创,借鉴了网上的一些资源。涉及出处将在本文的最后部分列出。
一.分布式ID原则
- 唯一性
- 高效性
- 可用性
- 有序性
此处主要介绍为什么ID生成需要有序性
- 写性能
在MySQL InnoDB引擎中使用的是聚集索引, 由于多数RDBMS使用B-tree的数据结构来存储索引数据,在主键的选择上面我们应该尽量使用有序的主键保证写入性能。 聚簇索引的数据的物理存放顺序与索引顺序是一致的,即:只要索引是相邻的,那么对应的数据一定也是相邻地存放在磁盘上的。 如果主键不是自增id,那么可以想象,它会干些什么,不断地调整数据的物理地址、分页,当然也有其他一些措施来减少这些操作, 但却无法彻底避免。但,如果是自增的,那就简单了,它只需要一页一页地写,索引结构相对紧凑,磁盘碎片少,效率也高。
- 读性能
来感受下以下两个sql的性能吧,即使created_at字段也有索引: 1.select from table order by created_at2.select from table order by id ps: 根据磁盘预读的特性,如果第一次读取“1”,那么如果你是顺序存储,那么“2,3,4,5”也会被读取进内存中。 (当然一般ID就是你的聚簇索引,已经帮你排好序了)
二.实现方案
1. 数据库方案(auto_increment、Ticket Servers)
- auto_increment
优点:
1.简单,代码方便,性能可以接受。 2.数字ID天然排序,对分页或者需要排序的结果很有帮助。
缺点:
1.可读性,容易暴露出库信息(今天下个订单,第二天同时间下个订单,其实就可以推测出该系统一天的订单量)。 2.在性能达不到要求的情况下,比较难于扩展。 3.如果遇见多个系统需要合并或者涉及到数据迁移会相当痛苦。 4.在单个数据库或读写分离或一主多从的情况下ÿ