时间:2021-07-01 10:21:17 帮助过:61人阅读
注意:--target后面的内容与你使用的Electron的版本要一致
SQLite的数据库表结构
CREATE TABLE [message]( [id] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE, [msg_from] VARCHAR(80), [msg_to] VARCHAR(80), [msg] TEXT, [create_time] DATETIME);
这里主要模拟了一个IM应用的消息表
SQLite的测试代码如下
let { app } = require(‘electron‘); let messages = require(‘./messages‘) let path = require(‘path‘); let filename = path.join(app.getPath(‘userData‘), ‘db.db‘); let db = require(‘knex‘)({ client: ‘sqlite3‘, useNullAsDefault: true, connection: { filename }, timezone: ‘UTC‘, dateStrings: true }); let start = async () => { let startTime = Date.now(); for (let i = 0; i < 10; i++) { let index = i % 2; await db(‘message‘).insert(messages[index]); } //let arr = await db(‘message‘).whereBetween(‘id‘,[1600,9600]); //await db(‘message‘).whereBetween(‘id‘,[0,10000]).del(); //await db(‘message‘).update({msg:`天接云涛连晓雾。!!!`}).whereBetween(‘id‘,[2600,2800]); let endTime = Date.now(); console.log(endTime - startTime); } module.exports = { start }
其中用到了messages是两个消息体的JSON对象,代码如下:
let messages = [{ msg_from: ‘辛弃疾‘, msg_to: ‘刘晓伦‘, msg: `醉里挑灯看剑,梦回吹角连营。 八百里分麾下炙, 五十弦翻塞外声, 沙场秋点兵。 马作的卢飞快, 弓如霹雳弦惊。 了却君王天下事, 赢得生前身后名。 可怜白发生!`, create_time: new Date() }, { msg_from: ‘李清照‘, msg_to: ‘刘晓伦‘, msg: `天接云涛连晓雾。 星河欲转千帆舞。 仿佛梦魂归帝所, 闻天语, 殷勤问我归何处。 我报路长嗟日暮, 学诗谩有惊人句。 九万里风鹏正举。 风休住, 蓬舟吹取三山去!`, create_time: new Date(), }]; module.exports = messages
IndexedDB的测试代码是在渲染进程中执行的,代码如下:
let Dexie = require(‘Dexie‘); const db = new Dexie(‘db‘); db.version(1).stores({ message: ‘++, message_from, message_to,msg,create_time‘ }); window.onload = async () => { let startTime = Date.now(); for (let i = 0; i < 10000; i++) { let index = i % 2; await db.message.add(messages[index]); } //let arr = await db.message.where("id").between(1000, 9000).delete(); let endTime = Date.now(); console.log(endTime - startTime); }
[ { name: ‘SQLite‘, data: [526,551,536, 897, 530, 509, 534,538] }, { name: ‘IndexedDB‘, data: [333,221,167, 169, 336, 313, 187,169] } ]
[ { name: ‘SQLite‘, data: [5669,7488,7443,7033,7231,7537,7563] }, { name: ‘IndexedDB‘, data: [2140,2111,1755,1716,2126,1757,2006] } ]
[ { name: ‘SQLite‘, data: [202415,158451,144221,143993] }, { name: ‘IndexedDB‘, data: [20028,18979,21013,18738] } ]
[ { name: ‘SQLite‘, data: [158,268,306,162,149,159] }, { name: ‘IndexedDB‘, data: [56,99,47,49,53,52] } ]
[ { name: ‘SQLite‘, data: [47,55,56,60] }, { name: ‘IndexedDB‘, data: [62,54,58,55] } ]
已存在10000行数据的前提下,删除200行数据(毫秒):18、16、18
已存在10000行数据的前提下,删除8000行数据(毫秒):18
已存在10000行数据的前提下,删除10000行数据(毫秒):18
已存在10000行数据的前提下,删除200行数据(毫秒):21、10、10
已存在10000行数据的前提下,删除8000行数据(毫秒):58
已存在10000行数据的前提下,删除10000行数据(毫秒):30
已存在10000行数据的前提下,更新1行数据(毫秒):8、8、8、9、8、8
已存在10000行数据的前提下,更新100行数据(毫秒):30、30、28、30、30
已存在10000行数据的前提下,更新1行数据(毫秒):11、8、7、7、8、8
已存在10000行数据的前提下,更新100行数据(毫秒):15、14、12、10、13
结论:插入数据两个数据库性能相差巨大,IndexedDB显然优于SQLite,检索,删除,更新操作两个数据库性能相差无几
分析:
SQLite有双写入机制,IndexedDB应该是有多级缓存写入机制(待考),显然多级缓存写入机制更优秀
因为是Electron工程下完成此对比,所以Js经Electron转到Node.js再转到SQLite的Node module最后才转到SQLite的C代码,这个过程可能是性能损耗的一大主要原因
最后:
综合对比下来,大型Electron应用更推荐使用IndexedDB来存储业务数据
(由于有Dexie的加持,IndexedDB操作也足够简单,所有中小型应用也是不错的选择)
如果你需要加密客户端数据,SQLite还需要外套sqlcipher这样的加密库,所以性能上会有更多损耗,
然而IndexedDB本身就有一层加密逻辑(可以说只能防君子,防不了小人),虽然简单,但聊胜于无。
欢迎大家购买我的新书《Electron实战:入门、进阶与性能优化》,
书里还有更多有趣的内容,
大家感兴趣可以加QQ群949674481交流。
当当:http://product.dangdang.com/28547952.html;
京东:https://item.jd.com/12867054.html
大型Electron应用本地数据库技术选型
标签:qq群 交互 索引 对象 article 个性 opener tab 特殊