一个快速的问题或意见。
我需要为数据库表生成一些UUID。
自动递增键无法满足需求,因为我需要在不同的数据库和系统之间使键唯一。UUID很好用,但是它的输出对于一些行将要导出到的系统来说过长了。UUID_SHORT()可以胜任这个任务,而且我已经阅读了MYSQL关于保证其唯一性的条件。
但我想再次确认,如果我偶尔使用UUID_SHORT()为行生成UUID,它们是否确实与UUID()一样在时间和空间上独一无二。
谢谢。
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
是否足够好?如果你:
第二个问题对大多数人来说似乎不太可能发生,但在决定以 uuid_short
作为你的键的基础之前,值得研究一下第一个问题。
*** 基于mysql文档中对uuid_short()
的描述,如果在单个服务器的正常运行时间内生成超过1600万个ID,则可能会导致ID冲突。但那是很荒谬的。mysql文档继续指出,只要每秒不生成1600万个ID,就没有问题。这意味着如果用完了1600万个顺序ID,他们必须增加时间戳中的某些位。我还没有测试过这一点。
UUID_SHORT()
是否像UUID()
一样在时间和空间上创建唯一值。简短的答案是是,只要你遵守MySQL所需的特定条件。UUID()
唯一的明显缺点是其表示不太节省存储空间(生成36个字符的字符串而不是64位整数)并且不能与基于语句的复制一起使用。但是,UUID()
的优势在于从来不必考虑MySQL对UUID_SHORT()
所需的特殊条件。如果您确定这些条件永远不会成为问题,并且渴望每个记录节省224位,请使用UUID_SHORT()
。但如果您对特殊条件有任何疑虑,那么最好避免使用它。mysqld
重新启动之间永远不要将系统时钟向后设置。通常配置服务器以自动将其时钟与其他时间源(例如unix中的ntp
,Windows中的Time Service)同步,如果此行为未符合您的预期,则可能无法保证达到这种条件的一致性。
PRIMARY KEY(id, server_id)
,然后在相关的机器/系统上更改server_id
的默认值为任何整数 - 您可以实现唯一性而不使用GUID,并仍然保留自动增量。 - N.B.id=1, server_id=1
被导入到一个已经存在id=1
但server_id
是2
的系统中。你不会遇到主键冲突,你会知道它是从哪里导入的,你的主键将会相对较小,并且你不必担心 GUID 带来的各种问题。 - N.B.