ios – CoreData导入和升级策略
CoreData有很多值得关注的东西,但我觉得数据导入不是其中之一.我对您用于导入/升级策略的内容有一些疑问,我很乐意听取您的意见.
关于如何提供初始数据库内容,有一些思想流派.有些人会在第一次运行时从文件中导入数据,而其他人则会提供在首次运行时复制和使用的数据存储 – 这是我个人所做的.如果还有其他选择,我很乐意听到. 我对这些方法的问题是在推送升级时该怎么做.当您将数据添加/更改/删除到您希望现有用户看到的初始数据集时,您会怎么做? 您是否在NSUserDefaults中存储正在使用的数据模型的版本,然后在第一次运行新版本时执行一些迁移代码以插入/更新默认数据?我在这里严格谈论数据,而不是架构.所有这一切看起来都很糟糕,因为我可以看到低收视率的浪潮,因为你在编写升级代码时没有想到什么.在CoreData中存储默认应用程序数据(用户没有真正修改)甚至是一件好事吗? 所以我想我的问题是,您首选的导入策略是什么?在发布未来版本时,您通常如何升级数据? 解决方法
tl; dr在提交任何解决方案之前,您应该考虑一下您期望更新的行为方式.任何更新一般可以是完全替换或部分替换(首先是diff,然后替换这些部分).全部和部分替换都有其优点和缺点.这两种解决方案的技术实现可能有很大差异.
如果我理解正确,那么您的应用程序附带了一组初始数据.您想要在应用程序的新版本中更改初始数据集.用户可能已修改或未修改数据. 我看到它的方式,这个问题的一个很好的解决方案取决于您的应用程序以及当前在您的应用程序中存储和使用默认数据的方式. 用户实体和初始实体(可能已修改)在一起 如果应用程序是使用其默认数据集创建的,并且用户稍后可以修改这些条目,则删除这些条目,添加其自己的条目,并且无法确定条目是初始数据集的一部分还是用户修改的条目,然后更新默认的应用程序数据集要复杂得多,但也更有趣. 既然你问“如果数据被修改了什么?”,我假设你也发现这个案例更有趣. 你的预期行为是什么? 就个人而言,我会尝试在进入技术解决方案之前定义您期望的确切行为.有些情况非常简单,如下: >“如果应删除默认数据集中的条目并且用户已将其删除,则不执行任何操作” 但是,这些有许多微妙的变化,比如 >“如果应删除默认日期集中的条目并且用户已对其进行了修改,那么……”. 在这种情况下,您应该将数据视为用户数据的一部分而不是对其进行修改,但也许您有充分的理由进行更新.当你开始写下这些时,你会清楚地看到有很多你以前可能没有的情况.此外,通过编写这些案例,您可以记录您的决定,以便以后可以返回并查看它们. 你有什么未来的计划? 一旦您详细确定了数据更新的目标,您就可以继续思考如何为这些目标实施解决方案.这也是开始思考未来的好时机.如果您觉得现在需要更新初始数据集,那么将来很可能会再次更新它们.也许现在是思考如何在未来更轻松地进行这类更新的好时机.也许这是更新架构的好时机.但也许不是.更新问题的某些解决方案不需要架构更新. 设计未来的数据更新 如果在考虑如何更新这些数据的同时,您偶然感受到“如果只是XYZ”.然后你可能有一个地方开始设计你未来的更新机制.如果不了解数据的复杂性,数据的大小或更新中插入,删除和未更改的内容的大致比例,则很难给出有关如何设计良好更新解决方案的具体提示.但是我会尝试指出要考虑的事情. 进入非常高级别的抽象,有两种主要方式来更新一组数据:替换所有数据或计算差异并仅替换已更改的内容 1.替换一切 设计 如果初始数据量非常小,即小到不需要高级更新机制,则可以在每次更新时更新整个默认数据集.为了能够在不改变用户数据的情况下替换默认数据,您需要将默认数据与用户数据分开(或者具有已经分离的解决方案),或者至少能够识别条目是否属于初始数据集与否. 将默认数据与用户数据分开 为了能够简单地“用新的默认数据替换所有旧的默认数据”,需要识别和删除所有旧数据.这可以通过几种不同的方式完成.如果可以启发式地识别条目是否是默认数据集的一部分,可能通过创建它的时间戳或类似的时间戳,则不需要进行大的修改.所有这些条目都可以标识为默认数据.如果没有,那么首次更新将更加困难. 如上所述,您应该设计更多未来的更新.因此,如果您无法确定哪些数据是默认数据集的一部分以及用户数据是什么,那么您应该修改模型,以便有一些方法可以将它们分开.一个简单的布尔值是一个非常小的修改. 值得注意的是,由于核心数据在关系之后在场景后面做了大量工作并根据每个关系的删除规则采取了行动,因此值得注意的是,大型核心数据删除可能非常缓慢.如果删除整个数据集,将默认数据分离到自己的存储区,即光盘上自己的SQLite文件,可能会更快.然后可以删除整个SQLite文件,因为其中的所有实体都将被删除.然而,这将增加解决方案的复杂性,因此在做出任何性能决策之前测量删除所花费的时间. 修改后的条目怎么样? 如上所述,在更新时可以通过修改的实体完成一些不同的事情,并且取决于是否应将修改的实体视为用户实体,必须更改这些实体以使它们显示为用户实体到更新机制(即删除所有默认实体的东西). (旁注:如果将修改后的默认实体修改回其原始值,是否应被视为用户实体或默认实体?我们如何跟踪此类更改?) 更新程序 根据初始数据是否单独存储以及您是否选择将其分开,可能需要首次进行迁移.如果无法确定哪些数据是默认集的一部分,则可能还需要迁移.迁移后,如果需要,可以单独更新初始数据,而无需迁移以备将来的数据更新. 根据确切的解决方案,可以使用父/子上下文在后台进行更新.这在解决方案2(“差异”)中进一步描述. 优点: >减少要编写的代码 缺点: >可能需要迁移才能从用户数据中拆分默认数据 2.只替换差异 设计 根据您的数据的复杂程度以及更新中已更改和未更改条目的比例,一种适合少量更改条目的设计可能是单独存储所有更新.但是,这需要以这种方式描述所有更新.如果您知道旧的默认数据集和新的默认数据集之间的差异,那么所有更新都可以描述为删除,插入或修改. (这类似于版本控制系统的工作原理:而不是(在版本控制的情况下)复制整个文件,只添加修改(“差异”).如果更新你不保留过时的数据,你替换它的好处是相似的.更新时间与更新的大小成比例,而不是与数据的总大小成比例.) 插入 插入可能是最简单的插入.通过存储要单独插入的所有新条目,可以将它们迭代并添加到用户数据中. 删除 删除同样容易,只要可以唯一地识别entires并且只要可以确保它们没有以任何方式被修改.通过存储必要的信息来唯一地标识实体并确保它没有被修改.可以从Core Data中提取和删除这些条目. 修改 根据变更的复杂程度,修改后的条目可能非常棘手.单值修改几乎是微不足道的,但关系修改可以解决许多新问题,这些问题应该在进一步研究之前进行(如上所述). 如何存储更新? 你可能已经注意到我对这些更新的存储方式一直模糊不清.这是因为这也取决于手头的需求和资源.一个简单的解决方案是将它们作为预先填充的数据以某种方式包含在更新的应用程序中.但是,更新不必存储在设备本身上.如果所有更新的总大小足够小,则它们可以位于服务器上并在后台下载到设备.在服务器上存储更新可以获得巨大的好处,可以在不必更新应用程序本身的情况下推送数据的新更新. 无论如何,下载更新与否,一旦更新在设备上,它们应以某种方式存储.它们可以存储在应用程序中的另一个Core Data模型中,在这种情况下,您不必进行迁移,因为更新是另一个模型中的实体.将更新存储在平面文件或任何其他非核心数据方式中也具有此优势. 决定如何存储更新类似于首先决定如何存储任何类型的数据.它应该类似于您决定将Core Data用于主数据的过程. 更新程序 当用户启动更新的应用程序时,您无需锁定UI以进行长时间迁移,因为不必更改模型本身.假设更新已经以某种方式在设备上获得并存储在某个地方,它们可以在后台迭代.如果您只定位iOS 5,则可以使用父/子上下文设置在后台更新Core Data.关于如何在Core Data中进行后台导入的一个很好的资源是从iDeveloper.tv开始的Core Data for Mac,iPhone & iPad Update.当然还有“核心数据中的新功能”WWDC视频,它们也涵盖了父/子上下文设置. 如果你使用这样的解决方案,你可以创建一个后台上下文,并在低优先级队列中进行所有修改.根据要更新的数据量,我将批量保存对“真实”核心数据上下文的任何修改,并删除已经处理的更新表中的实体.这样,如果更新花了很长时间并且用户退出或者应用程序在其中间崩溃,整个更新过程将能够恢复到原来的状态. 一般来说,无论如何插入或删除大量数据都不重要,最好分批保存,并以某种方式指示已处理的数据,以便应用程序可以恢复导入/删除.每次进入后都无需保存.如果应用程序崩溃并且几个条目没有保存,如果它可以在处理这些条目之前恢复并再次处理它们仍然是一个巨大的胜利.通过指示某些数据仅在保存后才被处理,此导入可以知道在何处恢复而不会丢失任何数据. 如果使用要插入/删除/修改的数据列表:通过从这些列表中删除实体,这些列表中的实体已经保存在Core Data中,更新机制可以跟踪尚未处理的插入/更新/删除. 将所有更新保存到“真实”上下文后,您将只剩下一个空的更新列表. 注意:在父/子上下文中,您必须在某个时刻保存“主”上下文,因为它是唯一一个实际将数据保存到磁盘的上下文.其他保存仅在内存中. 优点: >更高性能的小更新或大量未更改的数据. 缺点: >要编写大量代码 我注意到这个答案比我最初想要的要长.我意识到我试图在我的解决方案中保持非常一般性,并且这对于您的解决方案可能不够精确.如果您愿意,可以对我的答案发表评论,并添加有关您的问题和您所遇到的限制的更多详细信息.通过这种方式,我可以更好地满足您的需求. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |