Realm、WCDB与SQLite移动数据库性能对比测试

一、数据库介绍

SQLite 3比较常见不予赘述。

Realm是由Y Combinator孵化的创业团队开源出来的一款可以用于iOS(同样适用于Swift&Objective-C)和Android的跨平台移动数据库。目前最新版是Realm 2.0.2,支持的平台包括Java,Objective-C,Swift,React Native,Xamarin。

优势:兼顾iOS和Android两个平台;简单易用,学习成本低;提供了一个轻量级的数据库查看工具,开发者可以查看数据库当中的内容,执行简单的插入和删除数据的操作。

Realm支持事务,满足ACID:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。

WCDB是微信推出的一个高效、完整、易用的移动数据库框架,基于SQLCipher(an SQLite extension that provides 256 bit AES encryption of database files.),支持iOS,macOS和Android。易用,支持事务,可加密、损坏修复。

二、测试数据表结构

Student表。

字段:ID、name、age、money。

ID Name Age Money
主键 姓名 年龄 存款(建索引)


其中age为0~100随机数字,money为每一万条数据中,0~10000各个数字只出现一次。

三、测试数据

对于以下测试数据,只是给出一次测试后的具体数值供参考,经过反复测试后的,基本都在这个时间量级上。

这里测试用的是纯SQLite,没有用FMDB。

  • SQLite3

9万条数据基础上连续单条插入一万条数据耗时:1462ms。

已经建立索引,需要注意的是,如果是检索有大量重复数据的字段,不适合建立索引,反而会导致检索速度变慢,因为扫描索引节点的速度比全表扫描要慢。比如当我对age这个经常重复的数据建立索引再对其检索后,反而比不建立索引查询要慢一倍多。

已经设置WAL模式。

简单查询一万次耗时:331ms

dispatch 100个block来查询一万次耗时:150ms

  • realm

9万条数据基础上连续单条插入一万条数据耗时:32851ms。

注意,Realm似乎必须通过事务来插入,所谓的单条插入即是每次都开关一次事务,耗时很多,如果在一次事务中插入一万条,耗时735ms。

已经建立索引。

简单查询一万次耗时:699ms。

dispatch 100个block来查询一万次耗时:205ms。


  • WCDB

9万条数据基础上连续单条插入一万条数据耗时:750ms。

此为不用事务操作的时间,如果用事务统一操作,耗时667ms。

简单查询一万次耗时:690ms。

dispatch 100个block来查询一万次耗时:199ms。

  • 三者对比:

测试内容

Realm

WCDB

SQLite

用例数量

单条插入一万条

32851ms

750ms

1462ms

90000+10000

循环查询一万次

699ms

690ms

331ms

100000

100个block查询一万次

205ms

199ms

186ms

100000

由于Realm单次事务操作一万次耗时过长,图表中显示起来也就没有了意义,因此下面图中Realm的耗时是按照事务批量操作耗时来记录的,实际上WCDB的插入操作是优于Realm的。

从结果来看,Realm似乎必须用事务,单条插入的性能会差很多,但是用事务来批量操作就会好一些。按照参考资料[3]中的测试结果,Realm在插入速度上比SQLite慢,比用FMDB快,而查询是比SQLite快的。

而WCDB的表现很让人惊喜,其插入速度非常快,以至于比SQLite都快了一个量级,要知道WCDB也是基于SQLite扩展的。WCDB的查询速度也还可以接受,这个结果其实跟其官方给出的结果差不多:读操作基本等于FMDB速度,写操作比FMDB快很多。

四、Realm优缺点

  • 优点:

Realm在使用上和Core Data有点像,直接建立我们平常的对象Model类就是建立一个表了,确定主键、建立索引也在Model类里操作,几行代码就可以搞定,在操作上也可以很方便地增删改查,不同于SQLite的SQL语句(即使用FMDB封装的操作依然有点麻烦),Realm在日常使用上非常简单,起码在这次测试的例子中两个数据库同样的一些操作,Realm的代码只有SQLite的一半。

其实Realm的“表”之间也可以建立关系,对一、对多关系都可以通过创建属性来解决。

在.m方法中给“表”确定主键、属性默认值、加索引的字段等。

修改数据时,可以直接丢进去一条数据,Realm会根据主键判断是否有这个数据,有则更新,没有则添加。

查询操作太简单了,一行代码根据查询目的来获取查询结果的数组。

支持KVC和KVO。

支出数据库加密。

支持通知。

方便进行数据库变更(版本迭代时可能发生表的新增、删除、结构变化),Realm会自行监测新增加和需要移除的属性,然后更新硬盘上的数据库架构,Realm可以配置数据库版本,进行判断。

一般来说Realm比SQLite在硬盘上占用的空间更少。

  • 缺点:

Realm也有一些限制,需要考虑是否会影响。

类名长度最大57个UTF8字符。

属性名长度最大63个UTF8字符。

NSData及NSString属性不能保存超过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,如果服务器传来的有数组,那么需要我们自己取数据进行转换存储。

五、WCDB优缺点

    实际体验后,WCDB的代码体验非常好,代码量基本等于Realm,都是SQLite的一半,在风格上比Realm更接近于OC原本的风格,基本已经感受不到是在写数据库的SQL操作。并且其查询语句WINQ也写的很符合逻辑,基本都可以一看就懂,甚至不需要你了解SQL语句。整个开发流程下来非常流畅,除了配置环境时出了问题并且没有资料参考只能自己猜着解决外,代码基本是一气呵成写完完美运行的。

    • 缺点:

    最明显的缺点是其相关资料太少了,毕竟6月初才正式开源,大家可能还在体验阶段,不敢随便上项目,不过其提供了QQ群答疑,而且看了一下代码提交记录,更新很频繁,对于腾讯内部使用来说应该有问题会得到更快解决。

    贴一份评论:

    六、结

    测试过后,感觉还是比用FMDB方便很多,其中又以WCDB更为推崇,Realm其实也不错,如果是一些新创建的中小型工程,也可以尝试,WCDB刚开源不久,可能还会有一些坑,不过毕竟微信那边出品的,你问我支持不支持我当然是支持的。

    需要注意的是如果是老工程想换新数据库,那么需要注意一些数据库迁移的问题,这中间必然存在一些阵痛,此外,Realm和WCDB都会用到自有的Model类来作为表结构。

    刚刚上手,如果有哪里有问题或者疏漏,请多多指教。

    参考资料

    [1] Realm数据库 从入门到“放弃”:http://www.jianshu.com/p/50e0efb66bdf

    [2] Realm中文官方文档:https://realm.io/cn/docs/objc/latest/#section

    [3]移动端数据库新王者:realm(可以看看这篇博客的评论部分,看看坑)http://www.jianshu.com/p/2b4388cf2a2d

    [4] realm之于iOShttps://zhuanlan.zhihu.com/p/23556740

    [5] Core Data,FMDB,Realm性能测试http://suree.org/2015/09/29/DatabaseThink/

    [6] WCDB官方说明https://github.com/Tencent/wcdb/wiki

    [7] WCDB官方iOS使用说明https://github.com/Tencent/wcdb/wiki/iOS+macOS使用教程

    [8] WCDB官方与FMDB性能对比https://github.com/Tencent/wcdb/wiki/性能数据与Benchmark

    --------------------------------------------------------------------

    版权所有:http://blog.csdn.net/cloudox_

    版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


SQLite架构简单,又有Json计算能力,有时会承担Json文件/RESTful的计算功能,但SQLite不能直接解析Json文件/RESTful,需要用Java代码硬写,或借助第三方类库,最后再拼成insert语句插入数据表,代码非常繁琐,这里就不展示了。参考前面的代码可知,入库的过程比较麻烦,不能只用SQL,还要借助Java或命令行。SPL是现代的数据计算语言,属于简化的面向对象的语言风格,有对象的概念,可以用点号访问属性并进行多步骤计算,但没有继承重载这些内容,不算彻底的面向对象语言。...
使用Python操作内置数据库SQLite以及MySQL数据库。
破解微信数据库密码,用python导出微信聊天记录
(Unity)SQLite 是一个软件库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite 是在世界上最广泛部署的 SQL 数据库引擎。SQLite 源代码不受版权限制。本教程将告诉您如何使用 SQLite 编程,并让你迅速上手。.................................
安卓开发,利用SQLite实现登陆注册功能
相比大多数数据库而言,具有等优势,广泛应用于、等领域。
有时候,一个项目只有一个数据库,比如只有SQLite,或者MySQL数据库,那么我们只需要使用一个固定的数据库即可。但是一个项目如果写好了,有多个用户使用,但是多个用户使用不同的数据库,这个时候,我们就需要把软件设计成可以连接多个数据库的模式,用什么数据库,就配置什么数据库即可。4.Users实体类,这个实体类要和数据库一样的,形成一一对应的关系。11.Sqlite数据库,需要在代码里面创建数据库,建立表,再建立数据。8.我们开启MySQL数据库,然后进行调试,看程序的结果。2.安装SqlSugar。
基于Android的背单词软件,功能强大完整。
SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统。说白了就是使用起来轻便简单,
Android的简单购物车案例
SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它是D.RichardHipp建立的公有领域项目。它的设计目标是嵌入式的,而且已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如 Tcl、C#、PHP、Java等,还有ODBC接口,同样比起Mysql、PostgreSQL这两款开源的世界著名数据库...
Qt设计较为美观好看的登录注册界面(包含SQLite数据库以及TCP通信的应用)
SQLite是用C语言开发的跨平台小型数据库,可嵌入其他开发语言,也可在单机执行。SPL是用Java开发的跨平台的数据计算语言,可嵌入Java,可在单机执行,可以数据计算服务的形式被远程调用。两者的代码都是解释执行的。...
新建库.openDATA_BASE;新建表createtableLIST_NAME(DATA);语法:NAME关键字...<用逗号分割>删除表droptableNAME;查看表.schema查看表信息新建数据insertintoLIST_NAMEvalues();语法:CLASS,PARAMETER...,CLASS是类别,PARAMETER是参数<用逗号分割新建的
importsqlite3classDemo01:def__init__(self):self.conn=sqlite3.connect("sql_demo_001.db")self.cursor1=self.conn.cursor()self.cursor1.execute("select*fromtable_001wherename=?andid=?",('ssss&#0
 在客户端配置文件<configuration>节点下,添加:<connectionStrings>      <add name="localdb" connectionString="Data Source=config/local.db;Version=3;UseUTF16Encoding=True;" providerName="System.Data.SQLite.SQLiteFactory"/&g
提到锁就不得不说到死锁的问题,而SQLite也可能出现死锁。下面举个例子:连接1:BEGIN(UNLOCKED)连接1:SELECT...(SHARED)连接1:INSERT...(RESERVED)连接2:BEGIN(UNLOCKED)连接2:SELECT...(SHARED)连接1:COMMIT(PENDING,尝试获取EXCLUSIVE锁,但还有SHARED锁未释放,返回SQLITE_BUSY)连接2:INSERT...
SQLite是一种嵌入式数据库,它的数据库就是一个文件。由于SQLite本身是C写的,而且体积很小,所以,经常被集成到各种应用程序中,甚至在iOS和Android的App中都可以集成。Python就内置了SQLite3,所以,在Python中使用SQLite,不需要安装任何东西,直接使用。在使用SQLite前,我们先要搞清楚几个概念:表
设计思想————首先要确定有几个页面、和每个页面的大致布局由于是入门,我也是学习了不是很长的时间,所以项目比较low。。。。第一个页面,也就是打开APP的首页面:今天这个博客,先实现添加功能!:首先对主界面进行布局:其中activity_main.xml的代码为<?xmlversion="1.0"encoding="