Erlang 帮助我理解mnesia(NoSQL)建模

Erlang 帮助我理解mnesia(NoSQL)建模,erlang,nosql,mnesia,Erlang,Nosql,Mnesia,在我寻求理解记忆的过程中,我仍然在用关系的术语思考。因此,我将把我的挣扎放在这里,并寻求解决它们的最佳方法 一对多关系 假设我有一群人 -record(contact, {name, phone}). 现在,我知道我可以将电话定义为始终保存为列表,这样人们就可以有多个电话号码,我想这就是实现这一点的方法。(是吗?然后我如何从另一个角度查找,比如,找到一个号码的名称?) 多对多关系 现在,让我们假设我有多个组,我可以把人放在其中。组名没有任何意义,它们只是名称;其概念是“unix系统组”或“标

在我寻求理解记忆的过程中,我仍然在用关系的术语思考。因此,我将把我的挣扎放在这里,并寻求解决它们的最佳方法

一对多关系 假设我有一群人

-record(contact, {name, phone}). 
现在,我知道我可以将电话定义为始终保存为列表,这样人们就可以有多个电话号码,我想这就是实现这一点的方法。(是吗?然后我如何从另一个角度查找,比如,找到一个号码的名称?

多对多关系 现在,让我们假设我有多个组,我可以把人放在其中。组名没有任何意义,它们只是名称;其概念是“unix系统组”或“标签”。天真地说,我会将这个成员资格建模为一个proplist,比如

{groups [{friends, bool()}, {family, bool()}, {work, bool()}]} %% and so on...
例如,作为上面“联系人”记录中的字段。如果我希望能够根据组名快速查找组中的所有成员,并且还希望能够查找个人注册的所有组,那么在mnesia中对此进行建模的最佳方法是什么?当然,我也可以将其建模为只包含组标识符的列表。与mnesia一起使用时,建模的最佳方法是什么?


如果这个问题是愚蠢的,我道歉。有很多关于mnesia的文档,但是它缺乏(IMO)一些关于整体使用的好例子

首先,您要求提供具有关键价值的商店设计模式。很好。 在我回答你的问题之前,让我们先弄清楚什么是记忆。它是k-v DB,包含在OTP中。因为它是本地的,所以从Erlang使用起来非常舒服。但是要小心。这是一个古老的数据库,具有非常古老的假设(例如,使用线性散列的数据分布)。因此,请继续学习并使用它,但对于生产,请慢慢来浏览NoSQL商店,以找到最适合您需求的产品

@电话的例子。不要将内容存储为字符串(list())-这对GC来说非常沉重。我会创建两个字段,比如phone_1::<<二进制>>,phone_2::<<<二进制>>,phone_extra:[<<<二进制>>],并在最频繁的查询字段上建立索引。此外,记忆标记也很棘手——当节点崩溃并上升时,它们需要重新构建自己(这可能需要非常长的时间)


@家庭榜样。使用平面名称空间非常困难。您可以使用更复杂的键。。也许为组创建单独的表并保留成员的标识符?或者每个成员都有他所属组的ID(难以维护..)。如果你想认识朋友,我会在提交数据之前实现某种合同(A IS B的朋友IFF B是A的朋友)-这种方法将处理数据中的最终一致性和冲突。

< P>对于第一个例子,考虑此记录:

-record(contact, {name, [phonenumber, phonenumber, ...]}).
contact
是一个包含两个字段的记录,
name
phone
,其中phone是电话号码列表。正如user425720所说,如果您对小的存储空间有极端的要求,那么将它们存储为字符串以外的内容是有意义的

现在,使用键值存储很难“获取”的部分来了:您还需要存储反向关系。换句话说,您需要类似于以下内容的内容:

-record(phone, {phonenumber, contactname}).
-record(contact, {name, [{family, [group_id, group_id]}, {work, [..]}]}).
如果您的应用程序中有一个抽象数据库处理的层,那么您可以使它在添加/更改联系人时始终添加/更改电话记录

--

第二个例子,考虑这两个记录:

-record(contact, {uuid, name, [group_id, group_id]}).
-record(group, {uuid, name, [contact_id, contact_id]}).
最简单的方法是只存储指向相关记录的ID。由于Mnesia没有引用完整性的概念,例如,如果您删除一个组而不从所有用户中删除该组,则这可能会变得不同步

如果需要在联系人记录中存储组类型,可以使用以下选项:

-record(phone, {phonenumber, contactname}).
-record(contact, {name, [{family, [group_id, group_id]}, {work, [..]}]}).
--

您的第二个问题也可以通过使用中间记录来解决,您可以将其视为“成员资格”


可以有任意数量的“会员”记录。每个用户组都会有一个记录。

不必向我道歉,因为这个问题一点也不愚蠢+1虽然我没有投票否决你,但我很清楚你没有理解我在第二个问题中提出的问题(或者我没有说得足够清楚)。我想建立多对多关系模型;“家庭”和“朋友”并没有特别提及任何概念。我也已经指出,有成员的列表是一种方式,但要求提供更好的方式。是的,内华达州。然而,你们的元组示例似乎就是我在第二部分中写的。第一部分说,将多对多建模为包含成员键的单独表。这取决于数据库。在Riak中,有两级密钥结构(bucket,key)-(value),因此您可以将所有goup成员放在一个bucket中。从定义上看,KV商店不善于表示关系。