您如何最小化或压缩Core Data sqlite文件大小?

8 iphone core-data objective-c

我有一个215MB的csv文件,我已经解析并存储在我自己的自定义对象中的核心数据中.问题是我的核心数据sqlite文件大约是260MB.csv文件包含我城市交通系统(公交车站,时间,路线等)的大约450万行数据.

我已经尝试修改属性,以便表示停止时间的字符串数组存储为NSData文件,但由于某种原因,文件大小仍然保持在260MB左右.

我无法发送这么大的应用程序.我怀疑有人会想要下载一个260MB的应用程序,即使这意味着他们有整个城市的运输时间表.

有没有办法压缩或最小化使用的存储空间(即使它意味着不使用核心数据,我愿意听取建议)?

编辑:我只是想立即提供更新,因为我一直难以置信地盯着文件大小.通过一些涉及字符串,索引和数据库规范化的巧妙操作,我已经设法在压缩时将大小减小到6.5MB或2.6MB.Core Data中存储的大约105,000个对象包含城市交通系统的全部详细信息.我现在几乎流泪了D':

Rob*_*ier 8

除非您的原始CSV以非常愚蠢的方式编码,否则无论您压缩多少,它的大小似乎都不会低于100M.对于应用来说,这仍然非常大.解决方案是将您的数据移动到Web服务.您可能想要下载和缓存重要部分,但如果您正在谈论数百万条记录,那么从服务器获取最好.此外,我不得不相信,交通系统不时会发生变化,每次进行一次停止调整时,必须升级10多MB的应用程序才会令人沮丧.


我已经说过,但实际上你可以考虑一些事情:

  • 将布尔值移动到一些字段中.您可以将64个布尔值放入NSUInteger.(如果你只需要8位,就不要使用完整的64位整数.尽可能存储最小的东西.)
  • 压缩存储时间的方式.一天只有1440分钟.您可以将其存储在2个字节中.过境时间一般不到第二; 他们不需要CGFloat.
  • 可以类似地压缩星期几和日期.
  • 显然你应该规范化任何字符串.在许多行上查看CSV的重复字符串值.
  • 对于这类问题,我通常会建议使用原始sqlite而不是核心数据.核心数据更多地是关于对象持久性而不是原始数据存储.事实上,你看到对于这个问题,这个问题并不是一个很好的方向.
  • 如果您想要更紧凑,并且不需要非常好的搜索功能,您可以创建打包数据blob.我曾经在内存非常紧张的手机交换机上这样做.你创建了一个位字段结构,为一个变量分配了5位,为另一个变量分配了7位,等等.有了这些,并且有些时候将它们混合起来,使它们在字边界上正确排列,你可以变得非常紧张.

由于您最关心初始下载大小,并且可能愿意稍后扩展数据以便更快地访问,因此您可以考虑特定于域的压缩.例如,在上面的讨论中,我提到了如何在一段时间内减少2个字节.在许多情况下,你可以通过将时间存储为自上次以来的增量分钟来减少1个字节(因为如果它们是公共汽车和火车时刻表,大多数时间将总是以相当小的步数增加).放弃数据库,您可以创建一个非常紧密编码的数据文件,您可以在首次启动时将其提取到数据库中.

您还可以使用特定于域的知识将字符串编码为较小的标记.如果我编码纽约地铁系统,我会注意到一些字符串显示很多,如"大道","道路","街道","东方"等.我可能将那些编码为不可打印的ASCII像^ A,^ R,^ S,^ E等我可能将"138 Street"编码为两个字节(0x8A13).这当然是基于我的知识,è(0x8a)从未出现在纽约地铁站.这不是一般解决方案(在巴黎它可能是一个问题),但它可以用于高度压缩您特别了解的数据.在像华盛顿特区这样的城市,我相信他们最高编号的街道是第38街,然后是4值方向.因此,您可以将其编码为两个字节,首先是"编号街道"令牌,然后是一个位字段,其中象限为2位,街道号为6位.这种想法可能会显着缩小您的数据量.


Cla*_*och 0

您也许能够执行一些数据库规范化。

查找任何可能多余的内容或相同的值存储在多行中。您可能需要重组数据库,以便将这些重复值(如果有)存储在单独的表中,然后通过 id 从原始行引用。