我认为保存应用程序状态的最佳方法是传统的关系数据库,大多数情况下,它的表结构几乎代表了我们系统的数据模型+元数据。
然而,我团队中的其他人认为,现在最好将整个对象图序列化为二进制或XML文件。
没必要说(但我仍然会说)第三次世界大战正在我们之间进行,我想听听你对这个问题的看法。
我个人讨厌序列化,因为:
我想听听你对此的看法。
答案 0 :(得分:16)
您没有说出它是什么类型的数据 - 很大程度上取决于您的性能,同时性,安装,安全性和可用性/集中化要求。
如果此数据非常大(例如,有问题的对象的许多实例),则数据库可以通过其索引功能来帮助提高性能。否则它可能会伤害性能,或者难以区分。
如果您的应用程序同时由多个用户运行,并且他们可能希望编写此数据,则数据库会有所帮助,因为您可以依赖事务来确保数据的完整性。使用基于文件的持久性,您必须自己处理。如果数据是单用户或单实例,则数据库很可能过度。
如果您的应用程序有自己的必须安装,那么使用数据库会给用户带来额外的负担,用户必须设置和维护(应用补丁等)数据库服务器。如果可以保证数据库可用并由其他人处理,则这不是问题。
数据的安全要求是什么?如果数据是集中的,具有多个用户(同时或顺序),则可能需要管理数据的安全性和权限。在没有看到数据的情况下,很难说使用基于文件的持久性或数据库来管理是否更容易。
如果数据仅限本地,则上述有关数据的许多问题都有针对基于文件的持久性的答案。如果您需要集中访问,答案通常指向数据库。
我的猜测是你可能不需要一个数据库,完全基于你主要从编程方便的角度而不是数据需求的角度来询问它。序列化,特别是在.NET中,是高度可定制的,可以轻松定制,只保留您需要的基本部分。这个数据的版本化也有well-known best practices,所以从这个角度来看,我不确定数据库方面是否有优势。
关于跨平台问题:如果您不知道某些将来需要跨平台功能,请不要立即构建。在时机成熟(迁移等)时解决问题几乎肯定比现在限制你的开发更容易。通常是YAGNI。
关于在应用程序的各个部分之间共享数据:应该将其构建到应用程序本身,例如:进入访问数据的类。不要将持久性机制重载为应用程序各部分之间的数据管道;如果你以这种方式重载它,你将持久化状态转换为跨对象合同,而不是将其正确地视为对象私有状态的扩展。
答案 1 :(得分:8)
当然,这取决于你想要序列化的内容。在某些情况下,序列化非常容易。
(我曾用Java写过一种时间表程序, 您可以在哪里绘制并拖动对象并调整其大小。如果你准备好了,你可以把它保存在文件中(比如myTimeline.til)。在那个momenet上有数百个被保存的对象,它们在画布上的位置,它们的大小,颜色,它们的内在特征,它们的特殊效果......
你可以打开myTimeLine.til并进一步工作。
所有这些只询问几行代码。 (刚刚制作了所有类及其依赖项 序列化)我的编码时间不到5分钟,我自己也很惊讶! (这是我第一次使用序列化)
在时间轴上工作,您还可以为不同版本“保存”以及非常容易备份和邮寄的“直播”文件。
我认为在我的特殊情况下,使用数据库会有点傻。但这当然只适用于类似文档的结构,比如命名之一。)
我的观点首先是:当然有几种情况下数据库不是最佳解决方案。序列化不是开发人员发明的,只是因为它们很无聊。
当然序列化除了实现速度之外还有其他一些重要优点,比如在某些情况下根本不需要数据库!
答案 2 :(得分:3)
有关XML的适用性与数据库管理系统的适用性的评论,请参阅this Stackoverflow posting。它讨论的问题与团队辩论的主题非常相似。
答案 3 :(得分:3)
你有一些好处。我非常赞同你,但我会扮演魔鬼的拥护者。
好吧,你总是可以在C#中编写一个转换器,以便以后根据需要提取数据。
这是一个弱点,因为磁盘空间很便宜,而且我们使用的额外字节数远远少于我们浪费的时间,试图让这一切都按照您的方式运行。
这就是世界的方式。烧毁桥梁并需要升级。转换数据,或制作工具来做到这一点,然后不再支持旧版本的方式。
如果C#程序将数据移交给其他应用程序,则不会。其他应用程序不应该直接访问属于该应用程序的数据,是否应该?
答案 4 :(得分:2)
对于传输和离线存储,序列化很好;但是为了积极使用,某种数据库更为可取。
通常(如您所说),如果没有数据库,则需要反序列化整个流以执行任何查询,这使得难以扩展。添加线程等固有问题,你要求痛苦。
关于序列化的其他一些痛点并非都是正确的 - 只要你明智地选择。显然,BinaryFormatter
是portability and versioning的错误选择,但“protocol buffers”(Google的序列化格式)包含Java,C ++,C#和{{3}的版本},并且设计为版本容忍。
答案 5 :(得分:1)
只需确保您有一个处理保存/加载状态的组件,并为您的应用程序的其余部分提供干净的界面。那么你为持久性做出的任何选择都可以在以后轻松重新审视。
将对象图序列化为文件可能是一个快速而又脏的初始解决方案,可以很快实现。
但是如果你开始遇到使数据库成为更好选择的问题,你可以插入一个新版本,对应用程序的其余部分几乎没有影响。
答案 6 :(得分:0)
是的,确实如此。缺点是您必须检索整个对象,就像从表中检索所有行一样。如果它很大,那将是一个缺点。但是,如果它不是那么大,而我的爱好项目他们不是,所以也许他们应该是一个完美的匹配?