代码之家  ›  专栏  ›  技术社区  ›  Rob Keniger

在核心数据模型中高效地存储相同的数据

  •  4
  • Rob Keniger  · 技术社区  · 16 年前

    我有一个数据模型,它包含几个实体,每个实体都有几个不同的属性来存储图像数据。这些都是小图像,我需要将它们存储在持久存储中,而不是作为外部文件。

    虽然我可以将图像数据存储在二进制或可转换属性中,但用户很可能会为其中两个或多个属性指定相同的图像,因此我宁愿存储每个唯一图像的一个副本,也不愿复制图像数据。

    我在创建一个“ImageBlob”实体来存储图像数据和使用关系来实现这一点上做得很糟糕,但我是一个核心数据的新手,我并不认为这是正确的方法。特别是,我如何处理以下情况?

    • 我希望多个实体中的所有图像属性使用相同的“图像数据存储”,以便只存储每个图像blob的一个实例

    最好的处理方法是什么?

    2 回复  |  直到 16 年前
        1
  •  2
  •   Alex    16 年前

    我的第一个问题是,当两个对象使用同一图像时,您计划如何识别?图像上是否有可以存储和查询的属性,以确定正在设置的图像是否已存在?计算起来,这有多贵?如果这需要很多时间,您可能最终会优化存储并影响性能。

    但是,如果您确实有一种有效的方法,那么您可以创建一个 ImageBlob 实体来做你描述的事情。使用的实体 ImageBlob s应该有一个 imageBlob imageBlobs ImageBlob ImageBlob 应该和一个名字有相反的关系,比如, users .

    在代码中,当您希望重用 ,它很简单,就像这样做:

    NSManagedObject *blob = // get the image blob
    NSManagedObject *user = // get the user
    [user setValue:blob forKey:@"imageBlob"]; // do this if it uses a single image
    [[user mutableSetValueForKey:@"imageBlobs"] addObject:blob]; // do this if it uses multiple images
    

    NSPersistentDocument 子类(取决于您的应用程序是否基于文档) NSManagedObjectContextObjectsDidChangeNotification 通知。每当托管对象上下文发生更改时,您都可以删除任何不需要的图像,如下所示:

    - (void)managedObjectContextObjectsDidSave:(NSNotification *)notification {
        NSManagedObjectContext *managedObjectContext = [notification object];
    
        NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
        [fetchRequest setEntity:[NSEntity entityWithName:@"ImageBlob" inManagedObjectContext:managedObjectContext]];
        [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"users.@count == 0"];
        NSArray *unusedBlobs = [managedObjectContext executeFetchRequest:fetchRequest error:nil]; // Don't be stupid like me; catch and handle the error
        [fetchRequest release];
    
        for (NSManagedObject *blob in unusedBlobs) {
            [managedObjectContext deleteObject:blob];
        }
    }
    
        2
  •  1
  •   ma11hew28    15 年前

    Image 实体以确保只存储相同的图像一次。

    至于核心数据,我认为这样做可能会奏效: Parent )。从中添加关系 父母亲 打电话 image ,并为删除方法设置“级联”,以便在删除时 , 形象 也被删除。从中添加关系 打电话 parent 形象 ,该图像为 nil . 然后,添加其他实体并将其父实体设置为 父母亲