12

在我寻求理解 Mnesia 的过程中,我仍然在努力思考关系方面的问题。所以我会把我的挣扎放在这里,并寻求解决它们的最佳方法。

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

-record(contact, {name, phone}). 

现在,我知道我可以将电话定义为始终保存为列表,因此人们可以有多个电话号码,我想这就是这样做的方法(是吗?然后我将如何反过来查找,比如说,找到一个数字的名字?)

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

{groups [{friends, bool()}, {family, bool()}, {work, bool()}]} %% and so on...

例如,作为上面“联系人”记录中的一个字段。如果我希望能够根据组名快速查找组的所有成员,并且还希望能够查找个人注册的所有组,那么在 mnesia 中对此进行建模的最佳方法是什么?当然,我也可以将其建模为仅包含组标识符的列表。对于与 mnesia 一起使用,对此进行建模的最佳方法是什么?

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

4

2 回答 2

3

对于第一个示例,请考虑以下记录:

-record(contact, {name, [phonenumber, phonenumber, ...]}).

contact是包含两个字段的记录,name其中phonephone 是电话号码列表。正如 user425720 所说,例如,如果您对小存储空间有极端要求,那么将这些存储为字符串以外的东西可能是有意义的。

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

-record(phone, {phonenumber, contactname}).

如果您的应用程序中有一个层可以抽象出数据库处理,您可以让它在添加/更改联系人时始终添加/更改电话记录。

--

对于第二个示例,请考虑以下两条记录:

-record(contact, {uuid, name, [group_id, group_id]}).
-record(group, {uuid, name, [contact_id, contact_id]}).

最简单的方法是只存储指向相关记录的 id。由于 Mnesia 没有参照完整性的概念,例如,如果您删除一个组而不从所有用户中删除该组,这可能会变得不同步。

如果您需要在联系人记录中存储组的类型,您可以使用以下内容:

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

--

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

-record(contact, {uuid, name, ...}).
-record(group, {uuid, name, ...}).
-record(membership, {contact_uuid, group_uuid}). # must use 'bag' table type

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

于 2010-11-24T07:36:27.277 回答
-1

首先,您需要键值存储设计模式。完全没问题。在我尝试回答您的问题之前,让我们先弄清楚 - 什么是 Mnesia。它是 kv DB,包含在 OTP 中。因为它是原生的,所以从 Erlang 使用起来非常舒服。但小心点。这是具有非常古老假设的旧数据库(例如,具有线性散列的数据分布)。因此,继续学习和使用它,但对于生产,请花点时间浏览 NoSQL 商店以找到最适合您需求的产品。

@电话示例。不要将内容存储为字符串 (list()) - 这对于 GC 来说非常繁重。我会创建几个字段,例如 phone_1 :: < < binary > > 、phone_2 :: < < binary > >、phone_extra :: [ < < binary > > ] 并在最常见的查询字段上建立索引。mnesia indicies 也很棘手 - 当节点崩溃并上升时,它们需要重建自己(这可能需要非常多的时间)。

@family 示例。使用平面命名空间很难。您可以使用更复杂的键。也许为 TheGroup 创建单独的表并保留成员的标识符?或者每个成员都有他所属的组的 ID(难以维护......)。如果你想认识朋友,我会在呈现数据之前实现某种契约(A 是 B 的朋友,如果 B 是 A 的朋友)——这种方法可以处理数据的最终一致性和冲突。

于 2010-11-06T23:13:57.893 回答