我正在探索Mongo作为关系数据库的替代方案,但我遇到了无模式集合概念的问题。
理论上听起来不错,但只要将模型与集合绑定,模型就会成为您的事实模式。您不能再只是添加或删除模型中的字段,并希望它继续工作。我在这里看到了与管理关系数据库相同的问题,因为您需要某种类型的脚本从一个版本的数据库模式迁移到另一个版本。
我是从错误的角度接近这个吗?这里的成员采取了哪些方法来确保他们的收集项在更新其域模型时与其域模型保持同步?
编辑:值得注意的是,这些问题显然也存在于关系数据库中,但我特别要求使用无模式数据库,尤其是Mongo来缓解问题的策略。谢谢!
答案 0 :(得分:12)
使用MongoDB进行模式迁移实际上比使用SQL服务器要痛苦得多。
添加新字段很简单,旧记录将设置为null,或者您可以使用属性来控制默认值[BsonDefaultValue("abc", SerializeDefaultValue = false)]
[BsonIgnoreIfNull]
属性对于在序列化时省略文档中为空的对象也很方便。
删除字段也相当简单,您可以使用[BSonExtraElements]
(请参阅docs)来收集它们并保留它们,或者您可以使用[BsonIgnoreExtraElements]
将其丢弃。< / p>
有了这些,真的没有必要将每个记录转换为新的模式,你可以根据需要在记录更新时或在后台慢慢地进行。
PS,因为你也对使用Mongo动态感兴趣,这里是experiment我尝试过这些行。这是一篇包含完整serializer and deserializer for dynamic objects的更新帖子。
答案 1 :(得分:0)
我目前的想法是使用与使用关系数据库相同的实现方式。拥有一个存储当前数据库版本的数据库版本集合。
我的存储库将具有所需的最低版本,以便准确地序列化和反序列化集合项。如果当前的db版本低于所需的版本,我只是抛出异常。然后使用迁移来完成将集合更新到要反序列化的所需状态所需的所有转换,并更新数据库版本号。
答案 2 :(得分:0)
对于像C#这样的静态类型语言,只要某个对象在某处被序列化,那么它的原始类就会改变,然后它被反序列化回到新类中,你可能会在某个地方遇到问题。无论是MongoDB,WCF,XmlSerializer还是其他什么都是不可避免的。
您通常可以使用serialization options获得一些灵活性,例如使用Mongo,您可以更改类属性名称,但仍将其值映射到相同的字段名称(例如,使用BsonElement属性)。或者你可以使用BsonIgnoreExtraElements属性告诉反序列化器忽略没有相应类属性的Mongo字段,因此当从Mongo加载旧字段时,删除属性不会导致异常。
总的来说,对于任何结构架构更改,您可能需要重新加载数据或运行迁移脚本。另一种方法是使用C#动态变量,虽然这并没有真正解决潜在的问题,但你只会减少序列化错误。
答案 3 :(得分:0)
我一直在使用mongodb一年多,但不是非常大的项目。我使用hugo's csmongo或前叉here。我喜欢它引入的动态方法。这对于数据库结构不稳定的项目尤其有用。