1

现在编辑我正在编写一个两遍算法,首先创建所有父母,然后设置所有孩子(截至 8 月 7 日晚上 9:30)

我想知道在存储和查询递归层次结构时使用 SQLite 是否比使用 Core Data 更好,只是为了避免将 sql 行转换为 Core Data 存储所需的时间。

这是我可以将 sql 行转换为核心数据存储的一种方法:我在 MySQL 中有一个类别层次结构。每行都有一个categoryIdnameparentId,其中parentIdcategoryId包含它的类别的 。我想将此表转换为核心数据。我可以遍历行数组以生成一个NSDictionary,其中每个条目都有一个作为父类别名称的键和一个作为子名称数组的值。然后我可以使用递归函数将对象插入核心数据。

这个过程中每个操作的时间复杂度为:

  • O(n^2)对 MySQL 条目进行排序parentId
  • O(n)解析 mysql 行O(n)以查找每个父级的子级(假设行按 parentId 排序)
  • O(n^2)通过 id 获取每个类别名称
  • 考虑到孩子的数量总是< 10,类似于O(n)递归地将 转换NSDictionary为对象。Core Data
4

2 回答 2

0

“如果我使用 SQLite使用Core Data 更好”

核心数据使用 SQLite。也许我没有得到这个问题。

您是否建议将 a) Core Data 与 SQLite 一起使用;与 b) Core Data 只是对存储在 MySQL 中的数据执行 NSFetchPredicate(或你有什么)。...然后问题就变成了 MySQL vs SQLite

需要注意的一件事:您可以比较使用 SQLite 与二进制的 Core Data —— 没有代码更改的好处。

于 2013-08-07T08:06:37.280 回答
0

答案是,是的,我可以轻松地将 MySql 中的递归层次结构转换为 Core Data。这是简单的两遍算法。首先将所有父母插入数据库中。然后将每个孩子添加到其父母。

+ (void)populateCategories {
    [[ROAPIManager sharedInstance] request:GET
                                  endpoint:@"test_categories"
                                parameters:nil
                                   success:^(NSArray *data) {
                                       if ([data  count] > 0) {
                                           [self insertParentCategoriesIntoCoreDataFromArray:data];
                                           [self insertChildCategoriesIntoCoreDataFromArray:data];
                                       }
                                   }
                                     error:^(ROAPIError *error) {
                                         UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:error.message delegate:nil cancelButtonTitle:NSLocalizedString(@"LocalizedOK", nil) otherButtonTitles:nil];
                                         [alert show];
                                     }
                                    failed:^{
                                        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:NSLocalizedString(@"ErrorDuringSetup", nil) delegate:nil cancelButtonTitle:NSLocalizedString(@"LocalizedOK", nil) otherButtonTitles: nil];
                                        [alert show];
                                    }];
}

+ (void)insertParentCategoriesIntoCoreDataFromArray:(NSArray *)array {
    ROAppDelegate *delegate = (ROAppDelegate *)[UIApplication sharedApplication].delegate;
    NSManagedObjectContext *managedObjectContext = [delegate managedObjectContext];

    NSEntityDescription *categoryEntity = [NSEntityDescription entityForName:@"ROCategory" inManagedObjectContext:managedObjectContext];

    for (int i = 0; i < [array count]; i++) {
        ROCategory *category = [[ROCategory alloc] initWithEntity:categoryEntity insertIntoManagedObjectContext:managedObjectContext];
        NSArray *mySQLRow = [array objectAtIndex:i];
        NSString *name = [mySQLRow objectAtIndex:1];
        [category setValue:name forKey:@"name"];
    }
}

+ (void)insertChildCategoriesIntoCoreDataFromArray:(NSArray *)array {
    ROAppDelegate *delegate = (ROAppDelegate *)[UIApplication sharedApplication].delegate;
    NSManagedObjectContext *managedObjectContext = [delegate managedObjectContext];
    NSEntityDescription *categoryEntity = [NSEntityDescription entityForName:@"ROCategory" inManagedObjectContext:managedObjectContext];

    for (int i = 0; i < [array count]; i++) {
        NSArray *mySQLRow = [array objectAtIndex:i];
        // can't add the topmost category as a child
        if (![[mySQLRow objectAtIndex:2] isEqualToNumber:[NSNumber numberWithInt:-1]]) {
            NSString *name = [mySQLRow objectAtIndex:1];

            // fetch the child by name
            NSFetchRequest *request = [[NSFetchRequest alloc] init];
            [request setEntity:categoryEntity];
            request.predicate = [NSPredicate predicateWithFormat:[NSString stringWithFormat:@"name LIKE[c] \'%@\'", name]];

            NSError *error;
            NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
            if (!mutableFetchResults) {
                // major alert
            }

            if ([mutableFetchResults count] > 0) {
                ROCategory *childEntity = [mutableFetchResults objectAtIndex:0];
                [childEntity setValue:name forKey:@"name"];
                NSNumber *parentId = [mySQLRow objectAtIndex:2];
                ROCategory *parentEntity = [self parentEntityForId:parentId inArray:array];
                if (parentEntity) {
                    NSMutableOrderedSet *children = [parentEntity mutableOrderedSetValueForKey:@"children"];
                    [children addObject:childEntity];
                }
            } else {
                NSLog(@" ERROR there were no results returned");
            }
        }
    }
}
于 2013-08-08T06:59:04.150 回答