有没有人有任何关于如何在最终一致的环境中进行独特价值保留的链接/资源?
示例:用户在注册时可以选择他们的用户名。即使两个用户同时尝试获取相同的名称,也只有一个用户应该成功。
我有几个潜在的解决方案在我脑海中浮现,但我想知道是否有人已经为这个设计做了跑腿工作。
有没有人有任何关于如何在最终一致的环境中进行独特价值保留的链接/资源?
示例:用户在注册时可以选择他们的用户名。即使两个用户同时尝试获取相同的名称,也只有一个用户应该成功。
我有几个潜在的解决方案在我脑海中浮现,但我想知道是否有人已经为这个设计做了跑腿工作。
唯一性约束需要可序列化/线性化。这使得在不可序列化的系统中无法实现。CAP 意义上的所有 AP 系统都是不可序列化的。
最终一致性的定义模糊,但它几乎暗示了一个不可序列化的系统。因此,您的要求是不可能实现的。
选择一个一致的数据库以获得您需要的唯一性保证,并可能将该数据复制到您最终一致的数据存储中。
这是理论答案完全愚蠢的问题之一。是的,任何唯一标识符都需要某种形式的序列化。
但在现实世界中,很容易扩展现有的唯一标识符以形成新的唯一标识符。最明显的是您机器的公共 IP 地址和时间戳。任何时候都只能有一个 IP 地址的所有者,因此组合是唯一的。您现在只需决定允许从一个节点以时间戳的精度创建多少条记录。
域名也具有相同的特征,但不那么紧凑。但它们更容易验证,这就是为什么它们通常用于为对象类形成真正的全局命名空间。
当你提到用户名字段时,你让我想起了一个古老的病毒笑话,即 50 年后人类必须解决的最大问题是在互联网上找到可用的用户名。
您在评论中提到的问题与锁定和并发插入有关,详见此处:http ://dev.mysql.com/doc/refman/5.0/en/locking-issues.html
现在,据我所知,插入语句在执行之前被缓存并存储在队列中,而不管它们的到达时间相似。因此,一个会自动获得唯一值(例如:用户名),而另一个不会。但实际上,让两个用户在同一个原子时间选择同一个用户名的几率非常非常低。即使在实验室环境中,也有很多事情需要完美地工作才能进行测试。
另一方面,您可以允许两个用户使用相同的用户名进行注册。例如:假设您有一个用户帐户系统,您可以在其中允许用户使用用户名和密码进行注册。用户名仅限于以下字符:a 到 z、A 到 Z、0 到 9 以及特殊字符 _(下划线)和 .(句号)。您可以将用户名(在您的 mysql 表中定义为不唯一)与一个特殊字符(_ 和 . 除外)连接起来,然后是您在 mysql 表中的唯一标识符(比如说 user_id)。
当用户尝试登录时,您将他的输入与所有子字符串用户名的集合进行比较(您只取您定义的特殊字符之前的值)。将匹配项记录在一个数组中,然后检查用户密码是否与找到的任何用户密码匹配。如果是,那么你让他登录,如果不是,那么你不登录。
尽管我在实践中看到了上述内容,但我非常反对。我会使用用户的电子邮件而不是唯一的用户名。由于电子邮件是独一无二的,因此这是一个更简单、更清晰的解决方案。没有两个用户拥有相同的电子邮件帐户,除非他们共享该地址(例如,听起来像 contact@xyzcompany.com 的地址)。