Вам бонус- начислено 1 монета за дневную активность. Сейчас у вас 1 монета

NoSQL хранилища данных и их использование в .NET

Практика



Большинство .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-принципов. Намного важнее представляется быстрая обработка данных с минимальным временем отклика, а также быстрая и простая горизонтальная масштабируемость. Кроме того, иногда объем обрабатываемых данных настолько велик, что единственным возможным путем работы является параллельное ее решение на кластере.

Концепция NoSQL-хранилищ

Попробую перечислить наиболее характерные, на мой взгляд, особенности:

Schema-less данные. Вместо строго структурированных таблиц мы и имеем коллекции документов, а в некоторых системах и просто наборы ключ-значение. Структура каждого документа может быть индивидуальной, фактически он сам себя описывает. Поддержка документов разной структуры ложится на плечи логики приложения.

Data Sharding. Очень простая горизонтальная масштабируемость. Добавьте сервер в кластер и получите более производительное хранилище. Большинство NoSQL-систем мультиплатформенны, что позволяет собрать распределенное хранилище из практически любого набора серверов. Некоторые хранилища ограничены одним сервером для чтения и записи, остальные серверы read-only (MongoDB), другие (CouchDB) позволяют чтение и запись на всех шардах.

Быстрый поиск по индексу. Это первоочередная задача любой NoSQL системы. Использование B-trees позволяет очень быстрый поиск при низкой стоимости модификации данных.

MapReduce. Механизм параллельной обработки больших объемов данных на кластерах. На шаге Map один из компьютеров (master node) делит задачу на части, распределяя их между остальными компьютерами (worker nodes). На шаге Reduce master node получает предварительные результаты, и формирует из них конечный результат. Это существенно повышает эффективность распределенной обработки данных. Например, реализация MapReduce компанией Google позволяет отсортировать петабайт данных за несколько часов.

MongoDB

Для тестов я остановился на MongoDB. Это одна из самых популярных документно-ориентированных систем работающих на Windows, с массой хороших отзывов и радужными перспективами развития.

Итак, качаем MongoDB для Windows, ставить ничего нужно, все из консоли (снова здравствуй, мир мультиплатформенности).

Создаем папку C:\data\db (можно переконфигурировать).

Запускаем из консоли mongod.exe, это сервер. По пути http://localhost:28017 можно насладиться аскетичным activity-монитором.

Запустим mongo.exe и попробуем сделать пару запросов. Тут царство демократии. Создавать ничего не нужно, база и коллекции появятся, когда вы в них что-то запишете.

Например: 

use testdb
db.Movie.save({ Name: "Fight Club" Year: 1999 })
db.Movie.save({ Name: "Avatar", Year: 2010, Director: "James Cameron" })

Только что мы создали два документа в коллекции Movie. Структура аналогична JSON, и называется BSON (Binary JSON). Обратите внимание, заодно создалась и база в C:\data\db

Попробуем выбрать данные:

db.Movie.find()
{ "_id" : ObjectId("4bc37626a20c0000000072fd"), "Name" : "Fight Club", "Year" : 1999 }
{ "_id" : ObjectId("4bc37633a20c0000000072fe"), "Name" : "Avatar", "Year" : 2010, "Director" : "James Cameron" }

Как видите, идентификаторы документы получили автоматически.

Теперь выберем конкретную запись:


db.Movie.find({Name:"Avatar"})
{ "_id" : ObjectId("4bc37633a20c0000000072fe"), "Name" : "Avatar", "Year" : 2010, "Director" : "James Cameron" }

 

Использвонание MongoDB в .NET

Поддержка С# и .NET осуществляется сообществом. Наиболее функциональный драйвер - mongodb-csharp. Он еще далек от аналогов для других языков, однако это лучшее, что у нас есть.

С его помощью подключение к базе выглядит следующим образом:

var mongo = new Mongo();
mongo.Connect();
var db = mongo.getDB("testdb");

Добавление нового документа:


var movies = db.GetCollection("Movie");
var movie = new Document();
movie["title"] = "Star Wars";

movies.Insert(movie);

Поиск документов:


var criteria = new Document();
criteria ["title"] = "Star Wars";
var result = movies.FindOne(criteria);

Итак, спартанский функционал у нас уже есть. Стоит также отметить, что среди текущего функционала присутствует «Basic Linq Support», что, в общем, не спасает этот драйвер как продукт, учитывая что официальная вики состоит из трех предложений и шести строчек кода.

Также стоит обратить внимание на проект NoRM. Проект еще очень молод, первый коммит был сделан 30 января 2010. Однако уже сейчас он предлагает более удобный доступ к данным.

Обьявим класс Movie:


public class Movie

   public Movie() 
   { 
      this.Id = ObjectId.NewObjectId(); 
   } 
   public ObjectId Id { get; set; } 
   public string Name { get; set; } 
   public int Year { get; set; } 
   public string Director { get; set; }
}

ObjectId – класс, представляющий уникальный идентификатор MongoDB из библиотеки Norm.

После чего добавить данные можно следующим образом:

var provider = new MongoQueryProvider(dbName);
provider. DB.GetCollection().Insert(new Movie {Name = "Star Wars", Director = "George Lucas"});

Выбрать данные можно с помощью Linq:


var movie = new MongoQueryProvider(provider).Where(m => m.Name == "Star Wars").FirstOrDefault();

В данном случае взаимодействие с хранилищем приобретает удобоваримый вид, близкий .NET разработчикам.

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

Избавиться от этих ограничений можно с помощью Flyweight объектов:

var flys = provider. DB.GetCollection("collectionOfUnknowns");
foreach(var fly in flys)
{
    //проверим наличие значения 
   var value = fly["apropertyname"] ?? "свойство не задано"; 
   Console.Writeline(value);
}

Выводы

NoSQL хранилища становятся все более популярными благодаря гибкости хранения данных и масштабируемости. Основная их ниша – это проекты на динамических языках программирования, а также проекты с очень большими объемами данных. В статических языках программирования использования NoSQL не так удобно, а С#, возможно, наименее подходящий из современных языков ввиду скудности API драйверов. Однако, с появлением DLR и динамических возможностей C# 4.0 ситуация может существенно измениться в лучшую сторону. К тому же, последнее время начали появляться интересные проекты, делающие взаимодействие все более удобным.

С другой стороны, стоит дождаться, когда Windows Azure станет не будущим, а настоящим. Эта платформа предоставляет различные способы хранения данных, как SQL так и не SQL. Интересно проверить на практике, смогут ли NoSQL хранилища выдержать конкуренцию на платформе .NET?

создано: 2020-05-25
обновлено: 2021-03-13
132345



Рейтиг 9 of 10. count vote: 2
Вы довольны ?:


Поделиться:

Найди готовое или заработай

С нашими удобными сервисами без комиссии*

Как это работает? | Узнать цену?

Найти исполнителя
$0 / весь год.
  • У вас есть задание, но нет времени его делать
  • Вы хотите найти профессионала для выплнения задания
  • Возможно примерение функции гаранта на сделку
  • Приорететная поддержка
  • идеально подходит для студентов, у которых нет времени для решения заданий
Готовое решение
$0 / весь год.
  • Вы можите продать(исполнителем) или купить(заказчиком) готовое решение
  • Вам предоставят готовое решение
  • Будет предоставлено в минимальные сроки т.к. задание уже готовое
  • Вы получите базовую гарантию 8 дней
  • Вы можете заработать на материалах
  • подходит как для студентов так и для преподавателей
Я исполнитель
$0 / весь год.
  • Вы профессионал своего дела
  • У вас есть опыт и желание зарабатывать
  • Вы хотите помочь в решении задач или написании работ
  • Возможно примерение функции гаранта на сделку
  • подходит для опытных студентов так и для преподавателей



Комментарии


Оставить комментарий
Если у вас есть какое-либо предложение, идея, благодарность или комментарий, не стесняйтесь писать. Мы очень ценим отзывы и рады услышать ваше мнение.
To reply

MySql (Maria DB)

Термины: MySql (Maria DB)