sqlite的快速插入

来源:互联网 发布:淘宝宝贝视频怎么制作 编辑:程序博客网 时间:2024/05/17 21:34
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有重复怎么办,在多线程下的线程安全问题等等。

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

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

原创粉丝点击