【问题标题】:Index instead of primary key on UUID type in PostgreSQLPostgreSQL中UUID类型的索引而不是主键
【发布时间】:2023-03-15 06:45:01
【问题描述】:

首先,我已经阅读了一些关于此的帖子,例如: Postgresql: UUID or SEQUENCE for primary key?

我的问题很简单:我表中的 ID 是 UUID v4(在 Rails 中或从 iOS 应用程序创建)。 由于默认情况下 UUID 是唯一的,我可以删除 ID 上的主键并在其上添加索引吗?主要(也是唯一的?)目标是在每次插入时节省插入时间(几毫秒)(PostgreSQL 不必验证 ID 是否已被使用)。

这是一个好的选择吗?或者我是否保留 PK 在插入之前添加另一个唯一性验证?

对于信息,该表将管理大约 1000 万条记录。

【问题讨论】:

  • 理论上,没有PK约束的表是没有意义的。 (顺便说一句:我有一个带独特袜子的抽屉......)

标签: postgresql indexing uuid


【解决方案1】:

您所描述的两个键显然都被用作代理键。代理意味着它们不是从传入数据派生的,因此除了提供唯一性之外与它没有任何关系。

为了提供唯一性,您不需要 2 个密钥,因此您的问题的答案是您可以删除其中一个或另一个密钥。表的大小在这里并不是一个真正的因素,因为 uuid_v4() 将为比 10M 行更大的数据集提供唯一性。

拥有 2 个唯一性键不仅没有必要,而且也是一个瓶颈。这两个值都必须在插入时创建,并且都必须验证其唯一性。删除其中一个显然是更好的做法。

【讨论】:

  • 我没有 2 个键,只有一个:我的 ID 设置为 UUID 类型。我的问题只是在此字段上设置一个 PK 或一个索引(不是 uniq,因为 UUID 默认为 uniq),以节省插入时的时间。
  • 主键意味着无论如何都会创建一个索引来执行
  • @KirkRoybal 我正在使用 mySql,并且我有 id(Long) 和 uuid 字段的主键。 uuid 字段是表和应用程序之间实际通信的行的标识。我正在考虑摆脱 id 字段并使用 uuid 字段作为主键。这有意义吗?
【解决方案2】:

首先:UUID 并不是真正唯一的。但是产生双精度值的机会真的很低(How unique is UUID?)。

但是 UUID 还有一些其他问题。 UUID 用于在不同点之间交换数据。因此,如果您考虑两个通信的数据库将共享具有相同 UUID 的相同数据集。现在考虑一个存档,存储来自许多来源的数据集。您可以从一些旧的通信中获得具有相同 UUID 的数据集。

因此,这取决于您当前(也许将来可能?)的用例是否会造成任何问题。

此外,我不确定它是否对与主键索引空间有关的简单整数值产生任何优势。请注意,每个主键都会自动creates an internal index per default(因此无需创建单独的索引)。所以整数列的主键索引可能会更小更快。

【讨论】:

  • 我需要这个 ID 作为 UUID 字段,因为它用于来自许多设备的同步引擎(拉、推)。我不能改用简单的整数。而且我不能将 ID 设置为整数作为 PK,而另一个字段 UUID 仅用于同步引擎,因为它无法在“全局”系统上的 ID 字段上使用与其他表的关系。
  • 我并不是说你应该替换 UUID,但不要将它用作 PK 列。我的意思是你应该添加一个简单的整数列作为 PK(更小的索引,安全地考虑某些通信日志或档案中的双倍 UUID 行等)
  • UUID 可以很好地在源之间同步数据。但我不会说它们是为此而“制造”的。它可以解决多个问题。一旦这样的问题是一个无符号整数索引,它会翻转大约 4M 记录。
猜你喜欢
  • 2018-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-05
  • 1970-01-01
  • 2018-11-01
  • 2013-01-20
  • 1970-01-01
相关资源
最近更新 更多