Одна из целей разработки SQL состоит в том, что любые данные могут храниться / запрашиваться в любой реляционной базе данных. Между платформами есть некоторые различия, но в целом правильный способ обработки конкретной структуры данных хорошо известен и легко автоматизируется, но требующий довольно подробного кода. Это не относится к NoSQL - обычно вы будете напрямую хранить данные, используемые в вашем приложении, а не пытаться отобразить их в реляционную структуру, и без объединений или других различий между объектами и реляциями код отображения тривиален.
Помимо генерации стандартного кода доступа к данным, одной из основных целей ORM является абстракция различий между платформами. По моему опыту, возможность переключения платформ всегда была чисто теоретической, и этот подход с наименьшим общим знаменателем просто не будет работать для NoSQL, поскольку платформа обычно выбирается специально для возможностей, отсутствующих на других платформах. Ваш пример предназначен только для самого простого хранилища значений ключей - в зависимости от вашей платформы у вас, скорее всего, есть несколько полезных дополнительных команд, поэтому ваш первый пример может быть
MGET user: id: имя пользователя: id: email ... (multiget - получить любое количество ключей за один вызов)
GET user: id: * (ключевые символы подстановки)
HGETALL пользователь: id (redis hash - получает все подразделы пользователя)
Вы также можете хранить свой пользовательский объект в сериализованной форме - в отличие от реляционной базы данных, это не нарушит все ваши запросы.
Работа со списками не очень хороша, если в вашей платформе нет встроенной поддержки - собственная поддержка списков / наборов - одна из причин, по которой мне нравится использовать redis - но помимо потенциально необходимых блокировок это не хуже, чем получение списка из sql.
Стоит также отметить, что вам могут не понадобиться все отношения, которые вы бы определили в sql - например, если у вас есть группа, содержащая миллион пользователей, возможность получить список всех пользователей в группе совершенно бесполезна, поэтому Вы никогда не создадите список groupsuser вообще, и вместо того, чтобы отдельный список групп пользователей имел user: id: groups как многозначное свойство. Если вам просто нужно проверить членство, вы можете установить ключи как группы пользователей: userid: groupid и получить постоянный поиск по времени.
Я считаю, что это помогает думать с точки зрения индексов, а не отношений - при настройке кода доступа к данным решите, какие поля нужно будет запрашивать, и добавьте соответствующие записи индекса, когда эти поля будут записаны.