4

我已经为这个困境烦恼了一段时间,我想我会接近 SO。

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

  • 我有包含 0 个或多个 PlaylistItem 子项的播放列表。
  • 播放列表很少创建。因此,我可以从服务器请求 GUID,等待响应,并在成功时刷新 UI 以显示成功添加的播放列表。
  • PlaylistItem 对象经常被创建。因此,当我等待服务器以 UUID 响应时,我对加载消息不满意

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

尽管如此,我还是想讨论一下我唯一标识我的对象客户端的选项。我将首先强调我尝试过但失败的两个选项,然后是我正在考虑的第三个选项。我希望对其他可能的解决方案有所了解。


生成将持久保存到服务器的 PK UUID 客户端。

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

根据播放列表 GUID 和播放列表中的位置生成复合 PK

我认为这是一个棘手但很好的解决我的问题的方法。PlaylistItem 的位置对于给定的 Playlist 集合是唯一的,并且可以在客户端和服务器端派生。这似乎是一个很好的解决方案。不幸的是,让我的职位成为 PK 的一部分会破坏我的 PK 的不变性。每当一个 PlaylistItem 被重新排序或删除时——需要更新大量的 PlaylistItem 键。抓挠那个。

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

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

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

更新:

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

客户端想要添加一个新的 PlaylistItem。为此,系统会向 YouTube 的 API 发出请求以获取创建 PlaylistItem 所需的所有信息。在 YouTube 的 API 响应后,客户端拥有创建 PlaylistItem 所需的所有信息,但唯一标识它的能力除外。

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

我的服务器只是亚马逊 EC2 上的一个微型实例。我可以通过升级硬件来缩短 Y 时间范围,但我可以通过巧妙的编程完全消除 Y。这就是我面临的困境。

4

1 回答 1

6

好的,当我在评论中提出建议时,您似乎喜欢它:)

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

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

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

于 2013-01-30T21:28:02.090 回答