热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

iOS面试数据库比较:SQLitevs.CoreDatavs.Realm(未完待续)

SQLiteSQLite是使用最多的数据库引擎,并且是开源的。它实现了无配置,无服务要求的事务数据库引擎。SQLite可以在MacOS-X,iOS,Android,Linux,和W

SQLite

SQLite是使用最多的数据库引擎,并且是开源的。它实现了无配置,无服务要求的事务数据库引擎。SQLite可以在Mac OS-X, iOS, Android, Linux, 和 Windows上使用,可以被存储在跨平台磁盘文件的完善的数据库

SQLite的优点:

  • 独立于服务器
  • 零配置
  • 多进程和线程下安全访问。
  • 在表中使用含有特殊数据类型的一列或多列存储数据。

Core Data (推荐第三方:MagicalRecord)

Core Data 是App开发者可以使用的第二大主要的IOS存储技术。你需要根据数据类型和数据量进行管理和存储,SQLite和Core Data都有它们各自的优缺点。Core Data 更加关注于对象而不是传统的表数据库方法。使用Core Data,你可以存储一个Objective-C类的对象,(Core Data本身就是基于sqlite的封装,所以它的底层仍然是使用sqlite进行存储数据的)

尽管它们从本质上不相同,但是CoreData:

  • 比SQLite使用更多的内存、更多的存储空间。
  • 比SQLite在取数据方面更快,不需要书写大量的sql语句。
  • CoreData 的数据模型升级兼容性较差,如果模型不对,会导致程序连起都起不来。虽然提供了模型升级代码,但是在客户端的管理模型版本管理也会相对复杂
  • CoreData的好处是集成化数据动态加载icloud,包括上层的数据显示,都不需要重新进行数据装配,可以直接使用
  • CoreData,建立的表没有主键,添加时都要自己处理。它不是关系型数据库,处理多对多的关系时比较麻烦。
  • CoreData的一个比较大的痛点是多人合作开发的时候,管理CoreData的模型需要很小心,尤其是合并的时候,他的data model是XML格式的,手动resolve比较烦
  • CoreData还有其他sql所不具备的优点,比如对undo的支持多个context实现sketchbook类似的功能,为ManagedObject优化的row cash等。
  • CoreData是支持多线程,但需要thread confinement的方式实现,使用了多线程之后可以最大化的防止阻塞主线程
  • CoreData自定义升级麻烦,并且效率非常低下,升级的版本变动很难跟踪,有着各种限制(抛弃它主要原因),有些限制直接导致了没法继续开发下去

iOS 8之前,Core Data没有批处理,批量插入,删除,更新效率要比sqlite低很多(这也正是很多程序员因为Core Data批量更新数据效率之低而不得不放弃使用它的原因)。 iOS8之后的Core Data 更新,正好的解决了这个痛点: Batch Updates. Batch Updates在处理大量数据时速度明显提升.Batch Updates可用于批量快速更新数据,Asynchronous Fetching可用于异步抓取海量数据,并可以通过NSProgress实现进度跟踪和取消。

Batch Updates

在CoreData中想要更新大量数据,我们往往要将大量修改后的NSManagedObject加载到NSManagedObjectContext中并保存,这会占用大量内存,试想想在iPhone这样的内存有限的移动设备上将是个灾难,数据有可能丢失。你可能会采取批处理的方式,即一小批一小批的更新NSManagedObject并保存到NSManagedObjectContext中,但这样会花费很多时间,用户体验较差。

为了解决这个问题,苹果在NSManagedObjectContext加入了一个新的方法:executeRequest:error:,它接受一个NSPersistentStoreRequest类型的参数,返回类型为NSPersistentStoreResult

关于NSPersistentStoreRequest有些人可能比较熟悉,它是NSFetchRequest、NSSaveChangesRequest、NSBatchUpdateRequestNSAsynchronousFetchRequest的基类。后两个类是这次iOS8新加的

NSPersistentStoreResult是一个新加入的类,它也是一个基类,而且是抽象类,这个类作为executeRequest:error:返回内容的父类,相当于一个接口,它目前有两个子类:NSPersistentStoreAsynchronousResultNSBatchUpdateResult`。

NSBatchUpdateResult对应着前面的NSBatchUpdateRequestNSBatchUpdateRequest,它有点像NSFetchRequest:它允许你指定一个想要更新数据的实体;也可以指定一个affectedStores,它存储了一个接受更新请求的NSPersistentStore数组。(其实它是NSPersistentStoreRequest的属性);它也有一个谓词属性来做更新的条件,它跟NSFetchRequest中的谓词一样强大和灵活,类似于SQL的where语句;它允许你指定想要更新的字段,通过propertiesToUpdate属性来描述字段更新,它是一个字段,key为NSPropertyDescription或属性名字符串,value为NSExpression或常量。

NSBatchUpdateResult,它有一个result属性和resultType属性,result中的内容跟resultType有关,可能是成功或者失败,有可能是每行被更新的ID,也可能是被更新的行数。

需要注意的是,由于NSBatchUpdateRequest并不会先将数据存入内存,而是直接操作数据库,所以并不会引起NSManagedObjectContext的同步更新,所以你不仅需要获取NSBatchUpdateResult然后刷新NSManagedObjectContext对应的数据和UI界面,还需要保证更新后的数据满足数据库模型上的validation,因为NSManagedObjectContext没有感知Batch Updates,一些数据验证工作就落在了程序员的身上(你需要写一段代码验证更新后的数据是合法的,用户可不希望在跑步APP上看到自己今天跑步里程是个负数)。一旦有非法数据录入数据库,下次加载并修改NSManagedObject的时候就会导致数据验证失败。除了上面提到的这些,还要注意Batch Updates对数据库的操作是乐观锁,也就是假定很少会发生同时存取同一块数据的情况,所以你需要制定一个合理的”merge”策略来应付因同时更新数据产生的冲突。

Batch Updates的优势在于其效率,在处理上万条数据的时候,它执行的时间跟SQL语句执行时间相当。

Asynchronous Fetching

Asynchronous Fetching 的加入依然是为了解决CoreData读取海量数据所带来的问题。通过使用 Asynchronous Fetching,我们可以在抓取数据的同时不阻塞占用 NSManagedObjectContext,并可以随时取消抓取行为,随时跟踪抓取数据的进度。

设想我们平时用NSFetchRequest抓取数据的时候,我们会先用NSManagedObjectContextexecuteFetchRequest:error:方法传入一个NSFetchRequest,然后请求会被发送到NSPersistentStore,然后执行一段时间后返回一个数组,在NSManagedObjectContext更新后,这个数组被当做executeFetchRequest:error:的返回值返回到我们这里。

Asynchronous Fetching则不同,当我们将一个NSAsynchronousFetchRequest对象传入executeRequest:error:方法后会立即返回一个“未来的”NSAsynchronousFetchResultNSAsynchronousFetchRequest初始化时需要传入两个参数赋值给属性:

completionBlock属性,允许我们在抓取完成后执行回调block;
fetchRequest属性,类型是NSFetchRequest。也即是说虽然是异步抓取,其实我们用的还是以前的NSFetchRequest,当NSFetchRequest抓取结束后会更新NSManagedObjectContext,这也就意味着NSManagedObjectContext的并发类型只能是NSPrivateQueueConcurrencyTypeNSMainQueueConcurrencyType
于是当我们用NSAsynchronousFetchRequest抓取数据时,我们会先用NSManagedObjectContextexecuteRequest:error:方法传入一个NSAsynchronousFetchRequest,这个方法在NSManagedObjectContext上执行时,NSManagedObjectContext会立即制造并返回一个NSAsynchronousFetchResult,同时NSAsynchronousFetchRequest会被发送到NSPersistentStore。你现在可以继续编辑这个NSManagedObjectContext中的NSManagedObject,等到NSPersistentStore执行请求完毕时会将结果返回给NSAsynchronousFetchResultfinalResult属性,更新NSManagedObjectContext,执行NSAsynchronousFetchRequest的回调block。

Realm

Realm 是个新技术。Realm比前面提到的数据库解决方案更快,更高效。它是一个跨平台的移动数据库,不仅支持Android,iOS还支持macOS,Linux,ReactNative和Xamarin。

最棒的是你通过两行代码就可以处理所有的工作。Realm相比于SQLite和Core Data而言,更易于安装并且运行的更快。

如果你正在设计一款面向很多用户,有很多记录的程序,那么你从设计的一开始就需要特别注意它的可扩展性。Realm在这方面非常出色,并且能够让你快速的操作大量数据。

想要开始使用Realm,你所需要的仅仅是最低iOS 8或者OS X 10.9的系统。早期版本的系统并不支持本地存储与数据库的全新的简单解决方案。

Realm最主要的优势是:

  • 绝对免费
  • 快速,简单的使用
  • 没有使用限制(待定)
  • 为了速度和性能,运行在自己的持久化引擎上
  • 代码量少,几乎仅仅相当于sqlite的一半代码量

缺点:

  • 类名长度最大57个UTF8字符。
  • 属性名长度最大63个UTF8字符。
  • NSDataNSString属性不能保存超过16M数据,如果有大的可以分块。
  • 对字符串进行排序以及不区分大小写查询只支持”基础拉丁字符集”、”拉丁字符补充集”、”拉丁文扩展字符集 A” 以及”拉丁文扩展字符集 B”(UTF-8 的范围在 0~591 之间)。
  • 多线程访问时需要新建新的Realm对象。
  • Realm没有自增属性。也就是说对于我们习惯的自增主键,如果确实需要,我们要自己去赋值,如果只要求独一无二, 那么可以设为[[NSUUID UUID] UUIDString],如果还要求用来判断插入的顺序,那么可以用Date。
  • Realm支持以下的属性类型:BOOL、bool、int、NSInteger、long、long long、float、double、NSString、NSDate、NSData 以及 被特殊类型标记的NSNumber,注意,不支持集合类型,只有一个集合RLMArray,如果服务器传来的有数组,那么需要我们自己取数据进行转换存储。

读取性能测试

《iOS面试-数据库比较:SQLite vs. Core Data vs. Realm(未完待续)》 对比图
图片来源


推荐阅读
  • 恶意软件分析的最佳编程语言及其应用
    本文介绍了学习恶意软件分析和逆向工程领域时最适合的编程语言,并重点讨论了Python的优点。Python是一种解释型、多用途的语言,具有可读性高、可快速开发、易于学习的特点。作者分享了在本地恶意软件分析中使用Python的经验,包括快速复制恶意软件组件以更好地理解其工作。此外,作者还提到了Python的跨平台优势,使得在不同操作系统上运行代码变得更加方便。 ... [详细]
  • 本文介绍了Java集合库的使用方法,包括如何方便地重复使用集合以及下溯造型的应用。通过使用集合库,可以方便地取用各种集合,并将其插入到自己的程序中。为了使集合能够重复使用,Java提供了一种通用类型,即Object类型。通过添加指向集合的对象句柄,可以实现对集合的重复使用。然而,由于集合只能容纳Object类型,当向集合中添加对象句柄时,会丢失其身份或标识信息。为了恢复其本来面貌,可以使用下溯造型。本文还介绍了Java 1.2集合库的特点和优势。 ... [详细]
  • 如何在服务器主机上实现文件共享的方法和工具
    本文介绍了在服务器主机上实现文件共享的方法和工具,包括Linux主机和Windows主机的文件传输方式,Web运维和FTP/SFTP客户端运维两种方式,以及使用WinSCP工具将文件上传至Linux云服务器的操作方法。此外,还介绍了在迁移过程中需要安装迁移Agent并输入目的端服务器所在华为云的AK/SK,以及主机迁移服务会收集的源端服务器信息。 ... [详细]
  • 解决github访问慢的问题的方法集锦
    本文总结了国内用户在访问github网站时可能遇到的加载慢的问题,并提供了解决方法,其中包括修改hosts文件来加速访问。 ... [详细]
  • svnWebUI:一款现代化的svn服务端管理软件
    svnWebUI是一款图形化管理服务端Subversion的配置工具,适用于非程序员使用。它解决了svn用户和权限配置繁琐且不便的问题,提供了现代化的web界面,让svn服务端管理变得轻松。演示地址:http://svn.nginxwebui.cn:6060。 ... [详细]
  • Java和JavaScript是什么关系?java跟javaScript都是编程语言,只是java跟javaScript没有什么太大关系,一个是脚本语言(前端语言),一个是面向对象 ... [详细]
  • YOLOv7基于自己的数据集从零构建模型完整训练、推理计算超详细教程
    本文介绍了关于人工智能、神经网络和深度学习的知识点,并提供了YOLOv7基于自己的数据集从零构建模型完整训练、推理计算的详细教程。文章还提到了郑州最低生活保障的话题。对于从事目标检测任务的人来说,YOLO是一个熟悉的模型。文章还提到了yolov4和yolov6的相关内容,以及选择模型的优化思路。 ... [详细]
  • Android源码深入理解JNI技术的概述和应用
    本文介绍了Android源码中的JNI技术,包括概述和应用。JNI是Java Native Interface的缩写,是一种技术,可以实现Java程序调用Native语言写的函数,以及Native程序调用Java层的函数。在Android平台上,JNI充当了连接Java世界和Native世界的桥梁。本文通过分析Android源码中的相关文件和位置,深入探讨了JNI技术在Android开发中的重要性和应用场景。 ... [详细]
  • NotSupportedException无法将类型“System.DateTime”强制转换为类型“System.Object”
    本文介绍了在使用LINQ to Entities时出现的NotSupportedException异常,该异常是由于无法将类型“System.DateTime”强制转换为类型“System.Object”所导致的。同时还介绍了相关的错误信息和解决方法。 ... [详细]
  • 本文介绍了RxJava在Android开发中的广泛应用以及其在事件总线(Event Bus)实现中的使用方法。RxJava是一种基于观察者模式的异步java库,可以提高开发效率、降低维护成本。通过RxJava,开发者可以实现事件的异步处理和链式操作。对于已经具备RxJava基础的开发者来说,本文将详细介绍如何利用RxJava实现事件总线,并提供了使用建议。 ... [详细]
  • GPT-3发布,动动手指就能自动生成代码的神器来了!
    近日,OpenAI发布了最新的NLP模型GPT-3,该模型在GitHub趋势榜上名列前茅。GPT-3使用的数据集容量达到45TB,参数个数高达1750亿,训练好的模型需要700G的硬盘空间来存储。一位开发者根据GPT-3模型上线了一个名为debuid的网站,用户只需用英语描述需求,前端代码就能自动生成。这个神奇的功能让许多程序员感到惊讶。去年,OpenAI在与世界冠军OG战队的表演赛中展示了他们的强化学习模型,在限定条件下以2:0完胜人类冠军。 ... [详细]
  • macOS Big Sur全新设计大版本更新,10+个值得关注的新功能
    本文介绍了Apple发布的新一代操作系统macOS Big Sur,该系统采用全新的界面设计,包括图标、应用界面、程序坞和菜单栏等方面的变化。新系统还增加了通知中心、桌面小组件、强化的Safari浏览器以及隐私保护等多项功能。文章指出,macOS Big Sur的设计与iPadOS越来越接近,结合了去年iPadOS对鼠标的完善等功能。 ... [详细]
  • 如何实现JDK版本的切换功能,解决开发环境冲突问题
    本文介绍了在开发过程中遇到JDK版本冲突的情况,以及如何通过修改环境变量实现JDK版本的切换功能,解决开发环境冲突的问题。通过合理的切换环境,可以更好地进行项目开发。同时,提醒读者注意不仅限于1.7和1.8版本的转换,还要适应不同项目和个人开发习惯的需求。 ... [详细]
  • 2016 linux发行版排行_灵越7590 安装 linux (manjarognome)
    RT之前做了一次灵越7590黑苹果炒作业的文章,希望能够分享给更多不想折腾的人。kawauso:教你如何给灵越7590黑苹果抄作业​zhuanlan.z ... [详细]
  • 本文介绍了H5游戏性能优化和调试技巧,包括从问题表象出发进行优化、排除外部问题导致的卡顿、帧率设定、减少drawcall的方法、UI优化和图集渲染等八个理念。对于游戏程序员来说,解决游戏性能问题是一个关键的任务,本文提供了一些有用的参考价值。摘要长度为183字。 ... [详细]
author-avatar
晓晓鱼美人
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有