Лучшие способы моделировать этот простой дизайн схемы (MongoDB)?
У меня есть следующий случай: пользователь может добавить контакты (кто другие пользователи) на веб-сайте. При желании пользователь также может организовать свои контакты в группы. Пользователь может иметь много адресов электронной почты, адресов и телефонных номеров.
Я подумал о следующем дизайне схемы (хранилище документов /mongodb). Есть ли способы улучшить это? Моя главная проблема заключается в том, что изображение профиля встроено в документ. Я знаю, что это нехорошая практика, но для этой конкретной цели (задания) я также должен вставить сюда картинку (blob / gridfs). Но мне интересно, как эта схема может быть улучшена.
1 ответ
Для пользователей, я думаю, что ваша текущая схема в порядке. Хранение нескольких адресов, телефонных номеров и адресов электронной почты в массивах - это хорошо, потому что их не должно быть слишком много для конкретного человека, и легко задать вопрос "у кого есть этот адрес электронной почты" или "дать мне все номера телефонов этот человек". Вы, кажется, имеете избыточный e-mail
хотя поле - это специальный адрес электронной почты, такой как адрес учетной записи, который отличается от контактного адреса электронной почты? Если это так, я бы дал ему описательное имя ради других сопровождающих, например, имя account_email
, Я бы не стал хранить эту фотографию как блоб, но вы сказали, что это какое-то другое требование, поэтому я не буду его критиковать.
Мне нравится идея создания контактов с группами с использованием отдельной коллекции контактов. Я бы contacts
коллекция с каждым документом, представляющим один контакт
{
"_id" : ObjectId("..."),
"owner_id" : ObjectId("..."), // reference to user document of contact owner
"contact_id" : ObjectId("..."), // reference to user document of contact
"group" : "Rivals" // group name
}
Индекс на { "owner_id" : 1, "contact_id" : 1 }
и возможно { "owner_id" : 1, "group" : 1 }
и тогда запросы, подобные следующим, будут быстрыми:
// get all contacts for user x
db.contacts.find({ "owner_id" : x })
// is user y a contact of user x?
db.contacts.count({ "owner_id" : x, "contact_id" : y }) != 0
// get all contacts in group "family" for user x
db.contacts.find({ "owner_id" : x, "group" : "family" })
После извлечения контактов для получения удобной для пользователя информации об отображении вам потребуется выполнить второй запрос (объединение на уровне приложения), чтобы получить фактические пользовательские документы контактов. Если вы хотите, вы можете денормализовать некоторые контактные данные в контактный документ
{
"_id" : ObjectId("..."),
"owner_id" : ObjectId("..."), // reference to user document of contact owner
"contact_id" : ObjectId("..."), // reference to user document of contact
"group" : "Rivals", // group name
"contact_name" : "Franke Frankers"
}
Вам не нужно будет делать второй запрос, если вы включаете обычно необходимую информацию, но если контакт обновляет свою информацию, вам может потребоваться обновить каждый документ контакта, ссылающийся на них.