Статьи

MongoDB и концепция идентичности в базах данных NoSQL

В этой статье я имею дело с другой базой данных NoSql под названием MongoDb — зрелым движком NoSql, рожденным вне мира .NET, чтобы прояснить концепцию Id в типичной базе данных No Sql. Установка Mongo действительно проста, просто скачайте, распакуйте, найдите папку bin и введите ее из консоли администратора, чтобы установить Mongo как службу

   1: mongod --install --logpath c:xxxx --dbpath c:yyyy

Вы можете найти множество руководств по установке в Интернете, но с помощью приведенной выше команды установки вы создадите службу Windows, которая автоматически запустит MongoDb на вашем компьютере с использованием указанной папки данных. Теперь вам нужно скачать драйвер C # для подключения из кода .NET, но если вам нравится использовать LINQ, вы можете установить fluent mongo напрямую с помощью nuget.

образ

Рисунок 1: Установите беглый монго с помощью nuget.

Fluent Mongo — это библиотека, которая давала мало возможностей LINQ по сравнению со стандартными драйверами, но добавив ссылку на nuget к fluentmongo, вы автоматически получаете ссылку на официальные драйверы. Теперь вы готовы вставить свою первую запись в MongoDb с указанным выше кодом.

MongoServer server = MongoServer.Create();
MongoDatabase databaseTest = server.GetDatabase("TEST");
var untyped = databaseTest.GetCollection("UNTYPED");
untyped.Save(new BsonDocument { { "Name", "Untyped1" } });
BsonDocument secondDocument = BsonDocument.Parse("{Name: 'Untyped2', BlaBla: 'Bla Bla Value'}");
untyped.Save(secondDocument);

В строке 1 я создаю соединение с сервером MongoDb без передачи параметров для подключения к локальному серверу MongoDb, затем получаю ссылку на объект MongoDatabase с именем «TEST» с помощью метода MongoServer :: GetDatabase () и, наконец, получаю ссылку на коллекцию с именем «UNTYPED» с помощью метода MongngoDatabase :: GetCollection (). Это очень похоже на Sql Server или другую базу данных SQL, у вас есть сервер, сервер содержит несколько баз данных, и каждая база данных состоит из таблиц; Точно так же Монго делится на Сервер / База данных / Коллекция, где Коллекция содержит Документ.

MongoDB хранит данные в формате JSON, и для вставки данных в коллекцию вы можете просто создать BsonDocument, объект, определенный сборкой драйвера C #, который способен представлять документ, составленный из серии пар ключ-значение. Чтобы инициализировать BsonDocument, вы можете передать ICollection (строка 4) или, если вы чувствуете себя более комфортно с представлением String JSON, вы можете использовать BSonDocument.Parse (), чтобы указать документ непосредственно с помощью строки JSON.

После того, как вы вставили вышеуказанные документы, вы можете использовать MongoVue, чтобы увидеть, что содержится в базе данных.

образ

Рисунок 2: Используйте mongovue, чтобы увидеть, что находится внутри базы данных

Интересный аспект заключается в том, что каждый документ имеет уникальный идентификатор, даже если я не указал в коде никаких специальных свойств. Это стандартное поведение для баз данных NoSql, если вы не указали какое-либо свойство id, ядро ​​базы данных самостоятельно создаст уникальный идентификатор для упрощения документа. Идентификатор является ключевым фактором для Mongo и других хранилищ NoSql, если вы попытаетесь сохранить документ непосредственно внутри коллекции, указав содержимое JSON, вы получите ошибку.

untyped.Save("{Name: 'Json', Attribute:'attribute content'}");

Объект MongoCollection содержит объект Save, который принимает строку, но приведенный выше вызов завершится ошибкой. Подкласс должен реализовать GetDocumentId . Предыдущий код работает, потому что одна из конкретных функций, которую реализует BSonDocument, — это возможность управлять генерацией идентификатора, но обычный JSON не имеет этой возможности. Если вам нужно знать идентификатор, сгенерированный базой данных, вы можете запросить у BSonDocument его уникальный идентификатор после того, как он был сохранен в коллекции Mongo . (помните, что идентификатор недоступен, пока вы не сохраните документ).

   BsonDocument secondDocument = BsonDocument.Parse("{Name: 'Untyped2', BlaBla: 'Bla Bla Value'}");

   Object id;

   Type idType;

   IIdGenerator generator;

   untyped.Save(secondDocument);

   secondDocument.GetDocumentId(out id, out idType, out generator);

По сути, вы просите ваш BsonDocument вернуть вам сгенерированный идентификатор, а также тип идентификатора и генератор, который Mongo использовал для генерации этого конкретного идентификатора. Результат представлен в этом фрагменте

образ

Рисунок 3: Три объекта, которые вы получили при вызове GetDocumentId: Id, IdType и генератор.

Как видите, Id является экземпляром типа MongoDb.Bson.ObjectId, основанным на базовом классе BsonValue, а генератор является экземпляром ObjectIdGenerator. Этот тип Id специфичен для Mongo, и в документации говорится, что ObjectId

BSON ObjectID — это 12-байтовое значение, состоящее из 4-байтовой метки времени (секунды с начала эпохи), 3-байтового идентификатора компьютера, 2-байтового идентификатора процесса и 3-байтового счетчика. Обратите внимание, что поля timestamp и counter должны храниться с прямым порядком байтов в отличие от остальной части BSON. Это потому, что они сравниваются побайтово, и мы хотим обеспечить в основном увеличивающийся порядок.

Если вы хотите иметь генератор, который создает целочисленный идентификатор, например столбец Identity в SQL Server , вы обнаружите, что он просто недоступен сразу после установки, поскольку значение Int не гарантирует его уникальности при использовании шардинга. Sharding — это метод, который позволяет разбивать данные на разные физические экземпляры, поэтому каждый экземпляр должен генерировать идентификаторы, уникальные для всех экземпляров, и это предотвращает использование простого идентификатора Int32. Очевидно, что в .NET World Guid гарантированно уникален и более ориентирован на .NET, поэтому Mongo Db имеет генератор идентификаторов Guid, который можно указать с помощью приведенного выше фрагмента кода.

BsonDocument thirdDocument = BsonDocument.Parse("{Name: 'Untyped3', AnotherProperty: 'xxxxxxxxxxxxxxxxxxxxxxx'}");

var id2 = MongoDB.Bson.Serialization.IdGenerators.GuidGenerator.Instance.GenerateId(untyped, thirdDocument);

thirdDocument.SetDocumentId(id2);

Ключ с использованием GuidGenerator (в пространстве имен MongoDb.Bson.Serialization.IdGenerators) , чтобы сгенерировать действительное значение Mongoid Guid, затем вызвать SetDocumentId метод BsonDocument вручную установить идентификатор , а не на реле автоматической генерации идентификатора. Если вы посмотрите на базу данных, то обнаружите, что документ с идентификатором Guid действительно имеет другой тип идентификатора.

образ

Рисунок 4: Документ с идентификатором Guid представлен другим способом в mongovue, но, как вы можете убедиться, нет проблем с наличием документов с разными типами идентификаторов в одной коллекции.

Это показывает, что база данных No Sql имеет концепцию Document Id, которая похожа на концепцию Id стандартного сервера Sql, вы можете использовать механизм генерации собственного Id, который генерирует действительный идентификатор во время вставки, или вы можете назначить свой собственный Идентификатор документа, но в целом вся концепция идентификатора больше связана с движком и не имеет делового значения, поэтому я настоятельно не рекомендую использовать в качестве идентификатора документа все, что имеет деловое значение. Никто не запрещает вам вставлять в документ свойство с именем «MyId» или что-то еще, что имеет деловое значение и может использоваться в качестве логического идентификатора, что позволяет Механизму обрабатывать внутренний идентификатор самостоятельно.