我试图弄清楚如何为应用程序实现组成员资格模块,其中组的自然键是其用户集。换句话说,任何用户组合都只能创建一个组。
通过示例的方式,假设我们有三个用户:UserA,UserB和UserC。现在,假设UserA从UserB开始一个组。我们将其称为Group1。如果UserA尝试使用UserB启动另一个组,或者UserB尝试使用UserA创建一个组,则将返回Group1。但是,由于我们还没有一个具有该用户组合的组,因此UserA仍然可以从UserB和UserC开始一个组。我们将其称为Group2。
所以Group1的自然键是UserA + UserB。
Group2的自然键是UserA + UserB + UserC。
希望这是有道理的。
以上示例的表内容为:
User
=================
user_id username
1 UserA
2 UserB
3 UserC
Group
=========================
group_id name alt_key
1 Group1 1,2
2 Group2 1,2,3
Member
============================
member_id group_id user_id
1 1 1
2 1 2
3 2 1
4 2 2
5 2 3
alt_key是用户ID的排序列表。
很明显,此方法的可伸缩性不是很高,因此我通过对alt_key进行哈希处理对其进行了一些改进。这使得较大的组的密钥显着减小,但是由于哈希值不是唯一的,因此仍需要进行大量的体操操作以确保用户无法创建重复的组。
无论如何,我想知道是否存在一种模式或更好的实现方式,它允许每个组的用户数量“无限”,而无需疯狂地查询以确保组成员身份是唯一的。
编辑:为什么当前的解决方案不可扩展?对于初学者来说,对任意规模的user_id列表进行排序和哈希处理都不是很快,也不是节省内存。除此之外,尽管使用散列确实会大大缩小搜索范围,但检查一组用户是否存在也非常棘手。我只是希望有人知道更好的方法。
当前,我正在限制组的大小以减轻可伸缩性问题,但我想尽可能避免这种情况。
编辑:安全并不是真正的问题。哈希纯粹用作缩小组成员资格搜索的一种方式。它是使用所有内部整数ID构建的,并且永远不会通过API公开。当前代码(在Python 3.6中):
hashlib.md5(marshal.dumps(deduplicated_and_sorted_user_id_iterable))
这当然会导致可伸缩性问题,因为我必须将所有id都放入内存中才能对它们进行排序和散列。
答案 0 :(得分:1)
您可以使用长Zobrist hash并假设所有碰撞都是真实的正值。用类似
的公式计算哈希p
不需要排序或大量中间存储空间。将HMAC-SHA256(SecretKey1,
HMAC-SHA256(SecretKey2, UserA) XOR HMAC-SHA256(SecretKey2, UserB) XOR ...),
视为随机预言,并假设HMAC-SHA256
和中间计算是秘密的,给定SecretKey[12]
组(一个非常大的数目)的组发生碰撞的概率小于{{1} },它是如此之小,几乎肯定会在出现误报之前破坏您的数据库。 (外部2^64
阻止了定时攻击,并提供了对数据库被盗的抵抗力。)
我将考虑是否有可能以可证明的安全方式摆脱2^-128
而又不增加排序要求。