您需要“用户 ID、选民名单和结果”。让我们看看它看起来是一个元组:
{User :: user_id(), [Voters :: user_id()], Outcome :: boolean()}
没那么难。这些元组的列表——也不难。其中的 dict 有点复杂,因为你最终会得到(基本上,如果这是一个 proplist,使用上面的类型):
{User, {[Voters], Outcome}}
处理起来有点不高兴。例如,您可能希望按结果过滤,但现在它被隐藏在元组内的元组中,而平面元组列表允许简单过滤(真正的过滤器,或者只是保护列表理解,或其他)或使用lists:keysearch/3
. 这使复杂的搜索变得更加尴尬,尤其是如果您想知道特定选民投票踢某人的次数。
使用 ETS 肯定可以使基本问题变得更容易,因为它具有以比使用元组列表更快的方式完全处理元组的设施keysearch/3
(并且,我假设您有成千上万的案例,因此元组列表是不足——但与往常一样,首先尝试这种方式,您可能会发现元组列表是完全足够的!)。另一方面,如果搜索案例变得更加复杂,或者案例需要持久存储并且仍然受益于内存中的操作,或者您需要多个索引等,那么您真的应该转向 Mnesia。
除此之外......你正在处理嵌套数据,虽然这实际上在 90% 的情况下都很好,但另外 10% 的时间你最终要么重新发明关系数据(但更糟糕的是,实际效用较少,速度较慢( “——我知道这不是每个人都这样)。
作为参考,您的数据在分解时看起来像这样(为了示例,假设用户 ID 是电子邮件地址):
table user
attributes
id EmailAddress
conditions
pk id
table kick
attributes
id UUID
user EmailAddress
outcome Boolean
conditions
pk id
fk user
table vote
attributes
kick UUID
user EmailAddress
conditions
pk (kick user)
fk kick
fk user
虽然很明显,上述元组的User
和[Voter]
组件引用了用户记录,但为什么尝试使用元组提取某个用户投出的所有投票的列表是一个如此讨厌的过程并不那么明显。当我们查看分解后的数据时,我们意识到这是三个表,vote
如果您有此要求,我们真的希望我们可以单独运行一个查询。但是如果你没有这个要求,那么不用担心,只需在 ETS 或 Mnesia 中使用元组!:-) 这种数据在 Erlang 中非常小。