这两天在负责公司项目某个功能的数据库方面的工作,第一次比较完整的实际操作了一遍从数据库的创建到数据的输入输出操作,然后把其中觉得要注意的地方摘记下来吧。
在项目中有一个这样的需求,就是需要在游戏初次运行的时候将某份数据表全部存储到数据库中去,一开始我是想以平时操作数据库的方式去处理。当提出这个想法然后跟同事商量的时候,同事跟我说用另外的一个方法以加快速度,因为我也不懂,就先叫他帮我查了下这个方法。。。。然后就开始操作了。
主要参考了两篇博客:
http://www.cnblogs.com/likebeta/archive/2012/06/15/2551466.html
http://blog.csdn.net/fansongy/article/details/8966730
因为对数据库不懂,所以一开始不明觉厉的,自己傻乎乎的把之前的数据库操作的代码段打断点然后去看具体的操作,然后一些字符串的具体格式也是通过打断点的方式慢慢了解的。
第一篇博客主要就是将解决插入大量数据造成数据库操作慢的方法,引用博主的一段话:sqlite 插入数据很慢的原因:sqlite在没有显式使用事务的时候会为每条insert都使用事务操作,而sqlite数据库是以文件的形式存在磁盘中,就相当于每次访问时都要打开一次文件,如果对数据进行大量的操作,时间都耗费在I/O操作上,所以很慢。解决方法是显式使用事务的形式提交:因为我们开始事务后,进行的大量操作的语句都保存在内存中,当提交时才全部写入数据库,此时,数据库文件也就只用打开一次。 主要意思就是平时一般的操作方法是用的时候就打开一次文件,如果对数据库的操作需求不是一次性产生大量的数据操作,那么本文主要要讨论的问题就不会有很大的影响,但是如果是有一次性大量的数据操作,那么再采用平时的那种方法可能就会产生效率不足的问题,因此就有必要去解决这一问题。
在实际操作过程中,如果完全是照着第一篇博客上讲的方法来操作的话,我碰到的问题就是会操作失败,具体怎么个操作失败主要有:找不到某行(后来发现是字符串格式的问题)、然后还有一个错误大概就是transaction is not activity,没有启动?没有啥啥啥?反正就是不在activity的状态。然后就第二篇博客登场了:
参考了第一篇博客和第二篇博客之后,我在项目中遇到的问题基本就解决了,需求也满足了,主要操作就是:
- 用第二篇博客提到的
这个来解决上文中遇到的第二个错误;int result = sqlite3_exec ( m_pDB , "begin transaction" , 0 , 0 , & errMsg );
- 用第一篇博客提到的
类似这样的操作来进行操作;string strSql; strSql+="begin;\n"; for (int i=0;i<100;i++) { strSql+="insert into fuck values(null,'heh');\n"; } strSql+="commit;";
- 最后用第一篇博客中的
实现数据存储到数据库中。nResult = sqlite3_exec(db,strSql.c_str(),NULL,NULL,&errmsg);
同事说,这个方法主要是先将数据加入到缓存中,然后一次性的加载到数据库中,这样就减少了数据库的I/O操作。
这里要注意,关于格式的问题:每一行数据都是要加入"insert into %s(这里是指table名) values("数据,以英文逗号分隔");\n" 这个的。比如说我们一次要操作一百条数据的加载,那么这个就是加载了100次,刚开始我用的时候就是以为只要第一次加就可以,结果一直出问题;然后就是values("数据")括号后面的数据的问题,一开始我照着另一个同事的代码来写,写成这个格式:("one='1',two='2',three='3'"),这样的,结果就报找不到'one'这一列数据的错误,后来发现其实只要这样写:("'1','2','3'")就可以了,照着在数据库中的位置,将数据输入就可以了;还有一个问题,我把" insert into %s(这里是指table名) values("数据,以英文逗号分隔");\"这个写成了" insert into %s(这里是指table名) ( one,two,three ) values("one='1',two='2',three='3'");\"/ " insert into %s(这里是指table名) ( one,two,three ) values("'1','2','3'");\ "这两种格式的,也是一直加载不了,这个也是犯过的错误。总的来说,通过这一具体的项目实际操作,对使用sqlite3是有一番认识了,学习了~!