加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

sqlite的快速插入

发布时间:2020-12-12 20:14:34 所属栏目:百科 来源:网络整理
导读:sqlite的插入速度是比较慢的,在同时需要插入大量的数据时,一般采用将多条插入操作放入同一事务中处理,这样速度会有一个大的提升。 但是,这样插入有个问题 1、如果其中一条插入失败了,则整个事务就会失败,一条也插不进。 这个问题可以通过insert or igno
sqlite的插入速度是比较慢的,在同时需要插入大量的数据时,一般采用将多条插入操作放入同一事务中处理,这样速度会有一个大的提升。
但是,这样插入有个问题
1、如果其中一条插入失败了,则整个事务就会失败,一条也插不进。
这个问题可以通过insert or ignore into...来忽略掉失败的插入。这样,如果某一条失败后还可以继续插入。
这样又引入了另一个问题:我们怎么知道哪些是插入成功的,哪些是插入失败的呢?
用sqlite3_exec里的回调?但是该回调在inser操作时并不会被调用。
利用sqlite3_update_hook函数?sqlite可以通过sqlite3_update_hook函数注册一个回调函数,当数据库上有增,删,改时,该回调会被调用。如果是插


入成功,就会返回该条目的rowid,如果失败该函数不会被调用。但是该id是插入成功时才由数据库分配,我们预先并不知道。
sqlite还有另一个函数sqlite3_create_function,他可以自定义一个函数,在sql语句里调用该函数。
我们可以利用这个函数来做一些文章。
我们为一个table1注册一个函数fun1,同时为该table写一个触发器,当有插入时触发。
drop trigger if exists table1_triger1;
create trigger if not exists table1_triger1;
after insert on table1
for each row
begin
select fun1
(new.Field1,new.Field2,new.Field3);
end;
该触发器的作用是插入成功后将该条目的一些字段当做参数传入到fun1去


fun1函数应是这样的
void fun1(void *context,int argc,void **argv)
{
Entry entry;
entry.Field1 = (const char*)sqlite3_value_text((sqlite3_value*)argv[1]);
entry.Field2 = (const char*)sqlite3_value_text((sqlite3_value*)argv[2]);
entry.Field3 = (const char*)sqlite3_value_text((sqlite3_value*)argv[3]);


Map[entry.Field1] = entry;
}
可以看到,这里,我们将插入成功的条目做了一个记录,因为使用的map,因此要依赖一个事实:条目里需有一个field是唯一的。
这样,当插入完毕后再和插入前的条目比对,就可以得到插入成功的条目,失败的条目了。
实际使用时还有一些细节问题要注意。
比如如何来比对条目,条目的field有重复怎么办,在多线程下的线程安全问题等等。

以上问题在我实际的代码里是解决了的,这里主要讲的是一个大体的思路。

测试下来速度还是很不错的

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读