一、前言
最近在建表选择主键的时候有些纠结,我们经常使用的主键有两种UUID和自增ID,不知道选哪一种好。之前一直没有总结过这两种主键的区别,于是今天去总结了一下这两种主键的区别、优缺点,以便为我们以后主键选择提供一些参考。
二、自增ID
自增ID就是由数据库引擎负责生成主键ID,实现和使用都很简单,几乎所有的数据库都原生支持。
优点:
- 存储空间:ID是数字,占用存储空间比UUID(UUID通常是128位,自增ID一般是32位或64位)少。
- **查询效率高:**由于ID是自增的,可在一定程度上提高插入和查询的性能,尤其是在索引上的表现更好。
- **方便展示:**ID比较短,方面在页面上直接展示。
- **方便分页:**ID是连续自增的,所以在分页的时候,可以通过ID解决深度分页的问题。
缺点:
- **可能用完:**自增ID可能是int或bigint,无论是那种都有可能会用完。
- **可预测性:**由于ID是自增的,可以根据ID预测我们的业务量,可能会存在一定的安全风险。
- **分库分表:**当我们的系统做分库分表时,就不能用自增ID了,会导致ID重复。我们就需要采用额外的机制来保证ID的唯一性(如分布式ID生成器)。
三、UUID
UUID是一个128位长的唯一标识符,通常是字符串形式表现。
优点:
- **全局唯一:**UUID有很多版本,使用不同的算法生成。几乎可以保证全局唯一,可以确保在分布式系统中不会冲突。
- **不可预测性:**UUID是随机生成的,不容易猜测,能够提供一定的隐私保护。
- **去中心化:**不需要依赖一个统一的中间件,就能生成唯一的ID,非常适合分布式系统。
缺点:
- **存储空间:**UUID以字符串形式存储,前面提到过通常是128位,占用的存储空间大。
- **可读性差:**UUID较长且复杂,没有任何业务含义,不方便阅读,不方便在页面上展示。
- **不适合做范围查询:**UUID不是自增的,在做范围查询的时候不支持。
- 查询效率低:
a).UUID作为主键,因为长度很长,索引就会变得很大,会占用更多的磁盘空间,进而增加磁盘IO。并且,大索引还会导致查询时内存开销增加。
b). 使用UUID进行排序时,新的UUID通常会插入到叶子节点的中间位置。这可能会导致B+树的分裂和平衡操作频繁进行,增加了插入的开销。每次分裂或平衡都涉及到数据的重新排序,从而影响查询性能。
四、选择依据
通过上面的总结,我们可以根据下面几点来选择主键。
- 系统规模和复杂度:如果时单体应用或小规模系统,自增ID可能是更好的选择。如果是大规模的分布式系统,UUID会跟适合。
- 性能要求:如果对系统性能要求很高,特别是涉及到大量的写操作和读操作,选择自增ID会更优。
- 唯一性需求:如果系统需要保证ID全局唯一,或需要在多个数据库之间进行数据整合,则UUID更合适。
- 安全性要求:如果需要防止ID被推断,防止被预测业务量,选择UUID更安全。
需要综合考虑这些因素,根据具体的应用场景选择合适的主键类型。