Практика
Большинство .NET разработчиков очень редко задаются вопросом где и как хранить данные приложения. Прекрасная интеграция SQL Server с .NET делает его универсальным и удобным хранилищем, которое мы, не задумываясь, используем в любых задачах.
Современные СУБД – это замечательный пример слияния прекрасных инженерных решений и десятков лет опыта в создании надежных, оптимизированных хранилищ данных. Однако все больше программистов выбирают NoSQL хранилища данных, что последнее время считается модным и прогрессивным.
Недавно я решил изучить возможности NoSQL и удобство работы с ними в .NET, и в этой статье поделюсь с вами своим опытом и впечатлениями.
Если немного вернуться в прошлое, 2009 год я бы назвал годом ORM систем. Такие движки как Linq to SQL, Entity Framework, NHibernate стали обязательными инструментами в боекомплекте любого .NET разработчика.
В году нынешнем все чаще можно услышать восторженные отзывы о MongoDb, CouchDB, Cassandra и других хранилищах, а «select fun, profit from real_world where relational=false;» - новый лозунг веб-программистов на динамических языках. NoSQL-хранилища, или document-oriented storages, плотно закрепились на рынке и завоевывают все большую популярность.
К тому же, пример подают такие гиганты как Amazon (Dynamo), Google (BigTable), Twitter (Cassandra) и многие другие.
Многие проекты имеют высокую динамичность данных. Сущности системы часто меняют структуру, похожие сущности могут немного отличаться набором данных, а некоторые из уже существующих могут со временем «обрастать» новыми свойствами. Из-за строгой структуры данных в базе любые изменения схемы сущностей нужно отражать в структуре таблиц, постоянно усложняя модель (например, в случае наследования) и готовя migration-скрипты. При этих изменениях необходимо менять SQL-запросы или маппинг объектов, к тому же скорость доступа к данным может существенно пострадать (вспомним запросы, генерируемые Entity Framework при Table-per-Type наследовании). В итоге – нам необходимо поддерживать две разнородные модели – реляционную в базе и объектную в коде, и зачастую страдать от потерь производительности.
Также, многие проекты не требуют строгой поддержки ACID-принципов. Намного важнее представляется быстрая обработка данных с минимальным временем отклика, а также быстрая и простая горизонтальная масштабируемость. Кроме того, иногда объем обрабатываемых данных настолько велик, что единственным возможным путем работы является параллельное ее решение на кластере.
Попробую перечислить наиболее характерные, на мой взгляд, особенности:
Schema-less данные. Вместо строго структурированных таблиц мы и имеем коллекции документов, а в некоторых системах и просто наборы ключ-значение. Структура каждого документа может быть индивидуальной, фактически он сам себя описывает. Поддержка документов разной структуры ложится на плечи логики приложения.
Data Sharding. Очень простая горизонтальная масштабируемость. Добавьте сервер в кластер и получите более производительное хранилище. Большинство NoSQL-систем мультиплатформенны, что позволяет собрать распределенное хранилище из практически любого набора серверов. Некоторые хранилища ограничены одним сервером для чтения и записи, остальные серверы read-only (MongoDB), другие (CouchDB) позволяют чтение и запись на всех шардах.
Быстрый поиск по индексу. Это первоочередная задача любой NoSQL системы. Использование B-trees позволяет очень быстрый поиск при низкой стоимости модификации данных.
MapReduce. Механизм параллельной обработки больших объемов данных на кластерах. На шаге Map один из компьютеров (master node) делит задачу на части, распределяя их между остальными компьютерами (worker nodes). На шаге Reduce master node получает предварительные результаты, и формирует из них конечный результат. Это существенно повышает эффективность распределенной обработки данных. Например, реализация MapReduce компанией Google позволяет отсортировать петабайт данных за несколько часов.
Для тестов я остановился на MongoDB. Это одна из самых популярных документно-ориентированных систем работающих на Windows, с массой хороших отзывов и радужными перспективами развития.
Итак, качаем MongoDB для Windows, ставить ничего нужно, все из консоли (снова здравствуй, мир мультиплатформенности).
Создаем папку C:\data\db (можно переконфигурировать).
Запускаем из консоли mongod.exe, это сервер. По пути http://localhost:28017 можно насладиться аскетичным activity-монитором.
Запустим mongo.exe и попробуем сделать пару запросов. Тут царство демократии. Создавать ничего не нужно, база и коллекции появятся, когда вы в них что-то запишете.
Например:
Только что мы создали два документа в коллекции Movie. Структура аналогична JSON, и называется BSON (Binary JSON). Обратите внимание, заодно создалась и база в C:\data\db
Попробуем выбрать данные:
Как видите, идентификаторы документы получили автоматически.
Теперь выберем конкретную запись:
Поддержка С# и .NET осуществляется сообществом. Наиболее функциональный драйвер - mongodb-csharp. Он еще далек от аналогов для других языков, однако это лучшее, что у нас есть.
С его помощью подключение к базе выглядит следующим образом:
Добавление нового документа:
Поиск документов:
Итак, спартанский функционал у нас уже есть. Стоит также отметить, что среди текущего функционала присутствует «Basic Linq Support», что, в общем, не спасает этот драйвер как продукт, учитывая что официальная вики состоит из трех предложений и шести строчек кода.
Также стоит обратить внимание на проект NoRM. Проект еще очень молод, первый коммит был сделан 30 января 2010. Однако уже сейчас он предлагает более удобный доступ к данным.
Обьявим класс Movie:
ObjectId – класс, представляющий уникальный идентификатор MongoDB из библиотеки Norm.
После чего добавить данные можно следующим образом:
Выбрать данные можно с помощью Linq:
В данном случае взаимодействие с хранилищем приобретает удобоваримый вид, близкий .NET разработчикам.
Программная модель вносит некоторые ограничение на формат данных в базе. Название коллекции должно совпадать с именем класса, а сам класс должен содержать все существующие свойства документов коллекции. Если документ содержит лишь часть свойств, остальные просто не будут заполнены.
Избавиться от этих ограничений можно с помощью Flyweight объектов:
NoSQL хранилища становятся все более популярными благодаря гибкости хранения данных и масштабируемости. Основная их ниша – это проекты на динамических языках программирования, а также проекты с очень большими объемами данных. В статических языках программирования использования NoSQL не так удобно, а С#, возможно, наименее подходящий из современных языков ввиду скудности API драйверов. Однако, с появлением DLR и динамических возможностей C# 4.0 ситуация может существенно измениться в лучшую сторону. К тому же, последнее время начали появляться интересные проекты, делающие взаимодействие все более удобным.
С другой стороны, стоит дождаться, когда Windows Azure станет не будущим, а настоящим. Эта платформа предоставляет различные способы хранения данных, как SQL так и не SQL. Интересно проверить на практике, смогут ли NoSQL хранилища выдержать конкуренцию на платформе .NET?
Комментарии
Оставить комментарий
Базы данных - MySql (Maria DB)
Термины: Базы данных - MySql (Maria DB)