Подтвердить что ты не робот

Помогите мне понять моделирование mnesia (NoSQL)

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

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

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

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

много-ко-многим-отношения теперь пусть предположим, что у меня есть несколько групп, в которые я могу поместить людей. Названия групп не имеют никакого значения, они просто имена; концепция "unix system groups" или "label". Наивно, я бы моделировал это членство как пролистник, например

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

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

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

4b9b3361

Ответ 1

В первом примере рассмотрим эту запись:

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

contact - это запись с двумя полями name и 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

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

Ответ 2

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

Пример

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

Пример

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