MongoDB в действии

Автор: Eugeniy Marilev
Теги: PHP Linux Databases
Дата публикации: 2014-09-03 19:54:54

В этой статье речь пойдёт о MongoDb. Почти все о ней слышали, но не все представляют себе, что это. Некоторые знают по слухам, что это что-то интересное и в чём-то более полезное, чем mysql, некоторые не могут сказать даже этого, а некоторые уже использовали его в своих проектах, но не совсем понимали зачем, а потому что так сказали. Данная статья должна несколько прояснить опущенные моменты либо устранить пробелы в знаниях, так как mongoDb для программиста— это своего рода как разводной ключ для механника: можно его и не иметь, а обходится пассатижами или другими средствами, так сказать «слизывая шляпу» у винта, но лучше иметь и делать всё быстро и без подливы в будущем.

Общие принципы mongoDB

MongoDB – это документ-ориетированная NoSQL база данных, что в переводе: для хранения данных используются документы, а для работы с ними не используется SQL. Внутри mongoDB может быть ноль или несколько баз данных. Каждая база данных состоит из коллекций, коллекция — это аналог таблицы в реляционных БД. Каждая коллекция состоит из ноль и более документов, документ — это аналог строки в реляционных БД. Каждый документ состоит из полей, поле — это аналог колонки в реляционных БД. Индексы в mongoDB и реляционных БД идетничны.

Преимущества и недостатки по сравнению с SQL БД

Главное преимущество mongo – бесструктурность, как следствие — нет необходимости создавать заранее БД, колллекции, индексы и т.п. минимально расхождение с ООП (коллекции идентичны классам, а документы, в свою очередь, идентичны аттрибутам класса, что позволяет очень легко проецировать коллекции в классы), а соответственно — гибкость, что позволяет создавать нам вложенные друг в друга документы, и на выходе мы получаем 1 документ, который состоит из 5 вложенных, а 5 вложенных, в свою очередь, состоят из 3 вложенных и т. д. Это довольно трудоёмко реализовать join-ами в SQLDB, но и тут мы получаем первый маленьнький недостаток mongo — это отстуствие любых join, а потому — если вам придётся масштабировать данные горизонтально (например поддягивать значения из справочников по id), то придётся реализовывать join-ы ручками на клиенте. Альтернативой является запись всех связанных данных в массив приведенный ниже, что само по себе очень удобно, и это уже приемущество. Ещё один вариант — это денормализация.

categories: [
                   ObjectId(«4e209564203d83940f003»),
                   ObjectId(«4e209564203d83940f004»),
                   ObjectId(«4e209564203d83940f005»),
                   ObjectId(«4e209564203d83940f006»),
 ]

Ещё одно преимущество mongo — это поддержка автошардинга. Шардинг — это вид масштабирования, когда данные хранятся на разных серверах. Пример — на сервере А хранить всех мальчиков, на сервере B хранить всех девочек, на сервере C — всех остальных. Далее — это поддержка геопространственных индексов, что позволяет сохранять координаты X и Y документа, а потом найди близлежащие документы, либо документы в круге или прямоугольнике. Последним ощутимым плюсом является запись без подтверждения, что позволяет значительно ускорить работоспособность, но это и минус, так как возрастает вероятность потери данных. Ещё один недостаток — это отсутсвие транзакций, подробнее говорить об этом думаю не стоит, всё и так ясно. Есть ещё ряд мелких недостатков: это отсутвие такого набора инструментов, как в реляционных бд, так как nosql сам по себе намного моложе; отсутствие полнотекстового поиска; невозможность обеспечить устойчивость хранения данных на одном сервере, но это решается репликацией или журналированием.

Примеры, когда лучше использовать mongoDB

Я приведу 2 примера:

  1. При логировании. Вмеру того, что mongo ведёт запись без подтверждения, скорость записи логов будет значительно выше, чем в реляционных БД + мы не привязаны к структуре, а логах произвольная структура данных — это именно то, что нужно. Так же приемуществом для данной задачи будет то, что коллекция пишет документы в порядке их поступления, то есть последним документом в коллекции всегда будет последний поступивший лог. Но и это ещё не всё, в mongo есть такая возможность, как установка размера коллекции:
    db.createCollection('logs', {capped: true, size: 1048576})
    
    После этого, когда файл достигнет размера 1 мб, старые данные начнут перезатираться, что помоему очень и очень удобно.
  2. При создании сущностей, которые включают в себя другие сущности. Пример: у нас есть вопросы, которые содержат текст, картинку или ссылку и варианты ответа: Вопрос1:
    {
    	_id: objectId («4e209564203d83940f005»),
    	type:   «composite»,
    	right: 1,
    	items: [
                       {
    	             type:   «image»,
    	             url: «http://google.com/image.jpg»,
    		 alt:   «gg»,
    		 title:   «gl&hf»,
                       },
                       {
    	             type:   «text»,
    	             text: «Сколько зайчиков на картинке?»
                        },
                ]
    }
    
    Вопрос2:
    {
    	_id: objectId («4e209564203d83940f006»),
    	type:   «composite»,
    	right: 3,
    	items: [
                       {
    	             type:   «link»,
    	             url: «http://ru.wikipedia.org/wiki/Антанта»,
                       },
                       {
    	             type:   «text»,
    	             text: «Сколько стран было в Антанте?»
                        },
                ]
    }
    
    Как видим у нас нет чёткой структуры вопросов, поэтому мы можем произвольно задавать необходимые нам данные. Далее нам нужно составить тест, который будет состоять из вопросов, приведеных выше. Делается это очень просто:
    Type «quiz»:
    {
    	_id: objectId («4e209564203d83940f007»),
     	title: «Общеобразовательный тест»,
    	type:   «quiz»,
    	items: [
                       ObjectId(«4e209564203d83940f005»),
                       ObjectId(«4e209564203d83940f006»),
                ]
    }
    

Эти 2 примера отображают основные плюсы mongoDB — гибкость хранения данных, вертикальное масштабирование (одна сущность включает в себя несколько подсущностей) и другие приятные мелочи.

Лучшее решение — это использовать комбинацию SQL и MongoDB

Так что лучше, mysql или mongoDB? Лучше и то и другое, но только там, где это действительно нужно. Например в примере с логами, mysql не нужен совершенно, но во втором примере тесты будут кому-то отсылаться, будут появляться какие-то результаты, а значит появяться пользователи. Если появяться пользователи — возможно появятся группы. Так вот, можно использовать денормализацию и хранить данные mongo, а лучше — завести для структурированных данных таблицы в mysql, а связь документов mongo с sql БД выполнять по ключевым полям таблиц mysql (например, (mongo) somecollection .userId → (sql) user.id, (mongo) somecollection.groupId → (sql) group.id).

Вот и всё, теперь у Вас есть представление о nosql. Как Вы понимаете, это не необходимость, а просто иной подход, который более уместен в некоторых ситуациях. Ленивый не станет его изучать, а умный — изучит и применит на практике, чем повысит свою стоимость на рынке труда.

Комментарии к статье
Комментарии:
Нет результатов.
Только зарегистрированые пользователи могут оставлять комментарии