将客户端应用程序生成的 UUID 插入到 Postgres 中是否合法?

Is it legitimate to insert UUIDs into Postgres that have been generated by a client application?

在数据库中创建项目的正常 MO 是让数据库控制主键 (id) 的生成。无论您使用的是自动递增的整数 ID 还是 UUID,这通常都是正确的。

我正在构建一个客户端应用程序(Angular 但技术无关紧要),我希望能够在其中构建离线行为。为了允许离线对象创建(和关联),我需要客户端应用程序为新对象生成主键。这既允许与离线创建的其他对象关联,也允许无能(确保我不会由于网络问题而意外地将同一个对象保存到服务器两次)。

但挑战在于当该对象被发送到服务器时会发生什么。您是使用临时客户端 ID,然后将其替换为服务器随后生成的 ID,还是在客户端和服务器之间使用某种 ID 转换层 - this is what Trello did when building their offline functionality.

不过,我想到了可能还有第三种方式。我正在为后端的所有表使用 UUID。因此,这让我意识到,理论上我可以将前端生成的 UUID 插入后端。 UUID 的全部意义在于它们是普遍唯一的,因此前端不需要知道服务器状态即可生成 UUID。万一它们发生碰撞,服务器上的唯一性标准将防止重复。

这是合法的做法吗?风险似乎是 1. 碰撞和 2. 我没有预料到的任何形式的安全措施。 Collisons 似乎通过生成 UUID 的方式得到处理,但我不知道允许客户端选择插入对象的 ID 是否存在风险。

However, it occurred to me that there may be a third way. I'm using UUIDs for all tables on the back end. And so this made me realise that I could in theory insert a UUID into the back end that was generated on the front end. The whole point of UUIDs is that they're universally unique so the front end doesn't need to know the server state to generate one. In the unlikely event that they do collide then the uniqueness criteria on the server would prevent a duplicate.

是的,这很好。 Postgres even has a UUID type.

如果客户端不发送,请将默认 ID 设置为 a server-generated UUID

  1. Collisions.

UUID 旨在避免冲突。

  1. Any form of security that I haven't anticipated.

避免使用 UUIDv1,因为...

This involves the MAC address of the computer and a time stamp. Note that UUIDs of this kind reveal the identity of the computer that created the identifier and the time at which it did so, which might make it unsuitable for certain security-sensitive applications.

您可以改用 uuid_generate_v1mc 来掩盖 MAC 地址。

避免使用 UUIDv3,因为它使用 MD5。请改用 UUIDv5。

UUIDv4 is simplest, it's a 122 bit random number, and built into Postgres (the others are in the commonly available uuid-osp extension)。但是,这取决于每个客户端的随机数生成器的强度。但即使是一个糟糕的 UUIDv4 生成器也比增加一个整数要好。