NoSql Ссылочные данные - PullRequest
       31

NoSql Ссылочные данные

13 голосов
/ 29 сентября 2011

Отказ от ответственности: под ссылочными данными я не подразумеваю ссылочную целостность

Я изучаю nosql и хотел бы понять, как должны моделироваться данные.Например, в типичной реляционной базе данных для приложения CMS может быть две таблицы: article и author, где article имеет ссылку на автора.

В системе nosql вы можете создать документ статьи таким образом, поскольку они являются просто замаскированным графом объектов

{
title: "Learn nosql in 5 minutes",
slug: "nosql_is_easy", 
author: {firstName: "Smarty"
          lastName: "Pants"
}

{
title: "Death to RDBMS",
slug: "rdbms_sucks", 
author: {firstName: "Smarty"
          lastName: "Pants"
}

и так далее ...

Скажем, однажды мистер Смарти Пантс решил сменить имя на Обычного Джо, потому что nosql стал вездесущим.В таком случае необходимо будет отсканировать каждую статью и обновить имя автора.

Итак, мои вопросы: как моделировать данные в nosql, чтобы они соответствовали базовым сценариям использования CMS, чтобы производительность на одном уровне или выше, чем в РСУБД ? mongodb , например, утверждает, что CMS используется в качестве варианта использования ...

Редактировать :

Мало кто уже предложил нормализовать данные, например:

article 
{
title: "Death to RDBMS",
slug: "rdbms_sucks", 
author: {id: "10000001"}
}

author
{
name: "Big Brother",
id: "10000001"
}

Однако, поскольку nosql по своей природе не имеет соединений, вам придется использовать функции, подобные mapreduce, для объединения данных.Если это ваше предложение, пожалуйста, прокомментируйте выполнение такой операции.

Edit 2:

Если вы считаете, что nosql не подходит для любых типов данных, которыеТребуются справочные данные, пожалуйста, объясните, почему.Казалось бы, это делает вариант использования nosql довольно ограниченным, поскольку любое разумное приложение будет содержать реляционные данные.

Редактировать 3:

Nosql не означаетнереляционная

Ответы [ 6 ]

4 голосов
/ 29 сентября 2011

Ваши данные явно реляционные: у статьи есть автор.Вы можете моделировать свои данные в хранилище NOSQL, таком как MongoDB, точно так же, как в реляционном хранилище, НО, поскольку в базе данных нет соединений, вам нужно сделать два вызова базы данных, чтобы вы ничего не получили.

НО ... что вы МОЖЕТЕ сделать с хранилищем NOSQL - это несколько денормализовать данные, чтобы повысить производительность (один прием в оба конца, чтобы получить все необходимое для отображения статьи), НО за счет немедленной согласованности:замена всегда точных имен авторов на в конечном итоге точные имена авторов.

Вы можете, например, использовать это в своей статье:

author: {firstName: "Smarty", lastName: "Pants", _id:DE342624EF }

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

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

4 голосов
/ 29 сентября 2011

Полагаю, CouchDB - это база данных NoSQL, если вы так говорите.

Но на самом деле у нас есть универсальные языки программирования и специфичные для домена языки,Точно так же CouchDB является доменной базой данных .

Я часто использую CouchDB, но мне действительно все равно, использует ли она SQL или NoSQL.CouchDB является ценным (для меня), потому что API на 100% HTTP, JSON и Javascript.Вы можете создавать веб-приложения с помощью браузера, извлекающего HTML из CouchDB и запрашивающего данные через AJAX.Сказать, что это «не SQL» - это преуменьшение!

В любом случае, вернемся к Smarty Pants и Regular Joe.Может быть, у него есть 100 000 документов.Что если мы просто обновим их все, трудный путь?Ну, это довольно небольшое количество Javascript.

$.getJSON('/db/_design/cms/_view/by_user?key=Smarty+Pants', {
  success: function(result) {
    // Change the name right here, in the result objects.
    var docs = result.rows.map(function(row) {
      row.value.firstName = "Regular";
      row.value.lastName = "Joe";
      return row.value;
    })

    // Store it!
    $.post('/db/_bulk_docs', {"docs":docs}, function() {
      console.log("Done! Renamed Smarty Pants in " + docs.length + " documents!");
    })
  }
})

Да, эта техника даст вам F в классе информатики.Однако мне это нравится.Я бы написал этот код в Firebug.В моем браузере .Переименование не является атомарным и не имеет ссылочной целостности.С другой стороны, это, вероятно, завершится через пару секунд, и никто не будет беспокоиться.

Вы могли бы сказать, что CouchDB терпит неудачу в модных словах и тестах, но завершает школу жестких ударов.

PSby_user вид построен из карты-уменьшить.В CouchDB map-Reduce составляет incremental , что означает, что он работает как большинство индексов SQL.Все запросы завершаются в короткие, предсказуемые (логарифмические) сроки.

1 голос
/ 29 сентября 2011

для вашего конкретного случая используйте шаблон Flyweight , сохраняйте идентификатор объекта вместо объекта объекта.

article 
{
title: "Death to RDBMS",
slug: "rdbms_sucks", 
author: {id: "10000001"}
}

author
{
name: "Big Brother",
id: "10000001"
}

для общего предложения по разработке схемы mongodb прочитайте официальные документы

0 голосов
/ 06 сентября 2012

Вы можете просто смоделировать свои данные с помощью playOrm AND и выполнять объединения в хранилище noSQL.playOrm имеет S-SQL (Scalable SQL), который является поворотом в SQL, поскольку вы указываете, какие разделы вы запрашиваете.Таким образом, вы можете перейти с СУБД на noSQL, и при этом у вас останутся те же знакомые инструменты, которые вы использовали.

0 голосов
/ 24 января 2012

Этот пост был здесь в течение некоторого времени, но я подумал, что укажу другой метод для обработки "объединений" и перекрестных ссылок на документы с помощью CouchDB.Этот метод я использую в CMS, которую я (пере) пишу, чтобы использовать CouchDB (ранее он был написан для MySQL).

CMS называется BlueInk и его можно найти на Github по адресу http://github.com/BigBlueHat/BlueInk В настоящее время переписывание сосредоточено на дизайне документа и части «движка рендеринга», поэтому не нужно говорить о пользовательском интерфейсе - вам нужно создать весь JSON вручную.Это то, что я надеюсь исправить в ближайшее время, но в репо уже достаточно (после установки в CouchDB), чтобы дать вам представление о том, как выполняются «объединения».

В BlueInk страница ссылается на элементы контента, которые могут сами по себебыть включенным в одну или несколько страниц (или одну и ту же страницу несколько раз).Страница ссылается на элементы страницы через их идентификатор (как в вашем втором примере JSON).При запуске через представление "page_and_items" он генерирует выходные данные, которые можно использовать с параметром запроса CouchDB ?include_docs=true для извлечения полного содержимого ссылок на элементы содержимого в документе страницы.

Выходные данные представления затем передаются через функцию _list, форматируются с помощью шаблона усов и выводятся в виде HTML-страницы - все в одном запросе GET.

Этот же шаблон использования ссылочных идентификаторов с ?include_docs=true может использоваться в вашем случае использования выше.Использование функции _list является полностью «косметическим», но может быть полезно для реструктуризации выходного представления JSON или его шаблонирования и вывода HTML, CSV, XML и т. Д.

0 голосов
/ 29 сентября 2011

Позвольте мне заявить, что я ни в коем случае не эксперт по NoSQL.Вместо этого, мои знания в основном теоретические.

Тем не менее, я твердо убежден в том, что реализация системы типа CMS, подобной этой, в NoSQL, вероятно, не лучший способ решения проблем, поскольку данныев основном реляционный.

Мое решение этой проблемы основано на предположении, что используемая вами система NoSQL позволяет загружать записи с помощью структуры типа «первичный ключ».Я думаю, что большинство так и делают, но я уверен, что есть такие, которые этого не делают.

Тем не менее, я бы предложил хранить данные следующим образом.

Для автора:

{
_KEY: $AUTHOR_GUID,
firstName: "Smarty",
lastName: "Pants",
}

А для самого сообщения:

{
title: "Learn nosql in 5 minutes",
slug: "nosql_is_easy", 
author: $AUTHOR_GUID,
}

Обратите внимание, что в приведенном выше примере я использую _KEY, чтобы показать, что это значение типа "первичный ключ".

После загрузки сообщения вы можете загрузить автора по его GUID.

...