NoSQL и MongoDB


Метки: | | |
Просмотров: 9580

NoSQL и MongoDB

Сегодня под Linux выпускается множество разнообразных СУБД. Среди них Oracle, MySQL, Postgres и прочие. Всех их объединяет то, что они поддерживают использование SQL, который появился более двадцати лет назад и стал стандартом для получения или внесения данных в реляционные базы данных. Он достаточно прост в изучении и весьма универсален. SQL запросы успешно используются как в самых маленьких приложениях для мобильных устройств, так и в огромных веб-порталах.

Одним из краеугольных камней таких SQL СУБД является то, что при достаточно "весомом" количестве данных возникают проблемы с их размещением. В ответ на эту проблему в свет стали появляться NoSQL базы данных.

На сегодня их достаточно много, однако в этой статье мы рассмотрим всего лишь одну, популярную на сегодняшний день базу данных MongoDB. Приступая к работе практически с любой NoSQL базой будьте готовы к тому, что вам придется забыть все знания об SQL: запросы, ключи, таблицы и прочее. В NoSQL, и, в частности, в MongoDB всего этого попросту нет! Все данные хранятся не в таблицах, а в JSON-документах (синтаксис из JavaScript).

Самый лучший способ понять принцип работы - рассмотреть все на примере. Для начала нам нужно будет установить MongoDB. Последний релиз всегда можно скачать с сайта http://www.mongodb.org/downloads. Скачайте нужную вам версию (x32 или x64) и распакуйте содержимое при помощи команды:

tar zxvf <filename>

Cоздайте каталог базы данных:

mkdir -p/data/db

Дальше необходимо зайти в bin папку распакованного архива

cd ~/mongodb-linux-x86_64-2.4.5/bin

и запустить: сначала сервер базы данных ./mongod, а потом клиента ./mongo.

В MongoDB используется JavaScript, поэтому при необходимости там будут работать стандартные команды, например:

print('Hello, world');

Структура хранения данных в MongoDB представляет собой хранилище JSON-документов в виде одной или нескольких пар в формате "имя/значение". По простому, {name1:value1, name2:value2,...}.

Такой принцип хранения данных позволяет именам ссылаться на любые свойства. В этом и заключается основное различие NoSQL от традиционных баз данных - полностью отсутствует структура. А как же осуществляется валидация форматов? Ответ прост - все проверки осуществляются полностью на стороне приложения.

MongoDB

Но все же вернемся к примеру. Давайте добавим в нашу базу данных значение:

db.test.save({"hello":"world"});
db.test.find();

Разберем поподробнее. Сначала мы создали коллекцию test, добавили в нее одну пару (где "hello" - это имя, "world" - значение), а потом запросили все документы коллекции. Используя синтаксис JavaScript, добавим еще несколько значений:

for(i=0; i<10; i++) {db.test.save({'number' : i});}
db.test.find();

Если вы заметили, при получении данных извлекаются все записи, независимо от их формата. При помощи db.test.find() можно получить данные с заданными параметрами. Например,

db.test.find({number:2}) # вернет все значения с номером 2, а
db.test.find({number:{<:2}}) # все элементы с номером меньше 2.

Основным нюансом NoSQL СУБД является масштабируемость. То есть одну БД можно без проблем разместить на нескольких компьютерах. Да, такое можно сделать и со стандартными SQL БД, но это будет достаточно сложно. NoSQL БД создавались специально для использования как масштабируемая архитектура, что отлично выражается в функциях агрегирования.

Сжатие массива

Для того, чтобы вычислить сумму введенных чисел используется функция mapReduce(). Ее название содержит два слова: "map" (карта, массив) и "reduce" (сжатие) и то же время две функции.

Map вызывается для каждой записи и возвращает значения, которые поступают в reduce. Таким образом, она в любом случае обязательно возвращает ключ и значение, причем ключ - это категория, в которой будут "сжаты" значения. В качестве значения может возвращаться или одна переменная, или целый JSON документ. После получения всех значения reduce "сжимает" их. Чтобы вычислить среднее из всех четных и нечетных, map должна вернуть только число:

var mapFunction = function() {
	var out = "odd";
	if (this.number % 2==0) {
		out="even";
	}
	 
	emit(out, this.number);
}

В результате выполнения вернется либо "odd", либо "even". Рассмотри функцию reduce:

var reduceFunction = function(ids, number) {
	return Array.avg(number);
}

В итоге, рассчитается среднее значение для каждого ключа. Вызов функции mapReduce происходит так:

db.test.mapReduce(
	mapFunction,
	reduceFunction,
	{out:"mr_out"}
)

Конечно же, название функций mapFunction и reduceFunction могут быть произвольными. Приведенная команда "сожмет массив" и выдаст результат в новую mr_out коллекцию:

db.mr_out.find();

В результате можно выделить несколько моментов:

- во-первых, mapReduce больше подходит для сложного агрегирования;

- во-вторых, использование функции map позволяет значительно увеличить производительность. Это особенно будет заметно в распределенных базах данных.

На деле, mapReduce отлично распараллеливает агрегацию на очень больших объемах данных. По большому счету, все это не значит, что стандартные реляционные базы данных устарели. Но, стоит обратить свое внимание на NoSQL, если у вас довольно часто возникают проблемы с кластерами SQL или с производительностью запросов.

Оставьте комментарий!

Комментарий будет опубликован после проверки

Имя и сайт используются только при регистрации

(обязательно)