虽然没有任何迁移,但核心数据迁移速度很慢

时间:2013-06-11 09:56:19

标签: ios core-data

我创建了一个新模型并重命名了一个实体的2个字段。此实体从未在之前的应用程序版本中使用过,因此我没有将其映射到数据库中新的更新实体。因此,映射不会映射任何新内容,但迁移速度非常慢(主表中大约50行为3秒)。我想知道核心数据是创建新数据库还是删除旧数据库,并重新插入所有数据。这是迁移日志文件:http://cl.ly/3H1v252R1p1c

PS。如果NSInferMappingModelAutomaticallyOption为YES,这是否意味着我可能会遇到数据丢失,因为映射是由核心数据即兴创作的?

感谢

2 个答案:

答案 0 :(得分:3)

iOS上的核心数据使用SQLite进行数据存储。 SQLite不支持ALTER COLUMN,因此Core Data通过以下方式解决此限制:

  1. 重命名旧表
  2. 使用更新后的列创建新表
  3. 将记录插入新表
  4. 放弃旧桌子
  5. 有一个很好的答案here,它更详细地描述了这一点。

    在执行此操作时,我从未见过Core Data丢失数据的任何问题 - 我会假设Apple已实施防范措施,但可能需要直接与Apple DTS联系以确认。

答案 1 :(得分:3)

您能告诉我们您的数据库架构吗?我的猜测是你在其中使用了对象继承。

Core Data通过为父实体创建单个表并为子实体使用的所有字段的union添加列来实现SQL存储中的继承。因此,您可能认为您在一个实体上仅重命名了两个字段,但Core Data必须将更改应用于从该实体继承的每个对象,或者具有该实体的共同祖先。

在您的特定架构中,您看起来有一个实体,Item,至少从该类型,AudioTrack,Studio,Director,Store,Movie,Condition,Region,Owner,AspectRatio,Year,MyRating,Episode,Edition,Format ,制片人,作家,AudienceRating,SeenIt和电影下降。当我通过眼睛阅读您的日志而不是自动分析时,可能还有其他人。因此,Core Data创建了一个名为Item的表,其中存储了每个实体的每个实例。每当这些实体中的任何一个(或者我可能没有找到的其他实体)发生变化时,核心数据就必须更新每个实体的所有实例的记录。

这就是你看到的原因:

CREATE TABLE ZITEM ( Z_PK INTEGER PRIMARY KEY, Z_ENT INTEGER, Z_OPT INTEGER, 
ZUNIQUEID INTEGER, ZCOLLECTIONSTATUS INTEGER, ZHASCOVER INTEGER, ZINDEX INTEGER, 
ZPLOTNOTE INTEGER, ZUSERVALUES INTEGER, ZPURCHASEDATEDAY INTEGER, 
ZPURCHASEDATEMONTH INTEGER, ZPURCHASEDATEYEAR INTEGER, ZRELEASEDATEDAY INTEGER, 
ZRELEASEDATEMONTH INTEGER, ZRUNTIME INTEGER, ZVIEWINGDATEDAY INTEGER, 
ZVIEWINGDATEMONTH INTEGER, ZVIEWINGDATEYEAR INTEGER, ZAUDIENCERATING INTEGER, 
ZCONDITION INTEGER, ZEDITION INTEGER, ZFORMAT INTEGER, ZLOANER INTEGER, 
ZLOCATION INTEGER, ZMYRATING INTEGER, ZOWNER INTEGER, ZSEARCH INTEGER, 
ZSEENIT INTEGER, ZSEENWHERE INTEGER, ZSERIES INTEGER, ZSTORAGEDEVICE INTEGER, 
ZSTORE INTEGER, ZYEAR INTEGER, ZRANK INTEGER, ZTYPEID INTEGER, 
ZCOLLECTIBLE INTEGER, Z3_COLLECTIBLE INTEGER, ZBIN INTEGER, ZSORTORDER INTEGER, 
ZSECTION VARCHAR, ZCLZID VARCHAR, ZCONNECTHASH VARCHAR, ZSORTTITLE VARCHAR, 
ZTITLE VARCHAR, ZACTORS VARCHAR, ZCLZMEDIAID VARCHAR, ZCURRENTVALUE VARCHAR, 
ZIMDBNUMBER VARCHAR, ZIMDBRATING VARCHAR, ZLOANDATE VARCHAR, ZLOANDUEDATE VARCHAR, 
ZPURCHASEPRICE VARCHAR, ZSTORAGESLOT VARCHAR, ZTITLEEXTENSION VARCHAR, 
ZUPC VARCHAR, ZTHEDESCRIPTION VARCHAR, ZURL VARCHAR, ZDISPLAYNAME VARCHAR, 
ZSORTNAME VARCHAR ) 

这是包含Item的所有后代的所有字段的并集的表。这也是为什么例如AudienceRatings的获取执行如下:

SELECT t0.Z_ENT, t0.Z_PK, t0.Z_OPT, t0.ZSECTION ... FROM ZITEM t0 WHERE  t0.Z_ENT = ?

所以:

  • Core Data正在更新超过50行;
  • 如果你想避免这种情况,你需要避免继承;
  • 你可以避免'是'与'有'关系的关系但是核心数据的双向性质经常会让人感到痛苦(如果有30个对象与Item有连接那么Item必须有30个与其他对象的连接) ;
  • 如果Item只是一个像统一时间戳那样微不足道的东西,通常只需要为每个实体添加一个时间戳属性,并让每个实体调用一个共同的代码来建立它。