序列化与数据库

时间:2009-04-19 08:54:46

标签: c# database serialization

我认为保存应用程序状态的最佳方法是传统的关系数据库,大多数情况下,它的表结构几乎代表了我们系统的数据模型+元数据。

然而,我团队中的其他人认为,现在最好将整个对象图序列化为二进制或XML文件。
没必要说(但我仍然会说)第三次世界大战正在我们之间进行,我想听听你对这个问题的看法。

我个人讨厌序列化,因为:

  1. 保存的数据仅附加到您的开发平台(在我的情况下为C#)。没有像Java或C ++这样的其他平台可以使用这些数据。
  2. 保存整个对象图(包括所有继承链),而不仅仅是我们需要的数据。
  3. 尝试加载旧状态时,更改数据模型可能会导致严重的向后兼容性问题。
  4. 在应用程序之间共享部分数据是有问题的。
  5. 我想听听你对此的看法。

7 个答案:

答案 0 :(得分:16)

您没有说出它是什么类型的数据 - 很大程度上取决于您的性能,同时性,安装,安全性和可用性/集中化要求。

  • 如果此数据非常大(例如,有问题的对象的许多实例),则数据库可以通过其索引功能来帮助提高性能。否则它可能会伤害性能,或者难以区分。

  • 如果您的应用程序同时由多个用户运行,并且他们可能希望编写此数据,则数据库会有所帮助,因为您可以依赖事务来确保数据的完整性。使用基于文件的持久性,您必须自己处理。如果数据是单用户或单实例,则数据库很可能过度。

  • 如果您的应用程序有自己的必须安装,那么使用数据库会给用户带来额外的负担,用户必须设置和维护(应用补丁等)数据库服务器。如果可以保证数据库可用并由其他人处理,则这不是问题。

  • 数据的安全要求是什么?如果数据是集中的,具有多个用户(同时或顺序),则可能需要管理数据的安全性和权限。在没有看到数据的情况下,很难说使用基于文件的持久性或数据库来管理是否更容易。

  • 如果数据仅限本地,则上述有关数据的许多问题都有针对基于文件的持久性的答案。如果您需要集中访问,答案通常指向数据库。

我的猜测是你可能不需要一个数据库,完全基于你主要从编程方便的角度而不是数据需求的角度来询问它。序列化,特别是在.NET中,是高度可定制的,可以轻松定制,只保留您需要的基本部分。这个数据的版本化也有well-known best practices,所以从这个角度来看,我不确定数据库方面是否有优势。

关于跨平台问题:如果您不知道某些将来需要跨平台功能,请不要立即构建。在时机成熟(迁移等)时解决问题几乎肯定比现在限制你的开发更容易。通常是YAGNI

关于在应用程序的各个部分之间共享数据:应该将其构建到应用程序本身,例如:进入访问数据的类。不要将持久性机制重载为应用程序各部分之间的数据管道;如果你以这种方式重载它,你将持久化状态转换为跨对象合同,而不是将其正确地视为对象私有状态的扩展。

答案 1 :(得分:8)

当然,这取决于你想要序列化的内容。在某些情况下,序列化非常容易。

(我曾用Java写过一种时间表程序, 您可以在哪里绘制并拖动对象并调整其大小。如果你准备好了,你可以把它保存在文件中(比如myTimeline.til)。在那个momenet上有数百个被保存的对象,它们在画布上的位置,它们的大小,颜色,它们的内在特征,它们的特殊效果......

你可以打开myTimeLine.til并进一步工作。

所有这些只询问几行代码。 (刚刚制作了所有类及其依赖项 序列化)我的编码时间不到5分钟,我自己也很惊讶! (这是我第一次使用序列化)

在时间轴上工作,您还可以为不同版本“保存”以及非常容易备份和邮寄的“直播”文件。

我认为在我的特殊情况下,使用数据库会有点傻。但这当然只适用于类似文档的结构,比如命名之一。)

我的观点首先是:当然有几种情况下数据库不是最佳解决方案。序列化不是开发人员发明的,只是因为它们很无聊。

  1. 如果您使用XMLserialization或SOAP
  2. ,则不成立
  3. 不再那么相关了
  4. 只有你不小心,才有足够的“最佳实践”。
  5. 只有在您希望它出现问题时,请参阅1
  6. 当然序列化除了实现速度之外还有其他一些重要优点,比如在某些情况下根本不需要数据库!

答案 2 :(得分:3)

有关XML的适用性与数据库管理系统的适用性的评论,请参阅this Stackoverflow posting。它讨论的问题与团队辩论的主题非常相似。

答案 3 :(得分:3)

你有一些好处。我非常赞同你,但我会扮演魔鬼的拥护者。

  1. 好吧,你总是可以在C#中编写一个转换器,以便以后根据需要提取数据。

  2. 这是一个弱点,因为磁盘空间很便宜,而且我们使用的额外字节数远远少于我们浪费的时间,试图让这一切都按照您的方式运行。

  3. 这就是世界的方式。烧毁桥梁并需要升级。转换数据,或制作工具来做到这一点,然后不再支持旧版本的方式。

  4. 如果C#程序将数据移交给其他应用程序,则不会。其他应用程序不应该直接访问属于该应用程序的数据,是否应该?

答案 4 :(得分:2)

对于传输和离线存储,序列化很好;但是为了积极使用,某种数据库更为可取。

通常(如您所说),如果没有数据库,则需要反序列化整个流以执行任何查询,这使得难以扩展。添加线程等固有问题,你要求痛苦。

关于序列化的其他一些痛点并非都是正确的 - 只要你明智地选择。显然,BinaryFormatterportability and versioning的错误选择,但“protocol buffers”(Google的序列化格式)包含Java,C ++,C#和{{3}的版本},并且设计为版本容忍。

答案 5 :(得分:1)

只需确保您有一个处理保存/加载状态的组件,并为您的应用程序的其余部分提供干净的界面。那么你为持久性做出的任何选择都可以在以后轻松重新审视。

将对象图序列化为文件可能是一个快速而又脏的初始解决方案,可以很快实现。

但是如果你开始遇到使数据库成为更好选择的问题,你可以插入一个新版本,对应用程序的其余部分几乎没有影响。

答案 6 :(得分:0)

是的,确实如此。缺点是您必须检索整个对象,就像从表中检索所有行一样。如果它很大,那将是一个缺点。但是,如果它不是那么大,而我的爱好项目他们不是,所以也许他们应该是一个完美的匹配?