Я только что наткнулся на этот вопрос и, хотя он старый, я подумал, что было бы полезно добавить пару возможностей, не упомянутых в данных ответах. Кроме того, за последние несколько лет ситуация немного изменилась, поэтому стоит подчеркнуть, что SQL и NoSQL становятся ближе друг к другу.
Один из комментаторов поднял мудрое предостережение: «Если данные реляционные, используйте реляционные». Однако этот комментарий имеет смысл только в реляционном мире, где схемы всегда предшествуют приложению.
ОТНОШЕННЫЙ МИР: Структурные данные> Напишите заявку, чтобы получить ее
NOSQL WORLD: Дизайн приложения> Структура данных соответственно
Даже если данные являются реляционными, NoSQL все еще является опцией. Например, отношения «один ко многим» вообще не являются проблемой и широко рассматриваются в документах MongoDB
Решение 2015 года к проблеме 2010 года
Поскольку этот вопрос был опубликован, предпринимались серьезные попытки приблизить noSQL к SQL. Команда под руководством Янниса Папаконстантину из Калифорнийского университета (Сан-Диего) работает над FORWARD , реализацией SQL ++, которая вскоре может стать решением для постоянных проблем, подобных той, что была опубликована здесь.
На более практическом уровне выпуск Couchbase 4.0 означает, что вы впервые можете выполнять собственные соединения в NoSQL. Они используют свой собственный N1QL. Это пример JOIN
из их учебников :
SELECT usr.personal_details, orders
FROM users_with_orders usr
USE KEYS "Elinor_33313792"
JOIN orders_with_users orders
ON KEYS ARRAY s.order_id FOR s IN usr.shipped_order_history END
N1QL допускает большинство, если не все операции SQL, включая агрегирование, фильтрацию и т. Д.
НЕЧТО НОВОЕ ГИБРИДНОЕ РЕШЕНИЕ
Если MongoDB по-прежнему является единственным вариантом, я хотел бы вернуться к моей точке зрения, что приложение должно иметь приоритет над структурой данных. Ни в одном из ответов не упоминается гибридное встраивание, при котором большинство запрашиваемых данных внедряется в документ / объект, а ссылки сохраняются для меньшего числа случаев.
Пример: может ли информация (кроме имени роли) ждать? Может ли начальная загрузка приложения быть быстрее, не запрашивая ничего, что пользователю пока не нужно?
Это может быть в том случае, если пользователь входит в систему и ему / ей необходимо просмотреть все параметры для всех ролей, которым он / она принадлежит. Тем не менее, пользователь является «инженером», и опции для этой роли используются редко. Это означает, что приложение должно показывать опции для инженера только в том случае, если он / она хочет нажать на них.
Это может быть достигнуто с помощью документа, который сообщает приложению при запуске (1), к каким ролям принадлежит пользователь и (2) где получить информацию о событии, связанном с определенной ролью.
{_id: ObjectID(),
roles: [[“Engineer”, “ObjectId()”],
[“Administrator”, “ObjectId()”]]
}
Или, что еще лучше, индексируйте поле role.name в коллекции ролей, и вам, возможно, не потребуется также встраивать ObjectID ().
Другой пример: информация обо ВСЕХ ролях запрашивается ВСЕ время?
Это также может быть случай, когда пользователь входит в панель управления, и 90% времени выполняет задачи, связанные с ролью «Инженер». Гибридное встраивание может быть выполнено для этой конкретной роли полностью и сохранить ссылки только для остальных.
{_id: ObjectID(),
roles: [{name: “Engineer”,
property1: value1,
property2: value2
},
[“Administrator”, “ObjectId()”]
]
}
Отсутствие схемы - это не просто характеристика NoSQL, это может быть преимуществом в этом случае. Вполне допустимо вложить объекты разных типов в свойство «Роли» пользовательского объекта.