Подтвердить что ты не робот

Изменение "схемы" в RavenDB

Просто для того, чтобы расширить свои знания, я начал изучать различные варианты NoSQL. Первый, который я посетил, - это RavenDB, и это выглядит интересно. Я все еще пытаюсь нарушить свое глубокое реляционное мышление наряду с типичными процедурами обслуживания RDBMS.

В повседневной работе с Entity Framework мы просматриваем подпрограмму сценариев DB-изменений, обновляем модель сопоставления EF и т.д. Как это работает в материалах NoSQL, особенно RavenDB? Как только приложение стало жить, как можно вносить изменения в различные объекты POCO и т.д. И развертывать его для производства? Что происходит с данными, хранящимися в старых классах POCO?

Я еще не углубился в глубокую или использованную Raven DB. Это может быть очевидно, как только я это сделаю, но хотел бы знать перед собой, чтобы я не заколлировал себя в угол.

Спасибо, Д.

4b9b3361

Ответ 1

Они остаются такими, какие они есть - свойства, которые уже не существуют, будут игнорироваться при загрузке (и потеряны при изменении), а отсутствующие свойства возвращаются как null,

Рекомендуйте использовать операции на основе набора, чтобы данные проверялись с помощью объектной модели.

О, посмотри на меня, я сейчас на компьютере!

В принципе, при переходе в хранилище документов вы правы, признавая, что теряете какую-то функциональность и получаете некоторую свободу в том, что в базе данных у вас есть предварительная схема, и вы пытаетесь загрузить данные, которые не совпадают эта схема приведет к ошибке.

Важно, однако, признать, что существует разница между без схемы и структурой без учета того, что ваши документы содержат свою собственную структуру (пары ключ/значение, обозначающие имя свойства и значение свойства).

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

В этой точке представлено несколько стратегий:

  • Сделайте свою структуру неизменной, как только вы сохранили данные, версии ваших классов
  • Разрешить изменение структуры, но использовать операции на основе набора для обновления данных для соответствия новой структуре
  • Разрешить модификацию структуры и написать код для устранения несоответствий при загрузке данных.

Третий, безусловно, плохая идея, так как это приведет к недостижимому коду, управление версиями ваших классов может работать, если вы просто храните события или другие такие данные, но не подходит для большинства сценариев, поэтому вы остаетесь с средним вариантом.

Я бы рекомендовал сделать именно это и следовать нескольким простым правилам в соответствии с теми же строками, что и в случае с предыдущей схемой в реляционной базе данных.

  • Используйте систему VCS для определения изменений между развернутыми версиями
  • Запись сценариев миграции, которые обновляются с одной версии на другую
  • Будьте осторожны с переименованием/удалением свойств - поскольку загрузка документа и сохранение документа приведут к утере данных, если эти свойства не существуют в новом документе

Etc.

Я надеюсь, что это будет более полезно: -)

Ответ 2

RavenDB сериализует ваши объекты .NET в формате JSON. Нет схемы.

Если вы добавите некоторые объекты в свою базу данных, они будут сериализованы. Если вы добавите некоторые свойства в тип, который вы сериализуете, объекты, которые вы уже сохранили, не будут иметь этих свойств.

Ответ 3

В этой статье Айенде описывается, как выполнить переход от 1 до версии 2 (в этом случае изменить свойство "Имя" на свойства "FirstName" и "LastName".

http://ayende.com/blog/66563/ravendb-migrations-rolling-updates

Обычно в DocumentStore зарегистрирован слушатель:

documentStore.RegisterListener(new CustomerVersion1ToVersion2Converter())

Впечатление образца, взятое из упомянутой выше статьи:

public class CustomerVersion1ToVersion2Converter : IDocumentConversionListener
{
    public void EntityToDocument(object entity, RavenJObject document, RavenJObject metadata)
    {
        Customer c = entity as Customer;
        if (c == null)
            return;

        metadata["Customer-Schema-Version"] = 2;
        // preserve the old Name property, for now.
        document["Name"] = c.FirstName + " " + c.LastName;
        document["Email"] = c.CustomerEmail;
    }

    public void DocumentToEntity(object entity, RavenJObject document, RavenJObject metadata)
    {
        Customer c = entity as Customer;
        if (c == null)
            return;
        if (metadata.Value<int>("Customer-Schema-Version") >= 2)
            return;

        c.FirstName = document.Value<string>("Name").Split().First();
        c.LastName = document.Value<string>("Name").Split().Last();
        c.CustomerEmail = document.Value<string>("Email");
    }
}

Ответ 4

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

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

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

Для более сложных изменений, таких как переименование/объединение полей или изменение формата данных, добавьте новое поле в свой объект, не удаляя старые, и передайте данные о переносе данных из старых полей. Когда вы сохраните запись, она будет в новом формате. Этот код можно либо оставить на месте, либо обновить данные по мере необходимости, либо вы можете настроить одноразовый процесс для вызова того же кода для всех существующих объектов. Обратите внимание, что в отличие от sql script для этого типа обновления не требуется время простоя, даже если для большого набора данных требуется много времени, потому что код может обрабатывать как старые, так и новые форматы.