Mysql的UUID_SHORT()函数和UUID()函数是否可比较?

10

一个快速的问题或意见。

我需要为数据库表生成一些UUID。

自动递增键无法满足需求,因为我需要在不同的数据库和系统之间使键唯一。UUID很好用,但是它的输出对于一些行将要导出到的系统来说过长了。UUID_SHORT()可以胜任这个任务,而且我已经阅读了MYSQL关于保证其唯一性的条件。

但我想再次确认,如果我偶尔使用UUID_SHORT()为行生成UUID,它们是否确实与UUID()一样在时间和空间上独一无二。

谢谢。


2
如果您创建了复合主键,例如PRIMARY KEY(id, server_id),然后在相关的机器/系统上更改server_id的默认值为任何整数 - 您可以实现唯一性而不使用GUID,并仍然保留自动增量。 - N.B.
确实非常有趣。表格需要定期导出为csv文件,然后在其他系统中导入,因此主键应该是一个唯一的列,而不是由两个列组成的复合键。但是那种方法非常有趣,我确实会研究一下。谢谢。当数据离开mysql并变成一个平面文件时,唯一键是我的主要关注点。 - jiraiya
这就是为什么这种方法允许导入到其他系统中。考虑这样一种情况,你有一个 id=1, server_id=1 被导入到一个已经存在 id=1server_id2 的系统中。你不会遇到主键冲突,你会知道它是从哪里导入的,你的主键将会相对较小,并且你不必担心 GUID 带来的各种问题。 - N.B.
2个回答

11

uuid_short() 生成一个8字节的整数,其中包含服务器ID、一个比较稳定的时间组件和一个递增的24位整数。这些位被压缩成一个整数。时间组件基于服务器的启动时间。

uuid() 生成一个16字节版本1 UUID 的十六进制字符串。版本1 UUID 是服务器ID、当前时间戳、在高速生成ID时发挥作用的几个字节以及一些实用位的按位组合。

回答问题:是否 uuid_short 提供与 uuid 相媲美的时间和空间唯一性?答案是否定的。例如,uuid_short 中的服务器ID只有一个字节。因此,如果你有256个或更多服务器,则至少有一些服务器将具有相同的节点ID,这意味着你失去了空间唯一性。相比之下,版本1 UUID中的服务器ID长度为6个字节,有效地消除了除最大企业服务器群之外的重复机会 :)

更好的问题是,uuid_short 是否足够好?如果你:

  1. 在很短的时间内从同一台服务器生成超过1600万个ID。***
  2. 在完全相同的时间启动具有相同服务器ID的服务器,并共享数据。
  3. 调整系统时钟,然后重新启动服务器。

第二个问题对大多数人来说似乎不太可能发生,但在决定以 uuid_short 作为你的键的基础之前,值得研究一下第一个问题。

*** 基于mysql文档中对uuid_short() 的描述,如果在单个服务器的正常运行时间内生成超过1600万个ID,则可能会导致ID冲突。但那是很荒谬的。mysql文档继续指出,只要每秒不生成1600万个ID,就没有问题。这意味着如果用完了1600万个顺序ID,他们必须增加时间戳中的某些位。我还没有测试过这一点。


4
你的关键问题是,UUID_SHORT()是否像UUID()一样在时间和空间上创建唯一值。简短的答案是是,只要你遵守MySQL所需的特定条件。
长的答案是,是的,但为什么要使用它呢? UUID()唯一的明显缺点是其表示不太节省存储空间(生成36个字符的字符串而不是64位整数)并且不能与基于语句的复制一起使用。但是,UUID()的优势在于从来不必考虑MySQL对UUID_SHORT()所需的特殊条件。如果您确定这些条件永远不会成为问题,并且渴望每个记录节省224位,请使用UUID_SHORT()。但如果您对特殊条件有任何疑虑,那么最好避免使用它。
你对特殊条件的关注程度很大程度上取决于你的操作环境。我非常担心在mysqld重新启动之间永远不要将系统时钟向后设置。通常配置服务器以自动将其时钟与其他时间源(例如unix中的ntp,Windows中的Time Service)同步,如果此行为未符合您的预期,则可能无法保证达到这种条件的一致性。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接