问题描述
在数据库中创建项目的常规MO是让数据库控制主键(id)的生成。无论您使用的是自动递增的整数ID还是UUID,通常都是这样。
我正在构建一个客户端应用程序(Angular,但与技术无关),希望能够将其内置到脱机行为中。为了允许允许脱机对象创建(和关联),我需要客户端应用程序为新对象生成主键。这既可以与脱机创建的其他对象建立关联,也可以实现独立性(确保我不会由于网络问题将同一对象两次意外地保存到服务器中)。
尽管挑战是当该对象发送到服务器时会发生什么。是使用临时客户端ID,然后替换为服务器随后生成的ID,还是在客户端和服务器之间使用某种ID转换层-this is what Trello did when building their offline functionality。
但是,我想到可能还有第三种方法。我正在对后端的所有表使用UUID。因此,这使我意识到,从理论上讲,我可以将UUID插入前端生成的后端。 UUID的全部要点是它们是通用的,因此前端不需要知道服务器状态即可生成一个。如果它们确实发生冲突,则服务器上的唯一性标准将防止重复。
这是合法的方法吗?风险似乎是1.碰撞和2.我未曾预料到的任何形式的安全性。 Collison似乎可以通过生成UUID的方式来处理,但我无法确定允许客户端选择插入对象的ID是否存在风险。
解决方法
但是,我想到可能还有第三种方法。我正在对后端的所有表使用UUID。因此,这使我意识到,从理论上讲,我可以将UUID插入前端生成的后端。 UUID的全部要点是它们是通用的,因此前端不需要知道服务器状态即可生成一个。如果它们确实发生冲突,则服务器上的唯一性标准将防止重复。
是的,这很好。 Postgres even has a UUID type。
如果客户端不发送,则将默认ID设置为a server-generated UUID。
- 碰撞。
UUID设计为不会发生冲突。
- 我没有想到的任何形式的安全性。
避免使用UUIDv1,因为...
这涉及计算机的MAC地址和时间戳。请注意,这种UUID会揭示创建标识符的计算机的身份以及创建标识符的时间,这可能使其不适用于某些对安全敏感的应用程序。
您可以改用uuid_generate_v1mc
来掩盖MAC地址。
避免使用UUIDv3,因为它使用MD5。请改用UUIDv5。
UUIDv4是最简单的,它是一个122位随机数,内置在Postgres中(其他都在常用的uuid-osp extension中)。但是,这取决于每个客户端的随机数生成器的强度。但是,即使是坏的UUIDv4生成器也比增加整数好。