Я щойно натрапив на це питання, і, хоча це давнє, я подумав, що було б корисно додати пару можливостей, не зазначених у відповідях. Крім того, за останні кілька років справи трохи змінилися, тому варто підкреслити, що SQL і NoSQL наближаються один до одного.
Один із коментаторів висловив мудре застереження, що "якщо дані реляційні, то використовуй реляційні". Однак цей коментар має сенс лише у реляційному світі, де схеми завжди постають перед програмою.
Реляційна СВІТ: дані Структура> Написати додаток , щоб отримати його
NoSQL WORLD: додаток> дані Структура дизайну відповідно
Навіть якщо дані є реляційними, NoSQL все ще є варіантом. Наприклад, взаємини "один на багато" взагалі не є проблемою і широко висвітлюються в документах MongoDB
РІШЕННЯ 2015 ДО ПРОБЛЕМИ 2010 року
Після опублікування цього питання були серйозні спроби наближення noSQL до SQL. Команда під керівництвом Яніса Папаконстантіну в Каліфорнійському університеті (Сан-Дієго) працювала над FORWARD , впровадженням SQL ++, який незабаром може стати вирішенням постійних проблем, таких як розміщений тут.
На більш практичному рівні випуск Couchbase 4.0 означав, що вперше ви можете робити рідні JOIN в 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, це може бути перевагою в цьому випадку. Цілком справедливо вкладати різні типи об'єктів у властивості “Ролі” об’єкта користувача.