客户端是否可以为写入数据库的对象可靠地生成PK?

Sea*_*son 4 optimization guid client-server primary-key

我一直在为这个困境烦恼一段时间,我以为我会接近这个.

关于我的场景的一些背景知识:

  • 我有播放列表,其中包含0个或更多PlaylistItem子项.
  • 播放列表不经常创建.因此,我可以从服务器请求GUID,等待响应,并在成功时刷新UI以显示已成功添加的播放列表.
  • PlaylistItem对象经常创建.因此,当我等待服务器使用UUID进行响应时,我不能使用加载消息.

我知道,最后一个事实是优化,但我认为它极大地提高了程序的可用性.

不过,我想讨论我唯一识别客户端对象的选项.我首先要强调我尝试过但失败的两个选项,然后是我正在考虑的第三个选项.我希望能够深入了解其他可能的解决方案.


生成将保留到服务器的PK UUID客户端.

这是我的第一选择.这是一个明显的决定,但有一些明显的缺点.这里的第一个问题是客户端UUID不能也不应该被信任用于此类目的.恶意用户可以轻松强制PK冲突.此外,我的理解是,如果我选择生成UUID客户端,我应该期待更大的碰撞机会.抓那个.

基于播放列表GUID和播放列表中的位置生成复合PK

我认为这对我的问题来说是一个棘手但很好的解决方案.PlaylistItem的位置对于给定的播放列表集合是唯一的,并且它可以在客户端和服务器端派生.这似乎是一个很好的解决方案.不幸的是,让我的位置成为PK的一部分打破了我PK的不变性.每当重新排序或删除PlaylistItem时,都需要更新大量的PlaylistItem键.抓那个.

基于播放列表GUID和自动增量PlaylistItem ID生成复合PK

该解决方案类似于上述解决方案,但通过将复合键与位置分离来确保PK是不可变的.这是我正在考虑的当前解决方案.我唯一担心的是恶意用户可能会在发送之前通过修改客户端的自动增加ID来强制冲突.我不认为这种恶意行为会对系统造成任何伤害,而是需要考虑的事情.

好的!你有它.做这一切我是愚蠢的吗?我只是吮吸它并强制我的服务器为我的PlaylistItem对象生成GUID吗?或者,是否可以编写适当的实现?

更新:

我希望在服务器成功保存到数据库之前直观地表示用户的操作,并在保存失败时实现所需的恢复技术.我不确定这是否是傻瓜,但我将通过一个用例场景解释我的推理:

客户想要添加一个新的PlaylistItem.为此,我们会针对创建PlaylistItem的所有必要信息向YouTube API发出请求.在YouTube的API响应后,客户端拥有创建PlaylistItem的所有必要信息,但能够唯一识别它.

此时,用户已经等待了YouTube API的X时间范围.现在,我想在客户端上直观地显示PlaylistItem.如果我选择等待服务器,我现在正在等待X + Y时间帧,然后才能看到成功.在测试中,这种延迟感觉很尴尬.

我的服务器只是亚马逊EC2上的微型实例.我可以通过升级硬件来减少Y时间帧,但我可以通过巧妙的编程完全消除Y. 这是我所面临的困境.

Jon*_*eet 6

好吧,当我在评论中建议时,你似乎喜欢它:)

您可以使用高/低方法,这基本上允许客户端一次保留一堆密钥.最简单的方法可能是使它成为一个复合主键,由两个整数组成.客户端会有一个"给我一把钥匙"的电话.您将自动增加"下一个主键"序列,并记录哪个客户端"拥有"该主键.然后,该客户端可以使用任何次要密钥以及该主要密钥,并且知道它们将与任何其他客户端隔离.

当客户端执行插入时,您可以检查客户端是否使用了正确的主键,即分配给它们的主键.

当然,另一种方法是只生成主键{client ID,UUID}并让客户端只指定任何UUID ......