Помогите мне понять mnesia (NoSQL) моделирование - PullRequest
12 голосов
/ 06 ноября 2010

В моем стремлении понять Мнезию я все еще борюсь с мышлением в терминах отношений.Поэтому я поставлю здесь свои проблемы и попрошу лучший способ их решить.

отношения один ко многим Скажем, у меня есть группа людей,

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

Теперь я знаю, что могу определить телефон, который всегда будет сохраняться каксписок, чтобы люди могли иметь несколько телефонных номеров, и я полагаю, что это способ сделать это (верно? Как бы я тогда посмотрел на это с другой стороны, скажем, найти имя для номера?) .

отношения «многие ко многим» теперь давайте представим, что у меня есть несколько групп, в которые я могу поместить людей. Имена групп не имеют никакого значения, они просто имена;понятие "системные группы Unix" или "метки" .Наивно, я бы смоделировал это членство в качестве проплиста, например

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

как поле в записи "контакта" сверху, например.Как лучше всего смоделировать это в mnesia, если я хочу иметь возможность быстро искать всех членов группы по имени группы, а также иметь возможность искать все группы, в которых зарегистрировано лицо?Конечно, я мог бы просто смоделировать это как список, содержащий только идентификаторы групп.Для использования с mnesia, , как лучше всего это смоделировать?

Прошу прощения, если этот вопрос глуп.Есть много документации по mnesia, но в ней нет (IMO) хороших примеров для общего использования.

Ответы [ 2 ]

3 голосов
/ 24 ноября 2010

Для первого примера рассмотрим эту запись:

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

contact - это запись с двумя полями, name и phone, где phone - список телефонных номеров.Как сказал user425720, может иметь смысл хранить их как что-то иное, чем строки, если у вас есть экстремальные требования, например, к небольшому объему хранилища.

Теперь вот часть, которую трудно «достать» с помощью ключа.хранилища значений: вам также необходимо хранить обратные отношения.Другими словами, вам нужно что-то похожее на следующее:

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

Если в вашем приложении есть слой для абстрагирования от обработки базы данных, вы можете всегда добавлять / изменять записи телефона при добавлении / измененииконтакт.

-

Для второго примера рассмотрим эти две записи:

-record(contact, {uuid, name, [group_id, group_id]}).
-record(group, {uuid, name, [contact_id, contact_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

Может быть любое количество записей "членства".Для каждой группы пользователей будет одна запись.

0 голосов
/ 07 ноября 2010

Прежде всего, вы спрашиваете о шаблонах дизайна хранилища ключей.Прекрасно.Прежде чем я попытаюсь ответить на ваш вопрос, давайте поясним - что такое Мнезия.Это kv DB, которая входит в OTP.Поскольку он является родным, его очень удобно использовать от Erlang.Но будь осторожен.Это старая база данных с очень древними предположениями (например, распределение данных с линейным хешированием).Так что продолжайте, учитесь и играйте с ним, но для производства не торопитесь и просмотрите магазин NoSQL, чтобы найти лучшее для ваших нужд.

@ пример телефона.Не храните вещи как строки (list ()) - это очень тяжело для GC.Я хотел бы создать пару полей, таких как phone_1 :: <<двоичный>>, phone_2 :: <<двоичный>>, phone_extra :: [<<двоичный>>] и построить индекс по наиболее частому полю запроса.Кроме того, признаки mnesia хитрые - когда происходит сбой и выход узла из строя, ему необходимо восстановить себя (это может занять очень много времени).

@ пример семейства.Это довольно сложно с плоским пространством имен.Вы можете играть с более сложными ключами. Может быть, создать отдельную таблицу для TheGroup и сохранить идентификаторы членов?Или у каждого участника будут идентификаторы групп, к которым он принадлежит (трудно поддерживать ...).Если вы хотите узнать друзей, я бы заключил какой-то контракт, прежде чем представлять данные (А - друг Б, если Б - друг А) - этот подход будет справляться с возможной последовательностью и конфликтами в данных.

...