MySQL中INT和UUID的区别

The differences between INT and UUID in MySQL

如果我把主键设置成INT类型(AUTO_INCREMENT)或者设置成UUID,有什么区别这两者之间的数据库性能(SELECTINSERT 等)以及为什么?

UUID returns a universal unique identifier(如果也导入到另一个数据库,希望也是唯一的)。

引用 MySQL 文档(强调我的):

A UUID is designed as a number that is globally unique in space and time. Two calls to UUID() are expected to generate two different values, even if these calls are performed on two separate computers that are not connected to each other.

另一方面,一个简单的 INT 主 ID 键(例如 AUTO_INCREMENT)将 return 一个 唯一的特定数据库的整数和数据库table,但不是普遍唯一的(因此如果导入到另一个数据库,可能会出现主键冲突) .

就性能而言,使用 auto-incrementUUID 应该没有任何明显差异。大多数帖子(包括本网站作者的一些帖子)都是这样声明的。当然 UUID 可能会花费更多时间(和 space),但这对于大多数(如果不是全部)情况来说并不是性能瓶颈。将列设置为 Primary Key 应该使两种选择都与性能相等。请参阅以下参考资料:

  1. To UUID or not to UUID?
  2. Myths, GUID vs Autoincrement
  3. Performance: UUID vs auto-increment in cakephp-mysql
  4. UUID performance in MySQL?
  5. Primary Keys: IDs versus GUIDs (coding horror)

(UUID vs auto-increment 性能结果,改编自 Myths, GUID vs Autoincrement)

UUID 优点/缺点(改编自Primary Keys: IDs versus GUIDs

GUID Pros

  • Unique across every table, every database, every server
  • Allows easy merging of records from different databases
  • Allows easy distribution of databases across multiple servers
  • You can generate IDs anywhere, instead of having to roundtrip to the database
  • Most replication scenarios require GUID columns anyway

GUID Cons

  • It is a whopping 4 times larger than the traditional 4-byte index value; this can have serious performance and storage implications if you're not careful
  • Cumbersome to debug (where userid='{BAE7DF4-DDF-3RG-5TY3E3RF456AS10}')
  • The generated GUIDs should be partially sequential for best performance (eg, newsequentialid() on SQL 2005) and to enable use of clustered indexes.

备注

我会仔细阅读提到的参考资料,并根据我的用例决定是否使用 UUID。也就是说,在许多情况下 UUIDs 确实更可取。例如,可以在根本没有 using/accessing 数据库的情况下生成 UUIDs,甚至可以使用预先计算好的 and/or 存储在其他地方的 UUIDs。此外,您可以轻松地 generalise/update 您的数据库架构 and/or 集群方案,而不必担心 ID 中断并导致冲突。

在可能的冲突方面,例如使用 v4 UUIDS(随机),the probability to find a duplicate within 103 trillion version-4 UUIDs is one in a billion.

UUID 密钥不能被 pk 除非在数据库中持久存在,因此往返将发生直到那时你不能假设它的 pk 没有成功的事务。大多数 UUID 使用基于时间、mac、基于名称或一些随机 uuid。鉴于我们正大力转向基于容器的部署,并且它们有一种模式,即启动序列 MAC 地址依赖于 mac 地址将不起作用。基于时间并不能保证,因为假设系统始终处于精确的时间同步,但有时情况并非如此,因为时钟不遵循规则。 GUID 不能保证碰撞永远不会发生只是因为在给定的短时间内它不会发生但是如果有足够的时间和系统 运行 并行和系统的扩散保证最终会失败。

http://www.ietf.org/rfc/rfc4122.txt

对于使用集群主键的MySQL,版本 4 随机生成的 UUID 如果用作主键会影响插入性能。这是因为它需要重新排序行以将新插入的行放在聚簇索引中的正确位置。

FWIW,PostgreSQL 使用堆而不是集群主键,因此使用 UUID 作为主键不会影响 PostgreSQL 的插入性能。

更多信息,这篇文章对UUID和Int有比较全面的比较:Choose Primary Key - UUID or Auto Increment Integer