我正在从事一个基于 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 获取用户是不可能的。我们必须使用完整的实体键。
这种方法还有其他缺点吗?有人尝试过类似的东西吗?
编辑
正如我在评论中指出的那样,上述哈希值无法正常工作,因为它只会阻止注册具有非唯一电子邮件的用户以及与这些电子邮件匹配的非唯一用户名。如果哈希是基于单个字段计算的,它将起作用。
尽管如此,我发现这种分片的概念本身很有趣,也许值得讨论。