2

我正在从事一个基于 GAE 的项目,该项目涉及大量用户群(可能是数百万用户)。我们使用 Datastore 来实现持久性。用户将通过用户名和电子邮件地址来识别,因此这两个属性在所有类型的实体中应该是唯一的。因为 Datastore 不支持 ID 以外的唯一字段,所以我们需要事务来确保新用户注册时这些字段的唯一性。为了进行交易,用户实体需要包含在实体组中。

正如这里所指出的,不建议拥有大型实体组。因此,考虑到可能存储的大量用户,我正在考虑将它们放入多个较小的实体组中。每个组将有一个共同的父级,其 ID 由两个唯一字段(例如 MD5 总和的一部分)生成。插入新用户可能如下所示(在 Python 中):

@ndb.transactional
def register_new_user(login, email, full_name) :
    # validation code omitted
    user = User(login = login, email = email, full_name = full_name)
    group_id = a_simple_hash(login, email)
    group_key = ndb.Key('UserGroup', group_id)
    query = User.query(ancestor = group_key).filter(ndb.OR(User.login = login, User.email = email))
    if not query.get() :
        user.put()

我在这个解决方案中看到的一个问题是,仅通过 ID 获取用户是不可能的。我们必须使用完整的实体键。

这种方法还有其他缺点吗?有人尝试过类似的东西吗?

编辑

正如我在评论中指出的那样,上述哈希值无法正常工作,因为它只会阻止注册具有非唯一电子邮件的用户以及与这些电子邮件匹配的非唯一用户名。如果哈希是基于单个字段计算的,它将起作用。

尽管如此,我发现这种分片的概念本身很有趣,也许值得讨论。

4

2 回答 2

0

在我看来,您在这里想多了:两个用户同时使用相同的用户名注册的概率是多少?很苗条。对于这种情况,最终的一致性已经足够好了,因为你没有纳秒级的精度......除非你计划拥有比 facebook 更多的用户,并且每秒都有人注册。

不同的用户几乎不可能使用同一电子邮件注册,因为电子邮件提供商已经为您完成了检查!只有用户可以尝试使用相同的电子邮件地址开设两个帐户。最终一致性对于这个查询也足够好。

您的每个用户实体都属于他们自己的实体组。

实际上在大多数用例中,您的用户是最明显的根实体:人们使用数据存储是因为他们需要可扩展性,而且大多数时候面向用户的应用程序需要巨大的规模。

于 2014-03-19T15:25:28.883 回答
0

电子邮件地址归用户所有并且是唯一的。所以有一个很小的变化,有人会(尝试)使用相同的电子邮件地址。

所以我的方法是:get_or_insert 一个新的登录名,这样可以很容易地登录(通过密钥),然后验证电子邮件地址是否唯一。

如果它不是唯一的,您可以丢弃或.....做其他事情

实体组对事务有意义。我对您计划的交易感兴趣,因为我不了解您的实体组密钥哈希。哪些实体将成为实体组的一部分,为什么?

具有相同登录名的用户将成为另一个实体组的一部分,如果我确实了解您的哈希值?看起来您的实体组拥有一个实体。

于 2014-03-18T17:47:07.780 回答