2012-08-05 115 views
2

在我们的应用程序中,我们正在实现通过网络/电子邮件共享部分核心数据SQLite数据库。为了保持较小的文件大小,我实现了下面的方法来缩小Core Data数据库。在核心数据上使用Sqlite3 VACUUM命令SQLite持久存储

- (void) shrinkDB 
    { 
     sqlite3 * database; 
     NSString * string = [shareStoreURL path]; 
     const char * filename = [string cStringUsingEncoding:[NSString defaultCStringEncoding]]; 
     char *errMsg; 
     if (sqlite3_open(filename, &database) == SQLITE_OK) 
     { 
      NSLog(@"Shrinking..."); 
      if (sqlite3_exec(database, "VACUUM;", NULL, NULL, &errMsg) != SQLITE_OK) 
      { 
       NSLog(@"Failed execute VACUUM"); 
      } 
      sqlite3_close(database); 
     } 
     } 

问题:上面的代码确实收缩了数据库。但是苹果表示,Core Data的实施细节随时都可能发生变化。你认为我可以在可预见的未来使用这种方法吗?或者还有其他更好的解决方案吗?

+0

可能重复[如何真空核心数据SQLite数据库?](http://stackoverflow.com/questions/1532172/how-to-vacuum-a-core-data-sqlite-db) – OrangeDog 2016-09-19 15:57:38

回答

5

正确的做法是将NSSQLiteManualVacuumOption赋予持久存储协调器。从文档

段:

NSSQLiteManualVacuumOption

选项键重建存储文件, 迫使数据库范围碎片整理时,店里被添加到 协调。这将调用SQLite的VACUUM命令。它被除SQLite商店以外的 商店忽略。在OS X v10.6及更高版本中可用。 在NSPersistentStoreCoordinator.h中声明。

看到这个:https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/CoreDataFramework/Classes/NSPersistentStoreCoordinator_Class/NSPersistentStoreCoordinator.html

+0

感谢Jody!正如Scott在下面说的,看起来我必须在通过电子邮件发送之前重新打开并关闭。 – Dhanush 2012-08-06 16:45:29

+0

如果使用核心数据接口,则不一定。您可以使用多个持久性存储协调器。但是,另一个可能会被锁定,直到真空完成。 FWIW,那是一个封锁吗?你真的认为在开放和运行的核心数据栈下运行纯SQL命令会更好吗? – 2012-08-06 17:02:57

2

如何在SQLite数据库苹果结构的持久性数据是一个实现细节是随时可能更改。但是,SQLite管理已删除记录的方法与Apple的实现无关。

这就是说,真空SQLite数据库的过程导致重建整个数据库,如果CoreData NSPersistentStoreCoordinator正在使用sqlite文件,这可能会产生负面影响。

就你而言,听起来好像你想在保存更改之后但在通过电子邮件发送之前抽真空。使用NSSQLiteManualVacuumOption选项似乎只能在SQLite文件初次打开时清空数据库。

我会在文件不再与NSPersistentStoreCoordinator关联后运行上述代码,或者使用NSSQLiteManualVacuumOption,然后在通过电子邮件发送之前重新打开并关闭该文件。

另一种选择是使用外部SQLite工具(例如OS X上的Base)手动抽取文件。我过去也使用过Firefox SQLite管理器扩展。

+0

谢谢Scott!在运行代码之前,我将核心数据堆栈中的持久性存储删除。 – Dhanush 2012-08-06 16:48:45

相关问题