【问题标题】:method for performing lot of read/write operations on a database对数据库执行大量读/写操作的方法
【发布时间】:2012-04-16 15:55:02
【问题描述】:

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

谢谢

阿吉特

【问题讨论】:

    标签: objective-c xcode sqlite core-data


    【解决方案1】:

    如果您只是按顺序保存它们,然后以相同的顺序读回它们,那么常规文件可能是最好的。但是,如果您要执行其他任何操作,请使用 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];
        }];
    }
    

    或者,您可以将其设为兄弟,在这种情况下,所有数据库都不会在主线程上运行(UIManagedDocument 的主上下文在主线程上运行,因此在上述情况下,主线程将将对象传递给执行保存的上下文)。但是,在这种情况下,您的 document.managedObjectContext 必须执行 FETCH 才能获取放入数据库的任何内容。但是,它在存储过程中不会导致主线程的性能。

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

    现在,这些将进入数据库,但如果您的文档想要查看它们,则必须执行提取。根据您的用例选择最好的。不过,我想你会很好地处理第一个例子。

    【讨论】:

      【解决方案2】:

      如果有很多点击,你肯定不希望将它们中的每一个单独写入数据库。或许,累积鼠标操作并将其保存在-mouseUp: 事件中会是一个不错的折衷方案。

      Core Data 可以通过简化程序来提供一些帮助。它使您可以非常快速地创建对象并推迟将它们保存到持久存储中。但是如果你安装一个CFRunLoopObserver,你可以用SQLite达到同样的效果,等到没有事件,然后将一批数据写入数据库。

      无论你选择什么,策略都是累积点击并分批保存。

      【讨论】:

        【解决方案3】:

        您最好的选择是将您的操作流式传输到文件系统上的文件中。然后你可以把它留在那里,或者如果你真的需要,通过 Core Data 将它上传到 SQLite。这样做的原因是,如果你为每个偶数提交 ManagedObjectContext,事情会运行得非常慢。

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-04-07
          • 2012-09-18
          • 2011-08-17
          • 1970-01-01
          • 1970-01-01
          • 2014-08-01
          • 1970-01-01
          相关资源
          最近更新 更多