MongoDb и PHP
by Вредный • 20.08.2011 • nosql, php, программирование • 1 Комментарий
NoSQL — что за странная аббревиатура?
Наверное, какждый из вас уже слышал эту аббревиатуру, может даже вы «щупали» ее на зубок, а может и используете ее в своих проектах на продакшн серверах. Данная технология в момент ее появления наделала много шуму, легко втиснувшись и отобрав кусок хлеба у реляционных баз данных. NoSQL термин означает что это не только (not only) SQL, хотя на первый взгляд кажется, что это не SQL (no). Термин означает множество технологий работы с базами данных в обход стандартной реляционной модели. Данные могут храниться в виде пар ключ-значение, деревьев или документов. Мы с вами рассмотрим последнее.
Описание документо-ориентированных хранилищ
В данной системе управления базами данных единицей хранения информации является некий документ, хранящийся в виде пар ключ-значние и имеющих некие связи.
Что же такое MongoDB?
До рассмотрения возможностей данного замечательного продукта хотелось бы отметить 6 основных концепций, заключенных в нем:
- Концепция базы данных не отличима от понятий базы данных в реляционных СУБД. MongoDB также может содержать ноль или более баз данных, которые являются контейнером верхнего уровня.
- База данных может содрежать ноль или более коллекций. Коллекциями в контексте СУРБД (здесь и далее система управления реляционными базами данных) являются таблицы.
- Коллекция может содрежать в себе документы. В СУРБД это строки.
- Документ может состоять из разного количества полей. Если проводить аналогию с реляционной моделью, то это конечно же столбец.
- Индексы есть и в MongoDB, и в СУРБД, функции их почти неотлимы.
- Курсоры есть в MongoDB, но прямого аналога в реляционной модели нет. Важно понять, что, когда вы запрашиваете MongoDB вернуть вам определенные данные, Mongo возвращает курсор, с помощью которого мы можем подсчитать или пропустить некоторые документы, без нагрузки на сервер.
- Заходим на официальную страницу загрузки, скачиваем подходящую скомпилированную версию.
- Распаковываем архив куда угодно и заходим в папку bin. mongod — сервер, mongo — клиентская оболочка — с этими двумя исходниками мы и будем проводить большую часть времени.
- Создаем текстовый файл в папке bin, пусть называться он будет mongod.conf
- Записываем одну строку во вновь созданный файл dbpath=ПУТЬ-ГДЕ-ВЫ-ХОТИТЕ-ЧТОБЫ-ЛЕЖАЛА-БАЗА-ДАННЫХ. К примеру, на Windows вы можете написать dbpath=c:\mongodb\data, под Линуксом dbpath=/etc/mongodb/data. Указанный путь должен сущестовать (позаботьтесь об этом).
- Запустите из папки bin файл mongod с параметром **—config /путь/к/конфигу/mongodb.conf.
Установка MongoDB
Подробная информация об установке широко представлена на официальном сайте, поэтому не будем заострять внимание на этом разделе. Я затрону лишь основные моменты, чтобы начать работу.
Пройдемся по шагам, чтобы ее завершить:
Установка завершена. Чтобы это проверить запустите в командной строке клиент (mongo), которые должен автоматически соединиться с запущенным сервером и отобразить приглашение. Попробуйте ввести **help** или db.version(). Пока оставим наш клиент и перейдем к PHP.
PHP и MongoDB
MongoDB на данный момент имеет поддержку почти всех популярных языков программирования, таких как C++, Erlang, Java, Javascript, Perl, Python и PHP. На последнем мы и остановимся.
Описание расширения
Я не буду приводить пример установки раширений для PHP. В нем нет ничего нетривиального. Лучше заострю внимание на чем-нибуь более интересным, чтобы вы после прочтения данной заметки легко написать свое первое приложение с использованием MongoDB. Полное описание расширения вы можете на странице официального руководства (http://www.php.net/manual/en/book.mongo.php).
Соединение
Начнем с соединения (сервер на данный момент должен быть запущен). Если мы экспериментируем на своей локальной машине, то все просто.
1 2 3 | <?php $mongo = new Mongo(); // соединяемся с сервером $db = $mongo->database; // выбираем базу данных |
Если же вы используете MongoDB на выделенном хостинге или по каким-то другим причинам вам требуется авторизация, то данный пример немного усложнится.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <?php $options = array( 'db' => array( 'host' => 'mongodb.example.com', 'port' => '27017', 'username' => 'mongodb-user', 'password' => 'SECRET-PASSWORD', 'dbname' => 'DATABASE-NAME' ) ); $collectionName = 'COLLECTION-NAME'; $mongo = new Mongo( "mongodb://{$options['db']['username']}:{$options['db']['password']}@{$options['db']['host']}:{$options['db']['port']}/{$options['db']['dbname']}" ); $collection = $mongo->$options['db']['dbname']->$collectionName; |
Данные пляски очень похожи на DSN, которые повсеместно используется с PDO.
Запись
Соединяться с сервером мы уже научились, также как и выбирать коллекцию. Кстати, если нет коллекции, ничего страшного, если вы будете вносить данные в несуществующую коллекцию, то заботливый Mongo ее для вас создаст. Еще раз убеждаюь, что MongoDB создана для лентяев, которые хотят сосредоточиться только на важных вещах, а на не плясках с бубном.
1 2 3 4 5 6 7 | $collection->insert( array( 'title' => 'Simple Title', 'alias' => 'about', 'content' => 'Lorem Ipsum', 'images' => array('image1.jpg', 'image2.jpg')), // вставляем какие угодно данные, хоть массивы array("safe" => 1)); // данный параметро сообщает MongoDB проследить за успешностью вставки, обычно этот параметр отключен |
Выборка
1 2 | $content = $collection->findOne(array('alias' => 'about')); // находим одну запись, удоволетворяющая условию {alias: 'about'} var_dump($content); |
Выборка происходит почти также как в реляционных базах данных после слова WHERE (select * from COLLECTION-NAME WHERE alias = ‘about’ LIMIT 1)
Разработчики предусмотрели множество плюшек при выборке, но всех их рассмотреть в данной вводной заметке не представляется возможным, поэтому расскажу еще о выборке с участием регулярных выражений и отклоняюсь.
1 2 3 4 5 6 | $cursor = $collection->find(array('word' => new MongoRegex("/{$mask}/ig")))->limit(50); $words = array(); foreach ($cursor as $o) $words[] = $o; |
Данный пример почти из реального проекта, который показывает и выборку по регулярному выражению и работу с курсорами. Надеюсь, данный код не вызвал у вас затруднений.
Изменение
Изменение данных в документах чуть более обширный раздел, заключающий в себе и выборку и запись новых данных. Но не все так сложно, как я малюю. Начну с примера.
1 | $collection->update(array('alias' => 'about'), array('$set' => array("title" => 'In MongoDB we trust'))); |
Данная запутанная с первого взляда запись на самом деле проста, если разбить ее на составляющие. Первый параметр в методе update() отвечая за выборку, т.е. критерии выборки, второй параметр, как будем менять. В данном случае мы установим ($set) заголовок в новый. Отличные от $set параметры вы можете найти в документации к MongoDB. Аналог в виде SQL мог бы выглядеть так
1 | UPDATE COLLECTION-NAME SET title = 'In MongoDB we trust' WHERE alias = 'about' |
Данного минимума, как я уже упоминал ранее, должно хватить для реализации несложного приложения. Все информацию помимо упомянутого мною в данной заметке, можно получить на официальном сайте MongoDB
Заключение
В первую очередь вам следует понять, что волшебной таблетки не существует. Любое решение, каким бы оно не казалось со стороны гибким и легким, имеет свои плюсы и минусы. Если вам не нужно хранить статистические данные, которые размазаны по десятками а то и сотням таблиц со сложными связями, вряд ли вам подойдет NoSQL решения. Если же данные легко подвергаются денормализации, то смело выбирайте NoSQL из-за скорости и удобности работы.
Вы забыли сказать, что данные базы не то, чтобы втиснулись, они реинкарнировались так как теория этих СУБД была продумана еще до появления реляционных БД (если я не ошибаюсь)