只是为了扩大我的知识,我已经开始研究各种NOSQL选项。我访问的第一个是Ravendb,看起来很有趣。我仍在努力打破典型的RDBMS维护例程,打破我的深层关系思维。

在我的日常处理实体框架中,我们经历了脚本脚本DB更改,刷新EF映射模型等的常规。一旦应用程序栩栩如生,人们如何对各种POCO对象等进行更改并将其部署到生产中?存储在旧POCO类中的数据会发生什么?

我还没有深入研究或愤怒地使用乌鸦DB。一旦我做到这一点,这可能很明显,但很想事先知道,所以我不会将自己编写成角落。

感谢:D。

有帮助吗?

解决方案

它们保持原样 - 加载(丢失在更改)时,不再存在的属性将被忽略,并且丢失的属性将返回为null,

建议您使用基于集合的操作来检查数据与对象模型。

哦,看着我,我现在在电脑上!

因此,基本上,在搬到文档存储时,您可以意识到自己失去了一些功能并获得一些自由,因为在数据库中,您具有定义的前期架构,并尝试上传不匹配该模式的数据导致错误。

但是,重要的是要认识到,无模式和无结构之间存在差异,因为您的文档都包含其自己的结构(键/值对表示属性名称和属性值)。

这使得对整个“仅”编写一些代码并持续数据的“仅”因素有用 - 但是,当更容易解决您的代码结构时,很难将其与已经持久的数据调和。

此时表现出一些策略:

  • 一旦您持久数据,将您的结构变成不变
  • 允许修改结构,但使用基于集合的操作更新数据以匹配新结构
  • 允许修改结构,并编写代码在加载数据时处理不一致之处

第三个显然是一个坏主意,因为它将导致无法获得的代码,如果您只是存储事件或其他此类数据,则可以使用类别来使用,但实际上并不适合大多数情况,因此您却剩下的中间选项。

我建议这样做,并按照与关系数据库中的前期架构进行处理时要遵循的一些简单规则。

  • 使用VCS系统确定已部署版本之间的更改
  • 编写从一个版本升级到另一个版本的迁移脚本
  • 请注意重命名/删除属性 - 如果新文档中不存在这些属性,则加载文档并保存文档将导致丢失的数据

等等。

我希望这更有帮助:-)

其他提示

Ravendb将您的.NET对象序列化为JSON格式。没有模式。

如果您在数据库中添加一些对象,它们将被序列化。如果将一些属性添加到要序列化的类型中,则已经存储的对象将缺少这些属性。

Ayende的本文描述了如何执行从1到2版的迁移(在这种情况下,将“名称”属性更改为“ firstName”和“ lastName”属性。

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

基本上,在文档商店中注册了听众:

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");
    }
}

您没有太多的架构管理,因为它将其移至代码中,因此代码中的对象与数据库中的对象之间的不匹配永远不会不匹配。

处理更改的第一部分是确保您使用可以处理缺失/额外值的序列化器 - 如果数据中未定义的字段,请将其设置为null。如果数据中的字段与对象上的属性不匹配,请忽略它。

大多数更改都可以处理,而无需更多的更改 - 要么有一个新字段,而且您需要对现有记录具有默认值,或者有一个您不再关心的旧字段。

有关更复杂的更改,例如重命名/组合字段或更改数据格式,请在您的对象中添加一个新字段,而无需删除旧字段,并使您的负载方法从旧字段传输数据。保存记录时,它将采用新格式。该代码可以永久保留在适当的位置,根据需要更新数据,也可以设置一个时间过程,以调用所有现有对象的相同代码。请注意,与SQL脚本不同,这种类型的更新也不需要停机时间,即使在大型数据集上运行需要很长时间,因为代码可以处理旧格式和新格式。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top