繁体   English   中英

对数据库执行大量读/写操作的方法

[英]method for performing lot of read/write operations on a database

我正在开发一个iPad应用程序,在该应用程序中,我将不得不对数据库执行很多读/写操作(我必须将对视图的点击存储在数据库中,而基于点击的执行一些操作)。 我对在这种情况下如何进行感到困惑。 我应该创建一个SQLIte数据库并执行读/写操作(这会减慢应用程序的响应时间吗?),还是有其他技术(我听说过Core数据,但不确定是否适合我的情况) 。 请帮我

谢谢

阿吉斯

如果只按顺序保存它们,然后以相同顺序读回它们,则最好使用常规文件。 但是,如果您要执行其他任何操作,请使用CoreData。 它不仅是一个关系数据库。 它允许持久对象图。 另外,如果您使用UIManagedDocument或您自己的父/子NSManagedObjectContext安排,您甚至都不会看到数据库命中,因为这都将在后台线程中发生。

继续进行测试。 覆盖开始/移动/结束触摸,并在每次触摸时将对象扔到数据库中。 如果按照我的描述进行操作,您甚至都不会注意到数据库命中。

假定模型中的两个实体MyTouchEvent和MyTouch,其中MyTouchEvent与MyTouch具有一对多关系。

// Call this from touchesBegan, touchesMoved, and touchesEnded...
- (void) saveTouches:(NSSet*)touches kind:(NSString*)kind
{
    NSManagedObjectContext *moc = self.document.managedObjectContext;
    MyTouchEvent *myTouchEvent = [NSEntityDescription insertNewObjectForEntityForName:@"MyTouchEvent" inManagedObjectContext:moc];
    myTouchEvent.kind = kind;
    for (UITouch *touch in touches) {
        CGPoint touchPoint = [touch locationInView:self];
        MyTouch *myTouch = [NSEntityDescription insertNewObjectForEntityForName:@"MyTouch" inManagedObjectContext:moc];
        myTouch.x = [NSNumber numberWithFloat:touchPoint.x];
        myTouch.y = [NSNumber numberWithFloat:touchPoint.y];
        [myTouchEvent addTouchesObject:myTouch];
    }
    [self.document updateChangeCount:UIDocumentChangeDone];
}

如果创建对象的成本很高,则可以添加一个方法来创建私有上下文,并使用两个选项在其中完成所有工作。 您可以将其作为文档的主要上下文的父对象,在这种情况下,您要做的就是将代码嵌入块中,然后在MOC上调用save ...

- (NSManagedObjectContext*)moc
{
    if (!_moc) {
        _moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
        _moc.parentContext = self.document.managedObjectContext;
    }
    return _moc;
}
- (void) saveTouches:(NSSet*)touches kind:(NSString*)kind
{
    NSManagedObjectContext *moc = self.moc;
    [self.moc preformBlock:^{
        MyTouchEvent *myTouchEvent = [NSEntityDescription insertNewObjectForEntityForName:@"MyTouchEvent" inManagedObjectContext:moc];
        myTouchEvent.kind = kind;
        for (UITouch *touch in touches) {
            CGPoint touchPoint = [touch locationInView:self];
            MyTouch *myTouch = [NSEntityDescription insertNewObjectForEntityForName:@"MyTouch" inManagedObjectContext:moc];
            myTouch.x = [NSNumber numberWithFloat:touchPoint.x];
            myTouch.y = [NSNumber numberWithFloat:touchPoint.y];
            [myTouchEvent addTouchesObject:myTouch];
        }
        NSError *error = nil;
        [moc save:&error];
    }];
}

或者,您可以将其设为同级,在这种情况下,所有DB东西都不会在主线程上运行(UIManagedDocument的主上下文在主线程上运行,因此在上述情况下,主线程将传递对象进行保存的上下文)。 但是,在这种情况下,document.managedObjectContext将必须执行FETCH才能获取放入数据库的所有内容。 但是,它在存储期间不会对主线程造成任何性能。

- (NSManagedObjectContext*)moc
{
    if (!_moc) {
        _moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
        _moc.parentContext = self.document.parentContext;
    }
    return _moc;
}

现在,这些将进入数据库,但是如果您的文档想查看它们,则必须执行提取。 根据您的用例选择最合适的。 我想您会很喜欢第一个示例。

如果单击次数很多,则绝对不希望将它们分别写入数据库。 也许,最好是累积鼠标操作并将它们保存在-mouseUp:事件中,这是一个不错的选择。

通过简化过程,核心数据可能会有所帮助。 它使您可以快速创建对象并推迟将其保存到持久性存储中。 但是,如果安装CFRunLoopObserver ,则可以使用SQLite达到相同的效果,请等待直到没有事件并将一批数据写入数据库。

无论您选择什么,策略都是累积点击次数并批量保存。

最好的选择是将操作流式传输到文件系统上的文件。 然后,您可以将其保留在此处,或者如果确实需要,可以通过Core Data将其上传到SQLite。 这样做的原因是,如果对每个偶数都提交ManagedObjectContext ,则运行会非常缓慢。

使用: backingFile = [NSFileHandle fileHandleForUpdatingAtPath:eventsFilePath]; 使用[backingFile writeData:...];将事件附加到

请记住,关系数据库的主要目的是“搜索”数据。 如果您不打算搜索UI单击事件(我怀疑您会这样做),那么流式传输到文件是最好的选择。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM