使用UUID时,我还应该使用AUTO_INCREMENT吗?

时间:2013-03-12 11:43:30

标签: mysql sql sqlite auto-increment uuid

我们正在构建一个新的网络应用程序,该应用程序将在许多本地设备上具有离线iPad / Android应用程序版本,这将涉及插入新数据。因此,我们需要使用UUID来允许与master数据库进行必要的双向同步。为此,我们将UUID存储为BINARY(16)主键。

我在研究后学到的问题是,非顺序主键插入所需的时间会随着时间的推移而增加,而且这些插入会导致碎片化(如here所述)。 AUTO_INCREMENT的好处是新行通常只会添加到表的末尾,因此不会遇到UUID的速度问题。

我的问题是,使用AUTO_INCREMENT列作为主键,然后将UUID列作为非空唯一索引是否更好?据推测,这将具有顺序插入的速度优势,同时保留同步分布式数据库所需的必要UUID。

我可以看到的一个问题是UUID需要被用作对其他表的引用(使用外键约束)(即附加到检查的问题列表,而检查又连接到站点,所有这些都涉及插入,因此所有这些都需要UUID)。从语义上讲,主键作为引用更有意义,但作为一个分布式系统,我们不能使用AUTO_INCREMENTS。对于这些引用(当然还有它们附带的JOIN),使用(非空)唯一索引而不是主键是否存在缺陷?

值得注意的是,主(在线)数据库使用MySQL(InnoDB),分布式(离线)数据库使用SQLite。

修改

考虑到将UUID作为主键(因为它在语义上是这样的)可能更好,如果我将UUID设置为主键并且AUTO_INCREMENT,我是否会获得顺序插入的好处?列作为非null唯一索引?或者它只是确定在哪里插入新行时相关的主键?

4 个答案:

答案 0 :(得分:13)

使用自动增量作为主要加上一个uuid列是一个有效的模型,但你仍然需要解决自动增量带来的一些问题,这一切都取决于你如何进行同步。

无论如何,我一直在使用uuid作为主键(我目前的数据库有50万条记录)而且它仍然非常快,它只会减慢插件的速度,但除非你每天都有非常大量的插入它不应该吓到你。

如果您使用Sql-Server另一个解决方案,您可以查看顺序UUID,其碰撞机会比普通UUID略高,但绝对碰撞几率仍然很低,因为它们是部分顺序的涵盖了碎片化的问题。

答案 1 :(得分:4)

如果您拥有一个大型分布式数据仓库,如果您使用UUID或GUID作为唯一密钥并在以后加入时使用它,那就不好了。

请使用主数据库或数据管道中的顺序代理键,而不是使用UUID或GUID。

分享我们的项目经验作为参考。我们在并行数据仓库中保存了300亿条记录,在我们的系统中,甚至不支持自动增量密钥。我们使用8字节bigint作为主键(实际上我们系统中的唯一键也不受支持,但这不会影响逻辑唯一性),当我们处理文件和加载文件时,我们使用3个字节来生成文件ID,是2 ^ 24个文件,我们每天需要加载大约2,000个文件,所以,2 ^ 24可以支持大约25年,如果没有错的话。

我们使用剩余的4个字节作为行ID,这是40亿行,我们在任何文件中都没有40亿行。我们保留1个字节。在ETL处理期间,我们只需要跟踪master数据库中的文件ID,它支持自动增量ID,当我们需要在处理文件时生成记录ID时,我们组合FileID +保留1字节+4字节rowID。

答案 2 :(得分:0)

您可以使用复合主键,该复合主键由脱机客户端分配的自动递增bigint ID值加上分配给客户端的bigint ID组成。因此,您将在客户端1235上创建条目15。

客户端最好在进行第一次编辑之前从服务器请求其ID,例如,当它首次检索服务器的主数据时。

答案 3 :(得分:0)

来自https://uuid.fyi/uuidorint

UUID

专业人士

  • 全球唯一。
  • 无状态,可以即时生成。
  • 确保安全,因为恶意用户无法猜测ID。
  • 版本1 UUID存储时间戳信息,有时可能有用。

缺点

  • 不可读。
  • 对于使用集群主键的MySQL,Oracle等数据库,如果将其用作主键,则版本4随机生成的UUID将损害插入性能。这是因为它需要对行进行重新排序,以便将新插入的行放置在聚簇索引内的正确位置。另一方面,PostgreSQL使用堆而不是集群主键,因此使用UUID作为PK不会影响PostgreSQL的插入性能。

自动递增整数/顺序

专业人士

  • 可读。如果我们在外部公开它,这将特别有价值。考虑到问题ID,很明显,问题123比问题b1e92c3b-a44a-4856-9fe3-925444ac4c23可读得多。

缺点

  • 不能在分布式系统中使用它,因为不同的主机很可能会产生完全相同的数量。
  • 无法即时生成。相反,我们必须查阅数据库以找出下一个可用的PK。
  • 可以公开一些业务数据,因为最新的ID可以代表库存总数。攻击者还可以扫描整数范围来探索泄漏(尽管如果ACL实施正确,则不应发生泄漏)。