一、自增(auto_increment)和UUID优缺点
自增 (auto_increment)的优点:
1.字段长度较uuid小很多,可以是bigint甚至是int类型,这对检索的性能会有所影响。
2.在写的方面,因为是自增的,所以主键是趋势自增的,也就是说新增的数据永远在后面,这点对于性能有很大的提升。
3.数据库自动编号,速度快,而且是增量增长,按顺序存放,对于检索非常有利。
4.数字型,占用空间小,易排序,在程序中传递也方便。
自增 (auto_increment)的缺点:
1.由于是自增,很容易通过网络爬虫知晓当前系统的业务量。
2.高并发的情况下,竞争自增锁会降低数据库的吞吐能力。
3.数据迁移或分库分表场景下,自增方式不再适用。
UUID的优点:
1.不会冲突。进行数据拆分、合并存储的时候,能保证主键全局的唯一性。
2.可以在应用层生成,提高数据库吞吐能力。
UUID的缺点:
1.影响插入速度,并且造成硬盘使用丰低。与自增相比,最大的缺陷就是随机IO (新的记录可能会插入之前记录的中间,因此需要移动之前的记录)
2.字符串类型相比整数类型肯定更消耗空间,而且会比整数类型操作慢。
二、具体选择
选择数据库主键的类型要根据具体的需求来决定,以下是自增和UUID两种主键类型的比较:
-
自增主键:每次插入一条新记录时,数据库会自动为该记录分配一个唯一的自增值。自增主键通常使用整数类型,如INT或BIGINT。自增主键的优点是简单、高效,插入速度快,且查询效率较高。它适用于大多数情况下,特别是在需要频繁插入新记录的场景。
-
UUID主键:UUID(Universally Unique Identifier)是一种全球唯一的标识符。它是一个128位的数字,通常以字符串形式表示。UUID主键的优点是在分布式系统中可以保持唯一性,不同数据库之间也不会冲突。它适用于需要在多个数据库之间同步数据或者需要将数据标识与业务逻辑解耦的场景。
选择自增主键还是UUID主键,要考虑以下因素:
- 数据库性能: 自增主键往往比UUID主键的查询效率更高,对于大规模数据集更为适用。
- 数据复制和合并: 如果需要将数据从不同的数据库合并或同步,使用UUID主键可以避免冲突。
- 安全性和隐私: 如果需要保护数据的安全性或隐私,可以考虑使用UUID主键,因为自增主键可能会暴露数据的插入顺序和数量信息。
因为uuid 相对顺序的自增id来说是毫无规律可言,新行的值不一定要比之前主键的值要大,所以InnoDB无法做到总是把新行插入到索引的最后,而是需要为新行寻找新的合适的位置从而来分配新的空间。这个过程需要做很多额外的操作,数据的毫无顺序会导致数据分布散乱,将会导致以下问题:
①.写入的目标页很可能已经刷新到磁盘上并且从缓存上移除,或者还没有被加载到缓存中InnoDB在插入之前不得不先找到并从磁盘读取目标页到内存中,这将导致大量的随机IO。
②.因为写入是乱序的,innodb不得不频繁的做页分裂操作,以便为新的行分配空间,页分裂导致移动大量的数据,一次插入最少需要修改三个页以上。
③.由于频繁的页分裂,页会变得稀疏并被不规则的填充,最终会导致数据会有碎片。
④.在把随机值(uuid 和雪花id)载入到聚簇索引(InnoDB默认的索引类型)以后,有时候会需要做一次
OPTIMEIZE TABLE来重建表并优化页的填充,这将又需要一定的时间消耗。
结论:使用 InnoDB应该尽可能的按主键的自增顺序插入,并且尽可能使用单调的增加的聚簇键的值来插入新行。如果是分库分表场景下,分布式主键ID的生成方案优先选择雪花算法生成全局唯一主键(雪花算法生成的主键在一定程度上是有序的)。因此,对于大多数情况下,使用自增主键是一个较为常见和合理的选择。但如果需要在分布式系统中使用,或有特定的安全性或隐私需求,则可以考虑使用UUID主键。