个信个人使用总结

时间:2022-12-05 06:44:03 作者:花锄 其他个人工作总结 收藏本文 下载本文

“花锄”通过精心收集,向本站投稿了12篇个信个人使用总结,下面小编给大家带来个信个人使用总结,希望能帮助到大家!

篇1:个信个人使用总结

个信个人使用总结 -个人工作总结

个信是一款基于手机通讯录,跨网络(移动和联通)的免费短信软件。使用价值:l通过个信,可以与通讯录中已安装个信的用户,免费互发信息,包含文本和图片;l备份通讯录,防止手机丢失后,通讯录同时遗失。l与web版的结合,发挥电脑的优势。实现机制:挣脱gprs的束缚,基于互联网通讯信息业务。当对方没有安装个信时,互联网通讯无法建立,则走gprs网络,按照正常短信计费。定位理解:1、核心竞争力值多少?个信的核心竞争优势是短信免费,①在联系方式越来越多的今天,在手机越来越智能的趋势下,短信的地位已经越来越不重要了。②现在手机都有包月功能,包短信条数,除了春节那天,你一个月花费多少短信费?在意的人有多少?2、3G领域的即时通讯还那么重要吗?QQ创建了互联网领域的即时通讯的帝国,3G领域里,即时通讯还那么重要吗?手机本身基本的业务,消减了即时通讯多大的价值?而手机用户期待的,还是基本的短信和彩信沟通方式嘛?3、手机社交必须要依托短信功能吗?现在围绕人们的社交圈:①真实的社交圈(手机通讯录算是一个反馈);②即时通讯社交圈;③SNS社交圈;④微博社交圈。以上4者,智能手机已经实现了,“1机4圈”的覆盖,个信似乎就显得无足轻重了。总结:个信要想长足发展,需要依托3G信息通讯功能有更具价值的'服务提供。Kik的成功在哪里,不好妄下结论,但是在中国,只是目标单纯,未必能解决问题。我期望的功能:1、对手机通讯录有更强的补充:譬如更友好的分类管理、通讯录无法满足的一些信息的记录和补充;可以把通讯录一个或一些联系方式便捷的发送或者共享给某人或者某些人;2、资源共享方面:可以把手机内的文件或者图片,方便的发送给某人或者某些人。3、个性服务:短信定时发送,生日短信自动发送等功能。定位:手机,除了语音通讯外的信息通讯和共享平台。也可以考虑与互联网服务的结合,譬如在微博火爆的今天,与所有微博账号的绑定,一键发布等。应用环境:电脑:windows XP;手机:乐phone Adriod V1.6安装个信朋友发来邀请短信,短信中提供下载地址,短信内容倒是很直接:“快安这个,以后和我发短信就免费了。”诉求表达的很到位,到个信的网站,找到我的手机供应商的名字,点击进去,发现有三个完全一样的【3GW100(乐Phone)】,我犹豫了一下,估计可能是乐phone不同版本的安装程序,源于我一直都没有刷系统,所以应该是第一个吧,下载,安装,提示无法安装。那下载最后一个吧,安装,提示无法安装。算了,还是按平台找吧,点击【Android】,下载V1.6版本,安装成功。个信客户端:1、安装完的个信可以自动导入手机短信的所有内容,但是对于是手机号码还是显示这个号码我标注的名字,就比较随机了,而且每次登录看到的并不完全一样。2、通信界面仿照iphone,iphone的成功无法复制,iphone的表现形式也未必就是最好的,也许他适用于iphone,但却未必适合你。3、个信和手机自带的短信功能之间,“是否已阅读”的状态不互通,导致我在使用个信过程中,需要两个都去看,才能取消状态很麻烦。4、每次发短信,他都提示“你又省了一毛钱”。中国人讲究面子问题,好似用个信就为了剩那几块钱,这多不好。实际上,这种提示一次就够了,第一次的时候。5、频繁的信息发不出去现象,而且频繁的一发信息,屏幕就置灰,信息无法发送,不知道是不是我手机系统的问题。6、备份通讯录,应该是个信比较重要的一个功能,可是备份了一下午,无论是从手机端请求,但是从web端发起,都没有成功,也没有进度显示,也没有问题提示,最后都不了了之。MSN空间完美搬家到新浪博客!

篇2:微信使用技巧总结

微信使用技巧总结

现在越来越多的人都会使用微信了,大多数人都是用微信来进行聊天、交友、游戏、品牌展示等。但是,很多人在使用微信的时候,缺乏了一些技巧。所以,现在就来和大家介绍一下微信的使用技巧。

1、查找聊天记录

经常使用微信聊天的朋友,记录一多就很容易“断片”了,不知道刚刚到底说的是什么。所以,我们可以来查找某条特定的聊天记录。进入聊天信息后,点击“查找聊天内容”即可搜索查找某条聊天记录。

2、拒绝朋友圈信息推送

在朋友圈中,我们可以共享一些图片或者是文字信息。但是若我们不想要关注这些事情呢?不想要查看到某个人的信息呢?ok,在朋友圈中长按TA的头像,召唤出“设置朋友圈权限”,开始不看他(她)的照片后,朋友圈中将没有TA最新发布的信息了。若是加入朋友圈黑名单,则我们自己分享的信息,TA看不到。

3、查看当前好友数量

通过“设置——功能——群发助手功能”,点击开始群发——新建群发,全选就可以查看通讯录中究竟是有多少好友,统计的数字也包含了已经删除了/拉黑了你的.好友。

4、查看当前微信会话总数与上次微信聊天记录

通过设置功能中的“通用”,点击“聊天记录迁移”的“上传”功能,系统会统计当前聊天会话总数,我们可以看到现在有多少人在和自己聊天,同时还可以上传保存聊天记录。

5、独立密码设置

微信作为腾讯旗下的产品有着很好的兼容性,我们只需要有QQ号,就可以作为微信账号使用。但是,问题也来了,若是指定我们的QQ密码的时候,也可以轻而易举的查看我们的通讯录了。其实,只需要微信在“设置——我的账号”中,设置“独立密码”即可。

6、夜间免打扰

在联网状态下,微信会自动在后台接受信息。若是在白天问题还不大,要是在深夜的时候入睡还有推送信息的话,就有一点吵人了。所以,我们可以在“设置——通用——新信息通知”中设置“信息免打扰”,通过开启夜间免打扰模式,就可以在联网的状态下,也不会吵到我们睡觉了。

7、微信聊天记录恢复

若是我们遇到不小心删除了微信聊天记录的情况的话,可以将手机连接到电脑上,借助顶尖微信聊天记录恢复器查看以及恢复微信聊天记录。

篇3:后勤个人月总结个人总结

时间过得真快,转眼间一年又在忙忙碌碌中过去了,现在又到了总结过去,展望未来的时候了。回顾一个学年来的工作,虽然取得一些成绩但于在座各位分不开,没有你们的支持和帮助我的工作将无开展,在此我想对在家说一声‘谢谢,你们辛苦了’。我所做的工作,只是尽了一个教育工作者应尽的职责,下面我便将自己这一年来所做的一些工作进行总结:

一、在政治思想方面

我坚决拥护党的领导,热爱党的教育事业,时刻不忘一个共产党员所应担负的职责。平时我认真学习,积极参加学校组织的政治、业务学习,树立教书育人,全心全意为全体师生服务的思想,扎扎实实地开展工作。

作为一个后勤人员,要多干实事,少说空话。本年度在后勤工作方面主要做了以下几方面的工作:第一,保障学校教育教学工作有序正常开展,努力做好教师的后勤部长。学校的中心工作的教学,我作为主管后勤服务的总务主任,一定要保证学校各项设施、设备的正常运转。学校很多设施虽然比较新,但毛病却不可避免。比如厕所里的高位水箱,教室里的电灯、电扇,还有一些电教设备,如录音机、投影仪等。我放弃休息时间,自己对这些设施设备进行维修,虽然苦一点,累一点,但为学校节省了不少开支。看着师生们能够正常地使用这些设施、设备,我感到的高兴。

二、创设良好优美的校园环境,努力搞好学校的环境卫生工作

是我这个总务主任有不可推懈得责任,我们的学校比较大,对校园环境卫生的整治是件大事,也是件难事。本学期开学初,根据学校的实际情况和学生的年龄特点,我首先把校园划分为若干个区域,包干给各班负责。每天,我都要在校园的各个卫生包干区进行,发现问题及时进行处理。经过我和全校师生的共同努力,校园环境面貌良好,给上级领导和来宾留下了深刻的印象。其次,进一步搞好学校的绿化工作。平时我组织人员定期给学校绿化带进行除草,给花草树木进行施肥、除虫、浇水,有时我自己利用星期天休息的时间,亲自来干。

三、进一步完善食堂管理制度,强化质量意思和服务意识,努力为全校师生提供优质高效的服务

在食堂管理员庄伟民教师的配合下,本学年中学生在校就餐人数逐渐趋于稳定,而且人数逐月递增。食堂管理井然有序,食堂工作人员朴实勤劳,有责任心。工作人员能按食堂操作规则,并能做好清洗消毒方面的工作,真正使在校用餐的师生吃上了放心饭、放心菜。食堂工作人员以他们的吃苦耐劳的精神和全心全意为师生服务的思想,赢得了广大师生的认可。本学年为进一步完善食堂制度,提高食堂工作人员的服务质量,我组织他们学习了有关卫生方面的条例和知识,和他们签订了合同,使他们进一步明确了自己的职责。加强监督,严把进货关。食堂每次买菜,我都亲自参与,既要购买卫生新鲜的菜,又要考虑菜蔬的价格,因此我们每星期都要到xx塘买菜。虽然跑的路多一些,人累一些,但是买的菜既便宜又能保证质量,我认为这也是值得的。为了合理使用好食堂的经费,进一步完善了食堂财务制度。能做到食堂帐目分明,帐、物、钱分别管理,从物品入库到领用,都要进行登记,做到帐、物、钱相符。同时每月认真审核,使集体食堂越办越好。

本学年本人除了继续做好后勤服务工作外,还担任了一年级组的年级组长。平时与年级组的老师搞好团结,及时将学校有关通知、工作安排传达给老师,同时也将老师对学校的意见和建议反映给校长听,起好桥梁作用。在教师考核方面我坚持做到公平、公正、公开,每个月都比较全面地对本年级组的老师进行评分。

由于本人水平有限,对后勤管理还不够精通,很多事情做得还不尽人意。主要原因是思想上还存在着一些问题,办事能不强,思路不宽,还存在着一些依敕心理,希望广大教师能在今后的工作中帮助我,督促我,使我在工作中少走弯路,我也将认真学习先进的管理方法,适应当前教育发展的新形势,为了学生,我们将共同努力。

篇4:数码相机15个使用经验

1. 三大数码照片格式

数码相机三大存储格式就是RAW、TIFF和JPEG,了解这三种格式的特点您才能够在拍摄时正确地选择存储格式,

首先是高级数码相机支持的RAW图像格式,这是一种将数码相机感光元件成像后的图像数据直接存储的格式,不经过压缩也不会损伤数码照片的质量,而且由于存储的是感光元件的原始图像数据,以后您还可以对图像的正负两级的曝光调整、色阶曲线、白平衡、锐利度等参数进行调整;缺点是RAW需要特殊的软件来处理,同时在拍摄时,数码相机的液晶屏幕上只能看到RAW文件的专门为预览提供的JPEG副本,而且为了避免浪费存储空间,这个副本的压缩比大,图像质量比较差。这也是部分数码相机用户误以为RAW格式的效果比JPEG还差的原因。

如果拍摄的数码照片是用于印刷出版,那么只有RAW和采用无损压缩格式的 TIFF格式的照片的效果会比较理想。TIFF格式是目前大部分数码相机都支持的格式,其优点是质量好而且兼容性比RAW高,不会受到处理软件的限制,但 TIFF格式的缺点也非常明显,那就是图像的文件大而且在存储时也需要更多的时间。

JPEG是三种格式中“体积”最小的,如果您追求更快的存储速度和更高的软件兼容性,那么JPEG是最好的选择。但需要注意,JPEG是一种有损压缩格式,也就是它在压缩的过程中丢掉了原始图像的部分数据,而且这些数据是无法恢复的。

使用了数码变焦拍摄并存储为JPEG格式的照片,数码变焦的效果优于后期电脑软件的插值放大效果,而对于无损的TIFF或RAW格式图像而言,后期软件处理比数码变焦的效果要好一些。

2. 正确使用RAW格式

高级数码相机支持使用RAW图像格式,但是不少用户都不太明白应该怎么去使用它。这种原始图像数据存储格式类似传统相机的数字底片,是专业摄影师的首选格式。如果您也想使用单反数码相机代替专业传统胶片相机,那么您也会需要这种能够最大限度地保留了成像时的各项细节和数据的图像格式。

但要使用这种图像格式,需要专门的图像处理工具软件,RAW文件是CCD或CMOS感光部件在拍摄时所记录下的原始数据文件,是以一组8位或10位的二进制数据记录的数据,只反映照射到感光单元上光线的强度,本身并不包含色彩等直观的图像信息,而且它是和硬件密切相关的,不知道CCD或CMOS的感光单元行列排布、滤色镜排列等物理参数就无法将它转换成图像,所以处理RAW文件的图像处理工具还需要支持您的数码相机。

一般情况下,推荐您首选数码相机厂商附送的软件,例如,如果您使用佳能公司的EOS 10D数码相机,可以选择该公司附送的RAW文件浏览器“File Viewer UTility”,这样就可以在电脑上浏览拍摄的照片,查看所有相关的相机设置。更为重要的是,它可以让您调整RAW格式的图像,包括正负两级的曝光调整、色阶曲线、白平衡、锐度等参数。

另外,您也可以考虑使用Photoshop的数码相机RAW插件,该插件支持佳能、富士等多家数码相机厂商的数码相机。

3. 恢复误删的数码照片

使用数码相机时,我们将数码照片存储在存储媒介上,常见的存储媒介有CF、SM、SD卡和记忆棒等。另外,我们还会将数码照片拷贝到电脑上,有时因为主观或者客观的种种原因,会出现误操作而将有用的照片或者其他数据文件误删除。此时,您大可不必捶胸顿足,无论是存储在存储卡上的还是拷贝到硬盘上的数码照片,误删除后大部分情况下都是可以恢复的。

对于电脑上被误删除的数据可以恢复这一点,相信大多数比较熟悉电脑的用户都没有异议,但大部分用户都误以为存储卡上的数据是不一样的。实际上,数码相机都是遵循DCIM标准的,存储卡上的数据存储格式和操作方式都和电脑操作磁盘数据时一样。所以,基于磁盘等磁介质的数据恢复原理,从理论上讲,存储卡上的数码照片和已经拷贝到电脑上的数码照片一样,不但是可以恢复的,而且是很容易实现的。使用电脑上常用的数据恢复软件,例如Easy Recovery、Get Data Back、Final Data、R-Studio等,都可以轻易地恢复存储卡上的数码照片。

4. 拍摄时分辨率的影响

分辨率越大,图像的精度越高,尽量使用高分辨率进行拍摄是许多数码相机用户的一种错误的认识。理论上讲,高分辨率可以获得高精度的图像,但数码照片要以图像文件的形式记录,随着分辨率的提高,图像文件也将增大,数码相机处理图像的时间随之增多。所以使用的分辨率越高,拍摄时需要的处理时间越多,拍摄时需要占用的存储空间也越大。使用数码相机拍摄时存储器件的容量是有限的,使用的分辨率越高所能拍摄的张数自然也就越少。另外,由于处理的时间长,在抓拍时使用过高的分辨率将有可能错过精彩的镜头。

即使您不在意存储空间的浪费和处理时间的增加,分辨率的选择也应当以够用为限,否则当您做后期处理时,您会发现,用较高分辨率拍摄的图像利用软件缩小成低分辨率,与用较低分辨率直接拍摄的图像视觉效果几乎相同,而且后者的图像锐度似乎还会更好一些。

5. 拍摄时分辨率的选择

目前,大多数数码相机都有几级分辨率可供选择,如何决定应该选择多大的拍摄分辨率呢?拍摄后的图像用途是影响需要选择哪一级别分辨率进行拍摄的主要原因。如果数码照片只是用于网页制作上,那么不需要太高的分辨率,如果只是在显示器上显示用,必须记住,图像像素和显示器显示设置存在相互对应的关系。所以若想让图像全屏显示到标准640×480像素的显示屏上,那么您需要的仅仅是一幅640×480像素的图像。如果屏幕显示设置为1280×960像素,那么 640×480像素的图像只会占到屏幕的一半空间。不需要考虑每英寸的像素数目,显示器仅仅在意水平和垂直像素的数目。

如果您的数码照片将用于打印输出,那么您需要记住,屏幕显示和打印、印刷输出是两回事,您需要了解两个词汇并记住它们之间的关系,图像分辨率是描述图像的总像素数(PPI)的,以 PPI为单位。而决定图像输出质量的是图像的输出分辨率,描述的是设备输出图像时每英寸可产生的点数(DPI),以DPI为单位。两者有联系但并不相等, “图像分辨率÷输出分辨率=图像输出尺寸”。以杂志印刷为例,输出分辨率最低要求为300 DPI,16开满版图片也就需要约3200×2400的分辨率。

6. 冲印尺寸与拍摄参数

目前数码冲印系统可以为您提供小至1寸,大至16寸的10种不同规格的冲印服务,不同规格的冲印尺寸对数码照片有不同的要求。

要得到好的照片,数码相机的有效像素最好在300万以上,同时,拍摄的数码照片分辨率也有一定要求。一般情况下,在数码冲印时有一个简单的计算方法,可以计算多大分辨率的数码照片合适冲印多大的照片,分辨率为1600×1200的数码照片,通过1600÷250 = 6.4四舍五入后为6的计算方法,计算出合适的冲印照片尺寸是6寸,那么您可以将6乘以250,就可以得出选择1600×1200的分辨率是比较合适的。

要注意,不同数码相机的选择方法是不同的,大部分数码相机提供了比较详细的分辨率选项,但有的则只提供Large、Medium、Low三级选择,此时您需要参照数码相机的说明书等资料了解对应的分辨率大小。

7. 白平衡的使用

在数码摄影中,要达到准确的色彩还原,解决相机不能正确识别各种不同性质的光源颜色的问题,必须正确设置白平衡。

各厂家的数码相机既有自动进行白平衡的,也有手动进行的。自动白平衡虽然方便,但准确度有限,所以,现在的数码相机除了自动白平衡之外,还有日光、阴天、白炽灯、日光灯等多种预定义的白平衡。但即使如此,现实生活中光线条件是多种多样的,不同的数码相机,预定义的白平衡和自动白平衡的修正能力也是有限的。另外,在使用自动白平衡时还容易由于前一个景物的颜色特别偏向某一种颜色,引起之后的照片都偏向某一种色的问题。

因此,在选购时,您最好选择具有手动白平衡功能的数码相机,给自己留下更多的调整空间。仔细观察,反复揣摩,熟练地使用白平衡功能将会拍摄出更优美的照片,给您带来意想不到的乐趣。

不要太过于局限于专家或者传统的使用方法,例如佳能G2数码相机的用户大多按WB按钮切换到白平衡设置,选择最后一项的手动设置然后将镜头对着大面积的纯白色对象按下“*”按钮来设置白平衡。但事实上,我们可以按实际的需要进行设置,例如反向利用白平衡功能,这样不仅能够把晚霞拍摄得更红,而且还可以拍摄出像专业照片那样的摄影效果。

8. 测光方式的选择

几乎目前所有的数码相机都采用TTL测光方式经过镜头来测光。透过镜头测光的好处是能够直接反射所见景物光线的大小,也就是光线经于镜头投射在感光元件上,感光元件再将光信号传送给数码相机的处理芯片作分析。另外,部分半专业或者专业数码相机还提供多种测光方式供用户选择,在选择测光方式时,您首先要弄明白这些测光方式的特点。

目前,数码相机的测光方式有许多种,但实际上,可以将它们划分为平均测光、中央重点测光和点测光几种。

平均测光就是把画面的所有光线强度的平均值作为测光数值,其特点是不考虑画面主体,对于光照比较平均的画面,测光比较准确,适合于光照均匀,没有强烈反差对比的场合。平均测光有多种数据采集和计算方法,例如佳能的“分区评价测光”方式,将画面分割成35部分作评价测光,实际上这也是平均测光的一种,但是能令计算结果更趋合理。

中央重点测光是将画面中心及附近的画面按不同的加权系数进行计算得出的值作为测光数值,以中心的权数为最大,越接近画面边缘,权数越小,

这是一种中庸的测光方式,既照顾到取景范围内整体的亮度,又考虑到摄影时的主体一般位于中央区域,适合主体比较突出又需要兼顾背景的场合。

点测光是比较专业的测光方式,取画面中心占1%的面积作为测光区域。这是一种比较极端的测光方式,适合于光线复杂或光比强烈需要突出主体的场合,营造特殊艺术效果。

9. 感光度的设定

ISO(International Standards Organization)是制定工业标准的国际标准组织的简称。胶片相机工业标准中,ISO标准衡量胶片对光线敏感程度,数值越低,胶片的曝光感应速度越慢。

数码相机中同样也采用ISO标准来衡量感光部件对光线的敏感程度,数值越大,感光部件越敏感。在传统相机中,您可以按需要的拍摄效果使用不同ISO标准的胶片来利用其不同的曝光感应速度。在数码相机中,您也可以通过调整ISO数值来设定改变感光部件的敏感程度。

在数码相机上提高ISO数值也就是提高感光度,由于感光度的提高,数码相机的快门速度会比较快,拍摄起来也比较容易。但是需要注意,因此也会产生一些不良的影响,例如,因为感光部件感光不足而使光信号转换为电信号后的电流强度减弱,照片的阴暗部分或者单色区域噪声色斑现象会比较明显。如果您希望获得画面干净利索的照片,那么您或者可以考虑采用低ISO数值来拍摄。不过,不同的相机感光度的设定还需要您自己实际去体验,建议您在还没有了解相机的特性时,在拍摄时一级一级地升高感光度来进行测试。

10. 快门的控制技巧

在摄影技术中,拍摄影像的最原始的质量来源于对曝光的控制。数码相机与传统相机一样,通过光圈和快门控制允许光线照射到感光元件或胶片上的量。其中,快门决定了拍摄影像的时间,其打开的时间就是根据设定的快门速度决定的。

通常,相机的快门速度范围有4秒、2秒、1秒等多种。控制快门的技巧首先是要注意安全快门的时间,如果在快门打开期间,相机因不稳而产生晃动,则拍摄所得的影像就会变得模糊不清。这就是为什么在拍摄时要保持机身的稳定,也正是为什么快门速度过慢更容易使影像模糊的原因。因此,一般情况下,选择的快门速度要比安全快门速度快,安全快门=1/镜头的焦距。例如,镜头的焦距是50mm,安全快门就是1/50秒,即要选1/60秒以上的快门速度才可避免因拍摄时手部震动而造成影像模糊的问题。

另外,在控制快门时,还需要特别注意快门的时滞问题。所谓快门时滞也就是按下快门和感光元件或胶片成像之间的时间,由于数码相机的快门时滞比传统相机长,只有顶级专业单镜头反光数码相机的快门时滞与传统相机相当,而绝大多数数码相机的时滞都是普通传统相机的2-3倍。如果使用液晶屏取景的话,时滞更加严重,时滞的时间虽然很短,但对于一个运动的物体来说,这便是很长的时间了,对于抓拍摄影,必然会错过最佳时机。而且不同相机的时滞都不同,您需要了解自己的相机,同时做大量的快速反应拍摄练习来避免时滞对您的影响。

11. 控制曝光量

不论是传统相机还是数码相机,拍摄时控制曝光量都是影响照片效果的关键。要控制好曝光量,首先要记住快门速度、光圈和ISO感光度三者之间的关系,即快门速度提高一倍,镜头的通光量就会减少一半;光圈每增加一档,和快门速度提高一倍时一样,通光量也会减少一半;ISO感光度增加一倍,通光量即使减半也能够用同样曝光量曝光。

如今大多数数码相机都配备了“曝光补偿”功能,将曝光补偿设置成+1档,就意味着快门速度减慢一半,或者光圈增大一倍。实际上,使用数码相机提供的预设模式时,相机会从光圈和快门速度两方面进行调节,以使通光量翻倍。

一般情况下,可以由相机来测定整个画面的光线亮度,并确定最佳曝光量。但相机的智能是有限的,例如在拍摄雪景等以白色为主的对象时,数码相机本身就会错误地认为光量充足,并自动减小曝光量,这样拍摄到的画面就较暗。而拍摄大面积黑色对象时,相机同样会认为光线不足。

要控制好曝光量,您需要具有曝光补偿的知识,这样才能拍摄到亮度和预想亮度一样的照片。在什么样的情况下,什么程度的补偿最合适,最终还是要由您本人的眼睛来掌握。这里无法给您一个准确的标准,但原则是,对于白色和高亮度区域多的对象应增加曝光补偿,黑色和昏暗的、区域广的对象,应减小曝光补偿。

12. 红外线拍摄效果

除了一般的闪光灯外,其他光线也可以应用在摄影技术上,例如,红外线和紫外线等。红外线摄影技术不管是在业余或者是专业领域,都有相当多的讨论和应用。想体验一下,您可以在拍摄时应用大功率的红外线灯照射主体,也可以在其他电子发光装置上装一个红外滤光片,这样,红外线会直接打在主体上再反射回镜头成像,这样就可以实现红外线拍摄效果。但传统摄影必须依赖红外线专用底片,而且底片保存、冲洗与运送都是一件麻烦事,所以一般用户都比较缺乏这方面的经验。但数码相机由于硅材质的感光元件对红外线的波长敏感,拍摄红外线照片会比传统相机简单。

另外,如果您的数码相机配备红外线辅助功能,例如SONY的F717,那么应用红外线摄影时,不仅能在微光的环境下继续操作拍摄生态写真,而且将之应用在风景摄影上也可创造出与众不同的特别效果,并且还可以有 ,但红外线的透视能力并不是100%。

13. 合理使用闪光灯

闪光灯是非常便捷且适合当作补充光源的一种工具。但一般来说,强调自动化的数码相机并没有太强的闪光灯,充其量是把闪灯功能加以程序化,提供“自动”、“强制”、“防红眼”、“慢速”等设定。

“自动”模式下,相机会自动判断拍摄场景的光线是否充足。如果不足,就会自动在拍摄时打开闪光灯进行闪光,以弥补光线;“防红眼”模式先让闪光灯快速闪烁一次或数次,使人的瞳孔适应之后,再进行主要的闪光与拍摄,避免照片中人眼睛发红的问题;“强制”模式即不管在明亮或弱光的环境中,都开启闪光灯进行闪光,通常用在拍摄背对光源的人物;“慢速”模式会延迟数码相机的快门释放速度,以闪光灯照明前景,配合慢速快门,如1/5秒,为弱光背景曝光,能够拍摄出前后景均得到和谐曝光的照片。

由于数码相机的智能程度有限,在不同设定下,闪光灯产生的效果很难确定,因此,要获得更好的拍摄效果,需要选购带手动功能的外接闪光灯的数码相机,通过人脑决定闪光灯的强度、大小、次数与频率,可以大大地增加摄影适用范围。一般,手动控制闪光灯需要进行大量的实践,因为使用的是数码相机,所以您可以多试拍几张以确定闪光灯的能量。需要注意的是,部分外接闪光灯使用低功率以减少光的输出时,色温会稍高。

14. 理解电脑屏幕的差异

使用数码相机的用户大多都会使用电脑对照片进行处理,或者是在电脑上存储、浏览照片。但同时,由于在电脑屏幕上浏览照片的效果与实际输出的照片效果不相同而引起的烦恼也困扰着大部分用户。

实际上,由于设备的不同,产生这种差异是非常正常的,您是否感觉到电脑上所呈现的影像比打印机输出的照片漂亮呢?显示器的分辨率只有72dpi,但显示出的影像却比720dpi甚至1440dpi的打印机结果还要好,其原因就在于,电脑屏幕上输出的色彩采用模拟方式,当影像能以连续色调显示时,就算分辨率不怎么高,影像仍很逼真。但用喷墨或是激光打印机输出时,影像是以墨点来构成的。打印机仅能控制有无墨点,却无法控制其深浅变化。而且印刷采用的分辨率与电子影像的分辨率不同,以目前的技术要让打印机以同样精确的墨滴进行打印是相当困难的。

另外,还有许多类似的问题,例如,照片在数码相机上效果正常,但在电脑屏幕上看时却有点曝光不正常,这是由于数码相机的液晶显示和阴极射线式显示器的差异造成的,和打印机的问题一样是相当正常的。

那么应该如何解决这些问题呢?要解决打印机的问题,首先需要您调整电脑屏幕的颜色,使之显示的颜色能够与打印机的一致,同时学会计算打印输出不同质量的图像时需要的精度(可参考上面介绍的“拍摄时分辨率的选择”)。而数码相机液晶显示的问题比较简单,您只需要使用Photoshop打开图像,使用“图像”菜单“调整”中的“色阶”查看一下,如果色阶平均,则说明照片曝光正常,应该调节显示器亮度,如果色阶右边有空白的区域,则说明照片曝光不足,有了依据您就可以做出调整。

15. 保护Exif摄影信息

大部分数码相机都支持在照片上存储Exif摄影信息,这些摄影信息可以帮助我们方便地保存拍摄数据,在欣赏数码照片时,既可以回味拍摄时的感觉,还可以让我们总结拍摄经验,提高摄影水平。通过研读数码照片的摄影信息,比较同一主题的照片所采用的各种不同快门、光圈等相机设置和处理,我们可以更好地掌握拍摄此类照片时最佳的相机设置,从而提高自己的摄影水平。

Exif信息非常有用,但也很容易被破坏。如果您使用Windows XP的图像文件查看功能浏览您的数码照片,照片上的摄影信息将会被破坏。摄影信息就会被破坏,而且这些摄影信息一旦被破坏就无法恢复了。

另外,大部分电脑用户都喜欢使用通用的图像浏览软件(如ACDSee)来浏览数码照片,但是,您需要特别注意的是,如果您使用ACDSee旋转照片或者改变数码照片的分辨率,数码照片的摄影信息也会被更改,因此,在选择和使用管理数码照片的软件时,您需要特别小心。如果您的数码相机厂商随机附赠处理和浏览数码照片的软件,您应该首先选择它们,例如佳能数码相机的ZoomBrowser EX、PhotoStitch等随机附送软件。

篇5:11个发票使用规定

1、企业收到的国外发票可以入账吗?

【问】接到国外的形式发票如何入账?是否需要到税务部门登记备案?

【解答】根据《中华人民共和国发票管理办法》(中华人民共和国财政部令第6号)文件的规定:单位和个人从中国境外取得的与纳税有关的发票或者凭证,税务机关在纳税审查时有疑义的,可以要求其提供境外公证机构或者注册会计师的确认证明,经税务机关审核认可后,方可作为记账核算的凭证。

因此,贵公司取得境外凭证可以列支,但税务机关审查时需要由贵单位提供确认证明。

2、善意取得大头小尾发票如何进行处理

【问题】在税务检查中发现某企业取得几份发票存在疑问,企业已列入成本,并已在企业所得税税前扣除。经发函到开票方税务机关调查,现收到回函证实该业务、付款均真实,只是开票方开具了“大头小尾”发票,请问该企业取得的发票内容与该业务、付款金额等均一致的情况下,是否必须到开票方换开发票才能在所得税税前扣除?

【解答】纳税人有真实交易、善意取得“大头小尾”发票的,如果开票方纳税人所在地主管税务机关回函证明,该发票确属开票方自发售税务机关购买,且购票方、开具方、业务交易、收款属于同一方,实际交易金额与发票上所列金额一致的,其取得的发票准予作为税前扣除的凭据。

3、货物品种较多时发票的开具

【问】纳税人开具增值税专用发票时,货物品种较多时应如何开具发票?

【解答】根据《国家税务总局关于修订〈增值税专用发票使用规定〉的通知》(国税发[2006]156号)规定,一般纳税人销售货物或者提供应税劳务可汇总开具专用发票。汇总开具专用发票的,同时使用防伪税控系统开具《销售货物或者提供应税劳务清单》,并加盖财务专用章或者发票专用章。

4、以手写形式填写的发票能否在税前扣除?

【问】我公司取得快递公司的发票,但没有填写开具公司名称,财务人员直接以手写的形式填进去。这种情况下发生的真实合理的费用,能否在企业所得税税前扣除?

【解答】《企业所得税法》第八条规定,企业实际发生的与取得收入有关的、合理的支出,包括成本、费用、税金、损失和其他支出,准予在计算应纳税所得额时扣除。《国家税务总局关于印发〈进一步加强税收征管若干具体措施〉的通知》(国税发〔2009〕114号)第六条规定,加强企业所得税税前扣除项目管理。未按规定取得的合法有效凭据不得在税前扣除。《发票管理办法》第二十二条规定,不符合法规的发票,不得作为财务报销凭证,任何单位和个人有权拒收。第二十三条规定,开具发票应当按照法规的时限、顺序,逐栏、全部联次一次性如实开具,并加盖单位财务印章或者发票专用章。因此,企业索取发票时应根据以上规定,在取得发票时,一定要注意其合法性,不得索取填写项目不齐全,内容不真实,没有加盖财务印章或者发票专用章等不符合规定的发票,对不符合规定的发票,任何单位有权拒收,也不得在企业所得税税前扣除。

5、无法取得发票的赔偿金可否税前扣除

【问题】法院判决企业支付赔偿金,但无法取得发票,此项支出可否税前扣除?

【解答】《企业所得税法》第八条规定:企业实际发生的与取得收入有关的、合理的支出,包括成本、费用、税金、损失和其他支出,准予在计算应纳税所得额时扣除。因此,如果该赔偿金的支出是与企业生产经营有关且属于企业因合同行为而发生的,可以税前扣除。法院判决企业支付赔偿金,企业可凭法院的判决文书与收款方开具的收据作为扣除凭据。

6、公司班车运费发票是否能抵扣进项税

根据《财政部国家税务总局关于在上海市开展交通运输业和部分现代服务业营业税改征增值税试点的通知》(财税〔2011〕111号)的规定,从销售方或者提供方取得的增值税专用发票上注明的增值税额准予从销项税额中抵扣。但下列项目的进项税额不得从销项税额中抵扣:(一)用于适用简易计税方法计税项目、非增值税应税项目、免征增值税项目、集体福利或者个人消费的购进货物、接受加工修理修配劳务或者应税服务。其中涉及的固定资产、专利技术、非专利技术、商誉、商标、著作权、有形动产租赁,仅指专用于上述项目的固定资产、专利技术、非专利技术、商誉、商标、著作权、有形动产租赁。(二)非正常损失的购进货物及相关的加工修理修配劳务和交通运输业服务。(三)非正常损失的在产品、产成品所耗用的购进货物(不包括固定资产)、加工修理修配劳务或者交通运输业服务。(四)接受的旅客运输服务。(五)自用的应征消费税的摩托车、汽车、游艇,但作为提供交通运输业服务的运输工具和租赁服务标的物的除外。

因此,营业税改征增值税一般纳税人接受应税服务如属于允许抵扣的范围且取得合法的扣税凭证可予以抵扣进项税额;如用于上述不得抵扣范围的则不可抵扣。

7、外贸企业丢失专用发票如何办理出口退税

【问题】外贸企业丢失增值税专用发票如何办理出口退税?

【解答】根据《国家税务总局关于外贸企业丢失增值税专用发票抵扣联出口退税有关问题的通知》(国税函[2010]162号)规定,对于企业丢失增值税专用发票应分以下两种情况处理:

篇6:新教材使用总结

新教材使用总结

我们备课组的几位老师经过了差不多两年的新课改实验,在实验的过程中真切的感受了新课改的主旨和精神,理解了并能够按照新大纲和新教材的精神来指导自己的日常教学,初步形成了自己的教学风格。尤其是新教材进课堂后,如何用好它,我们下了一番苦功夫去讨论、适应。经过摸索,在教材的使用方面,我们慢慢地积累了一些经验,现总结如下:

一、以“要让学生成为学习的主体”的精神来指导教材的使用。

新教材的使用,是为了配合新课标的实施而改的。所以在使用新教材时,首先要明白和牢牢记住这样的原则。在平时的教学中,我们做到了转变观念,解放思想,明确课改的目的意义,能主动投入到课改中去,主动想办法解决课改中出现的问题当然也包括有关教材使用上的问题。在思想观念上,我们放弃以前陈旧落后的思想和方法,尽快适应了新的形势。无可否认,新教材在注重知识性与人文性方面,有其显著的优点,但是教材虽好,教好学生却不容易!所以我们认为说一千,道一万,最重要的还是要让学生成为学习的主体,即学习的主人。为了让学生成为学习的主体,我们在教学中强调师生应在平等对话的过程中进行。主动为学生创设良好的自主学习情境,激发学生的学习兴趣,注重培养学生自主学习的意识和习惯,尊重学生的个体差异,引导和鼓励学生选择适合自己的学习方式。我们教师只是作为学习活动的组织者和引导者。如以语文阅读教学为例,以前的教学,我们多是采用以教师的分析及教学参考书作为教学主要依据的教学方法。但阅读教学是学生、教师、文本之间对话的过程,更是学生的个性化行为,是学生个性化体验的过程。所以,在教学中,我们非常珍惜每个学生对阅读文本的独特体验。指导学生从阅读中体会文章语言文字运用的精妙之处,从阅读中领悟作者的思想感情,从阅读中感受自然和社会生活的情趣。通过这样使文本所表达的思想,所运用的语言逐渐内化,从而在语言实践的过程中提高学生的人文素养及语文素养。学生阅读文本的过程中,我们注重扮演“引导者”的角色,在引导学生进入作者所描述的世界,指导学生对文本进行探究,拓展学生的思维和想象空间。

二、用新教材培养学生良好的读书学习习惯。

新教材的.变化较大,课后练习少了,题型也简单了。但是我们觉得教学并没有因此而轻松。我们认为新教材的根本目的是使学生养成良好的读书学习习惯。因此,在使用教材时一直强调做到这一点,多引导学生养成良好的学习习惯。虽然新教材的变化减轻了学生负担,但我们的教学要求没有降低甚至是提高了。在教学过程中,我们做到了加强研讨和交流,力争做到新教材有新教法。

三、使用新教材的几个注意。

在平时的教学中,我们总结出几点注意是:

一、使用新教材要注意深入并充分地了解学生。新教材关注学生的学习兴趣和生活经验,并主张在这一基础上教学。这就要求教师转变观念,改革教学模式。深入并充分地了解自己的学生,探明学生现在的智力基础、生活经验、个性差异等等,从学生的实际出发,引导学生主动积极地学习。

二、使用新教材要注意别被教材束缚住。教材的价值在于能作用于学生充分发展,在于能有效地激活学生积极主动地学习。因此不能为了教教材而教教材,而是以教材为重要的而不是唯一的课程资源,要用教材教,但不是教教材。在用的过程中为学生创设活动、提供机会,促其情感愉悦、态度主动,促其获得方法、提高技能。

三、利用新教材创造学习资源。再好的教材也会有局限性,也会有不适应性。我们要做教材的主人,而不是教材的奴隶。通过我们去再创造、去内化、去升华,能够创造出许多相关的教学资源,全面提高学生的素质。

篇7:SQLITE3 使用总结

前序:

这里要注明,我是一个跨平台专注者,并不喜欢只用 windows平台。我以前的工作就是为 unix平台写代码。下面我所写的东西,虽然没有验证,但是我已尽量不使用任何 windows 的东西,只使用标准 C 或标准C++。但是,我没有尝试过在别的系统、别的编译器下编译,因此下面的叙述如果不正确,则留待以后修改。

下面我的代码仍然用 VC 编写,因为我觉得VC是一个很不错的IDE,可以加快代码编写速度(例如配合 Vassist )。下面我所说的编译环境,是VC2003。如果读者觉得自己习惯于 unix 下用 vi 编写代码速度较快,可以不用管我的说明,只需要符合自己习惯即可,因为我用的是标准 C 或 C++ 。不会给任何人带来不便。

一、版本

从 www.sqlite.org 网站可下载到最新的 sqlite 代码和编译版本。我写此文章时,最新代码是 3.3.17 版本。

很久没有去下载 sqlite 新代码,因此也不知道 sqlite 变化这么大。以前很多文件,现在全部合并成一个 sqlite3.c 文件。如果单独用此文件,是挺好的,省去拷贝一堆文件还担心有没有遗漏。但是也带来一个问题:此文件太大,快接近7万行代码,VC开它整个机器都慢下来了。如果不需要改它代码,也就不需要打开 sqlite3.c 文件,机器不会慢。但是,下面我要写通过修改 sqlite 代码完成加密功能,那时候就比较痛苦了。如果个人水平较高,建议用些简单的编辑器来编辑,例如UltraEdit 或 Notepad 。速度会快很多。

二、基本编译

这个不想多说了,在 VC 里新建 dos 控制台空白工程,把 sqlite3.c 和 sqlite3.h 添加到工程,再新建一个 main.cpp文件。在里面写:

extern “C”{#include “./sqlite3.h”};int main( int , char** ){return 0;}

为什么要 extern “C” ?如果问这个问题,我不想说太多,这是C++的基础。要在 C++ 里使用一段 C 的代码,必须要用 extern “C” 括起来。C++跟 C虽然语法上有重叠,但是它们是两个不同的东西,内存里的布局是完全不同的,在C++编译器里不用extern “C”括起C代码,会导致编译器不知道该如何为 C 代码描述内存布局。

可能在 sqlite3.c 里人家已经把整段代码都 extern “C” 括起来了,但是你遇到一个 .c 文件就自觉的再括一次,也没什么不好。

基本工程就这样建立起来了。编译,可以通过。但是有一堆的 warning。可以不管它。

三、SQLITE操作入门

sqlite提供的是一些C函数接口,你可以用这些函数操作数据库。通过使用这些接口,传递一些标准 sql 语句(以 char * 类型)给 sqlite 函数,sqlite 就会为你操作数据库。

sqlite 跟MS的access一样是文件型数据库,就是说,一个数据库就是一个文件,此数据库里可以建立很多的表,可以建立索引、触发器等等,但是,它实际上得到的就是一个文件。备份这个文件就备份了整个数据库。

sqlite 不需要任何数据库引擎,这意味着如果你需要 sqlite 来保存一些用户数据,甚至都不需要安装数据库(如果你做个小软件还要求人家必须装了sqlserver 才能运行,那也太黑心了)。

下面开始介绍数据库基本操作。

1 基本流程(1)关键数据结构

sqlite 里最常用到的是 sqlite3 * 类型。从数据库打开开始,sqlite就要为这个类型准备好内存,直到数据库关闭,整个过程都需要用到这个类型。当数据库打开时开始,这个类型的变量就代表了你要操作的数据库。下面再详细介绍。

(2)打开数据库

int sqlite3_open( 文件名, sqlite3 ** );

用这个函数开始数据库操作。

需要传入两个参数,一是数据库文件名,比如:c://DongChunGuang_Database.db。

文件名不需要一定存在,如果此文件不存在,sqlite 会自动建立它。如果它存在,就尝试把它当数据库文件来打开。

sqlite3 ** 参数即前面提到的关键数据结构。这个结构底层细节如何,你不要关它。

函数返回值表示操作是否正确,如果是 SQLITE_OK 则表示操作正常。相关的返回值sqlite定义了一些宏。具体这些宏的含义可以参考 sqlite3.h 文件。里面有详细定义(顺便说一下,sqlite3 的代码注释率自称是非常高的,实际上也的确很高。只要你会看英文,sqlite 可以让你学到不少东西)。

下面介绍关闭数据库后,再给一段参考代码。

(3)关闭数据库

int sqlite3_close(sqlite3 *);

前面如果用 sqlite3_open 开启了一个数据库,结尾时不要忘了用这个函数关闭数据库。

下面给段简单的代码:

extern “C”{#include “./sqlite3.h”};int main( int , char** ){ sqlite3 * db = NULL; //声明sqlite关键结构指针 int result;//打开数据库//需要传入 db 这个指针的指针,因为 sqlite3_open 函数要为这个指针分配内存,还要让db指针指向这个内存区 result = sqlite3_open( “c://Dcg_database.db”, &db ); if( result != SQLITE_OK ) { //数据库打开失败return -1;}//数据库操作代码//…//数据库打开成功//关闭数据库sqlite3_close( db );return 0;}

这就是一次数据库操作过程。

2 SQL语句操作

本节介绍如何用sqlite 执行标准 sql 语法。

(1)执行sql语句

int sqlite3_exec(sqlite3*, const char *sql, sqlite3_callback, void *, char **errmsg );

这就是执行一条 sql 语句的函数。

第1个参数不再说了,是前面open函数得到的指针。说了是关键数据结构。

第2个参数const char *sql 是一条 sql 语句,以/0结尾。

第3个参数sqlite3_callback 是回调,当这条语句执行之后,sqlite3会去调用你提供的这个函数。(什么是回调函数,自己找别的资料学习)

第4个参数void * 是你所提供的指针,你可以传递任何一个指针参数到这里,这个参数最终会传到回调函数里面,如果不需要传递指针给回调函数,可以填NULL。等下我们再看回调函数的写法,以及这个参数的使用。

第5个参数char ** errmsg 是错误信息。注意是指针的指针。sqlite3里面有很多固定的错误信息。执行 sqlite3_exec 之后,执行失败时可以查阅这个指针(直接 printf(“%s/n”,errmsg))得到一串字符串信息,这串信息告诉你错在什么地方。sqlite3_exec函数通过修改你传入的指针的指针,把你提供的指针指向错误提示信息,这样sqlite3_exec函数外面就可以通过这个 char*得到具体错误提示。

说明:通常,sqlite3_callback 和它后面的 void * 这两个位置都可以填 NULL。填NULL表示你不需要回调。比如你做insert 操作,做 delete 操作,就没有必要使用回调。而当你做 select 时,就要使用回调,因为 sqlite3 把数据查出来,得通过回调告诉你查出了什么数据。

(2)exec 的回调

typedef int (*sqlite3_callback)(void*,int,char**, char**);

你的回调函数必须定义成上面这个函数的类型。下面给个简单的例子:

//sqlite3的回调函数 // sqlite 每查到一条记录,就调用一次这个回调int LoadMyInfo( void * para, int n_column, char ** column_value, char ** column_name ){ //para是你在 sqlite3_exec 里传入的 void * 参数 //通过para参数,你可以传入一些特殊的指针(比如类指针、结构指针),然后在这里面强制转换成对应的类型(这里面是void*类型,必须强制转换成你的类型才可用)。然后操作这些数据 //n_column是这一条记录有多少个字段 (即这条记录有多少列) // char ** column_value 是个关键值,查出来的数据都保存在这里,它实际上是个1维数组(不要以为是2维数组),每一个元素都是一个 char * 值,是一个字段内容(用字符串来表示,以/0结尾) //char ** column_name 跟 column_value是对应的,表示这个字段的字段名称 //这里,我不使用 para 参数。忽略它的存在. int i;printf( “记录包含 %d 个字段/n”, n_column );for( i = 0 ; i < n_column; i ++ ){ printf( “字段名:%s ß>字段值:%s/n”, column_name[i], column_value[i] );}printf( “------------------/n“ ); return 0;}int main( int , char ** ){ sqlite3 * db; int result; char * errmsg = NULL; result = sqlite3_open( “c://Dcg_database.db”, &db ); if( result != SQLITE_OK ) { //数据库打开失败return -1;}//数据库操作代码//创建一个测试表,表名叫 MyTable_1,有2个字段: ID 和 name。其中ID是一个自动增加的类型,以后insert时可以不去指定这个字段,它会自己从0开始增加result = sqlite3_exec( db, “create table MyTable_1( ID integer primary key autoincrement, name nvarchar(32) )”, NULL, NULL, errmsg );if(result != SQLITE_OK ){ printf( “创建表失败,错误码:%d,错误原因:%s/n”, result, errmsg );}//插入一些记录result = sqlite3_exec( db, “insert into MyTable_1( name ) values ( ‘走路‘ )”, 0, 0, errmsg );if(result != SQLITE_OK ){ printf( “插入记录失败,错误码:%d,错误原因:%s/n”, result, errmsg );}result = sqlite3_exec( db, “insert into MyTable_1( name ) values ( ‘骑单车‘ )”, 0, 0, errmsg );if(result != SQLITE_OK ){ printf( “插入记录失败,错误码:%d,错误原因:%s/n”, result, errmsg );}result = sqlite3_exec( db, “insert into MyTable_1( name ) values ( ‘坐汽车‘ )”, 0, 0, errmsg );if(result != SQLITE_OK ){ printf( “插入记录失败,错误码:%d,错误原因:%s/n”, result, errmsg );}//开始查询数据库result = sqlite3_exec( db, “select * from MyTable_1”, LoadMyInfo, NULL, errmsg );//关闭数据库sqlite3_close( db );return 0;}

通过上面的例子,应该可以知道如何打开一个数据库,如何做数据库基本操作。

有这些知识,基本上可以应付很多数据库操作了。

(3)不使用回调查询数据库

上面介绍的 sqlite3_exec 是使用回调来执行 select 操作。还有一个方法可以直接查询而不需要回调。但是,我个人感觉还是回调好,因为代码可以更加整齐,只不过用回调很麻烦,你得声明一个函数,如果这个函数是类成员函数,你还不得不把它声明成 static 的(要问为什么?这又是C++基础了。C++成员函数实际上隐藏了一个参数:this,C++调用类的成员函数的时候,隐含把类指针当成函数的第一个参数传递进去。结果,这造成跟前面说的 sqlite 回调函数的参数不相符。只有当把成员函数声明成 static 时,它才没有多余的隐含的this参数)。

虽然回调显得代码整齐,但有时候你还是想要非回调的 select 查询。这可以通过 sqlite3_get_table 函数做到。

int sqlite3_get_table(sqlite3*, const char *sql, char ***resultp, int *nrow, int *ncolumn, char **errmsg );

第1个参数不再多说,看前面的例子。

第2个参数是 sql 语句,跟 sqlite3_exec 里的 sql 是一样的。是一个很普通的以/0结尾的char *字符串。

第3个参数是查询结果,它依然一维数组(不要以为是二维数组,更不要以为是三维数组)。它内存布局是:第一行是字段名称,后面是紧接着是每个字段的值。下面用例子来说事。

第4个参数是查询出多少条记录(即查出多少行)。

第5个参数是多少个字段(多少列)。

第6个参数是错误信息,跟前面一样,这里不多说了。

下面给个简单例子:

int main( int , char ** ){ sqlite3 * db; int result; char * errmsg = NULL; char **dbResult; //是 char ** 类型,两个*号 int nRow, nColumn; int i , j; int index; result = sqlite3_open( “c://Dcg_database.db”, &db ); if( result != SQLITE_OK ) { //数据库打开失败 return -1; } //数据库操作代码 //假设前面已经创建了 MyTable_1 表 //开始查询,传入的 dbResult 已经是 char **,这里又加了一个 & 取地址符,传递进去的就成了 char *** result = sqlite3_get_table( db, “select * from MyTable_1”, &dbResult, &nRow, &nColumn, &errmsg ); if( SQLITE_OK == result ) { //查询成功 index = nColumn; //前面说过 dbResult 前面第一行数据是字段名称,从 nColumn 索引开始才是真正的数据 printf( “查到%d条记录/n”, nRow ); for( i = 0; i < nRow ; i++ ) { printf( “第 %d 条记录/n”, i+1 ); for( j = 0 ; j < nColumn; j++ ) { printf( “字段名:%s ß>字段值:%s/n”, dbResult[j], dbResult [index] ); ++index; // dbResult 的字段值是连续的,从第0索引到第 nColumn - 1索引都是字段名称,从第 nColumn 索引开始,后面都是字段值,它把一个二维的表(传统的行列表示法)用一个扁平的形式来表示 } printf( “-------/n” ); } } //到这里,不论数据库查询是否成功,都释放 char** 查询结果,使用 sqlite 提供的功能来释放 sqlite3_free_table( dbResult ); //关闭数据库 sqlite3_close( db ); return 0;}

到这个例子为止,sqlite3 的常用用法都介绍完了。

用以上的方法,再配上 sql 语句,完全可以应付绝大多数数据库需求。

但有一种情况,用上面方法是无法实现的:需要insert、select 二进制。当需要处理二进制数据时,上面的方法就没办法做到。下面这一节说明如何插入二进制数据

3 操作二进制

sqlite 操作二进制数据需要用一个辅助的数据类型:sqlite3_stmt * 。

这个数据类型记录了一个“sql语句”。为什么我把 “sql语句” 用双引号引起来?因为你可以把 sqlite3_stmt * 所表示的内容看成是 sql语句,但是实际上它不是我们所熟知的sql语句。它是一个已经把sql语句解析了的、用sqlite自己标记记录的内部数据结构。

正因为这个结构已经被解析了,所以你可以往这个语句里插入二进制数据。当然,把二进制数据插到 sqlite3_stmt 结构里可不能直接 memcpy ,也不能像 std::string 那样用 + 号。必须用 sqlite 提供的函数来插入。

(1)写入二进制

下面说写二进制的步骤。

要插入二进制,前提是这个表的字段的类型是 blob 类型。我假设有这么一张表:

create table Tbl_2( ID integer, file_content blob )

首先声明

sqlite3_stmt * stat;

然后,把一个 sql 语句解析到 stat 结构里去:

sqlite3_prepare( db, “insert into Tbl_2( ID, file_content) values( 10, ? )”, -1, &stat, 0 );

上面的函数完成 sql 语句的解析。第一个参数跟前面一样,是个 sqlite3 * 类型变量,第二个参数是一个 sql 语句。

这个 sql 语句特别之处在于 values 里面有个 ? 号。在sqlite3_prepare函数里,?号表示一个未定的值,它的值等下才插入。

第三个参数我写的是-1,这个参数含义是前面 sql 语句的长度。如果小于0,sqlite会自动计算它的长度(把sql语句当成以/0结尾的字符串)。

第四个参数是 sqlite3_stmt 的指针的指针。解析以后的sql语句就放在这个结构里。

第五个参数我也不知道是干什么的。为0就可以了。

如果这个函数执行成功(返回值是 SQLITE_OK 且 stat 不为NULL ),那么下面就可以开始插入二进制数据。

sqlite3_bind_blob( stat, 1, pdata, (int)(length_of_data_in_bytes), NULL ); // pdata为数据缓冲区,length_of_data_in_bytes为数据大小,以字节为单位

这个函数一共有5个参数。

第1个参数:是前面prepare得到的 sqlite3_stmt * 类型变量。

第2个参数:?号的索引。前面prepare的sql语句里有一个?号,假如有多个?号怎么插入?方法就是改变 bind_blob 函数第2个参数。这个参数我写1,表示这里插入的值要替换 stat 的第一个?号(这里的索引从1开始计数,而非从0开始)。如果你有多个?号,就写多个 bind_blob 语句,并改变它们的第2个参数就替换到不同的?号。如果有?号没有替换,sqlite为它取值null。

第3个参数:二进制数据起始指针。

第4个参数:二进制数据的长度,以字节为单位。

第5个参数:是个析够回调函数,告诉sqlite当把数据处理完后调用此函数来析够你的数据。这个参数我还没有使用过,因此理解也不深刻。但是一般都填NULL,需要释放的内存自己用代码来释放。

bind完了之后,二进制数据就进入了你的“sql语句”里了。你现在可以把它保存到数据库里:

int result = sqlite3_step( stat );

通过这个语句,stat 表示的sql语句就被写到了数据库里。

最后,要把 sqlite3_stmt 结构给释放:

sqlite3_finalize( stat ); //把刚才分配的内容析构掉

(2)读出二进制

下面说读二进制的步骤。

跟前面一样,先声明 sqlite3_stmt * 类型变量:

sqlite3_stmt * stat;

然后,把一个 sql 语句解析到 stat 结构里去:

sqlite3_prepare( db, “select * from Tbl_2”, -1, &stat, 0 );

当 prepare 成功之后(返回值是 SQLITE_OK ),开始查询数据。

int result = sqlite3_step( stat );

这一句的返回值是SQLITE_ROW 时表示成功(不是 SQLITE_OK )。

你可以循环执行sqlite3_step 函数,一次step查询出一条记录。直到返回值不为 SQLITE_ROW 时表示查询结束。

然后开始获取第一个字段:ID 的值。ID是个整数,用下面这个语句获取它的值:

int id = sqlite3_column_int( stat, 0 ); //第2个参数表示获取第几个字段内容,从0开始计算,因为我的表的ID字段是第一个字段,因此这里我填0

下面开始获取 file_content 的值,因为 file_content 是二进制,因此我需要得到它的指针,还有它的长度:

const void * pFileContent = sqlite3_column_blob( stat, 1 );int len = sqlite3_column_bytes( stat, 1 );

这样就得到了二进制的值。

把 pFileContent 的内容保存出来之后,不要忘了释放 sqlite3_stmt 结构:

sqlite3_finalize( stat ); //把刚才分配的内容析构掉

(3)重复使用 sqlite3_stmt 结构

如果你需要重复使用 sqlite3_prepare 解析好的 sqlite3_stmt 结构,需要用函数: sqlite3_reset。

result = sqlite3_reset(stat);

这样, stat 结构又成为 sqlite3_prepare 完成时的状态,你可以重新为它 bind 内容。

4 事务处理

sqlite 是支持事务处理的。如果你知道你要同步删除很多数据,不仿把它们做成一个统一的事务。

通常一次 sqlite3_exec 就是一次事务,如果你要删除1万条数据,sqlite就做了1万次:开始新事务->删除一条数据->提交事务->开始新事务->… 的过程。这个操作是很慢的。因为时间都花在了开始事务、提交事务上。

你可以把这些同类操作做成一个事务,这样如果操作错误,还能够回滚事务。

事务的操作没有特别的接口函数,它就是一个普通的 sql 语句而已:

分别如下:

int result; result = sqlite3_exec( db, “begin transaction”, 0, 0, &zErrorMsg ); //开始一个事务result = sqlite3_exec( db, “commit transaction”, 0, 0, &zErrorMsg ); //提交事务result = sqlite3_exec( db, “rollback transaction”, 0, 0, &zErrorMsg ); //回滚事务

四、C/C++开发接口简介1 总览

SQLite3是SQLite一个全新的版本,它虽然是在SQLite 2.8.13的代码基础之上开发的,但是使用了和之前的版本不兼容的数据库格式和API. SQLite3是为了满足以下的需求而开发的:

支持UTF-16编码.

用户自定义的文本排序方法.

可以对BLOBs字段建立索引.

因此为了支持这些特性我改变了数据库的格式,建立了一个与之前版本不兼容的3.0版. 至于其他的兼容性的改变,例如全新的API等等,都将在理论介绍之后向你说明,这样可以使你最快的一次性摆脱兼容性问题.

3.0版的和2.X版的API非常相似,但是有一些重要的改变需要注意. 所有API接口函数和数据结构的前缀都由“sqlite_”改为了“sqlite3_”. 这是为了避免同时使用SQLite 2.X和SQLite 3.0这两个版本的时候发生链接冲突.

由于对于C语言应该用什么数据类型来存放UTF-16编码的字符串并没有一致的规范. 因此SQLite使用了普通的void* 类型来指向UTF-16编码的字符串. 客户端使用过程中可以把void*映射成适合他们的系统的任何数据类型.

2 C/C++接口

SQLite 3.0一共有83个API函数,此外还有一些数据结构和预定义(#defines). (完整的API介绍请参看另一份文档.) 不过你们可以放心,这些接口使用起来不会像它的数量所暗示的那么复杂. 最简单的程序仍然使用三个函数就可以完成: sqlite3_open, sqlite3_exec(), 和 sqlite3_close(). 要是想更好的控制数据库引擎的执行,可以使用提供的sqlite3_prepare()函数把SQL语句编译成字节码,然后在使用sqlite3_step()函数来执行编译后的字节码. 以sqlite3_column_开头的一组API函数用来获取查询结果集中的信息. 许多接口函数都是成对出现的,同时有UTF-8和UTF-16两个版本. 并且提供了一组函数用来执行用户自定义的SQL函数和文本排序函数.

(1)如何打开关闭数据库

typedef struct sqlite3 sqlite3; int sqlite3_open(const char*, sqlite3**); int sqlite3_open16(const void*, sqlite3**); int sqlite3_close(sqlite3*); const char *sqlite3_errmsg(sqlite3*); const void *sqlite3_errmsg16(sqlite3*); int sqlite3_errcode(sqlite3*);

sqlite3_open() 函数返回一个整数错误代码,而不是像第二版中一样返回一个指向sqlite3结构体的指针. sqlite3_open() 和sqlite3_open16() 的不同之处在于sqlite3_open16() 使用UTF-16编码(使用本地主机字节顺序)传递数据库文件名. 如果要创建新数据库, sqlite3_open16() 将内部文本转换为UTF-16编码, 反之sqlite3_open() 将文本转换为UTF-8编码.

打开或者创建数据库的命令会被缓存,直到这个数据库真正被调用的时候才会被执行. 而且允许使用PRAGMA声明来设置如本地文本编码或默认内存页面大小等选项和参数.

sqlite3_errcode() 通常用来获取最近调用的API接口返回的错误代码. sqlite3_errmsg() 则用来得到这些错误代码所对应的文字说明. 这些错误信息将以 UTF-8 的编码返回,并且在下一次调用任何SQLite API函数的时候被清除. sqlite3_errmsg16() 和sqlite3_errmsg() 大体上相同,除了返回的错误信息将以 UTF-16 本机字节顺序编码.

SQLite3的错误代码相比SQLite2没有任何的改变,它们分别是:

#define SQLITE_OK0 /* Successful result */#define SQLITE_ERROR 1 /* SQL error or missing database */#define SQLITE_INTERNAL 2 /* An internal logic error in SQLite */#define SQLITE_PERM 3 /* Access permission denied */#define SQLITE_ABORT 4 /* Callback routine requested an abort */#define SQLITE_BUSY 5 /* The database file is locked */#define SQLITE_LOCKED 6 /* A table in the database is locked */#define SQLITE_NOMEM 7 /* A malloc() failed */#define SQLITE_READONLY 8 /* Attempt to write a readonly database */#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite_interrupt() */#define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */#define SQLITE_CORRUPT 11 /* The database disk image is malformed */#define SQLITE_NOTFOUND 12 /* (Internal Only) Table or record not found */#define SQLITE_FULL 13 /* Insertion failed because database is full */#define SQLITE_CANTOPEN 14 /* Unable to open the database file */#define SQLITE_PROTOCOL 15 /* Database lock protocol error */#define SQLITE_EMPTY 16 /* (Internal Only) Database table is empty */#define SQLITE_SCHEMA 17 /* The database schema changed */#define SQLITE_TOOBIG 18 /* Too much data for one row of a table */#define SQLITE_CONSTRAINT 19 /* Abort due to contraint violation */#define SQLITE_MISMATCH 20 /* Data type mismatch */#define SQLITE_MISUSE 21 /* Library used incorrectly */#define SQLITE_NOLFS 22 /* Uses OS features not supported on host */#define SQLITE_AUTH 23 /* Authorization denied */#define SQLITE_ROW 100 /* sqlite_step() has another row ready */#define SQLITE_DONE 101 /* sqlite_step() has finished executing */

(2)执行 SQL 语句

typedef int (*sqlite_callback)(void*,int,char**, char**);

int sqlite3_exec(sqlite3*, const char *sql, sqlite_callback, void*, char**);

sqlite3_exec 函数依然像它在SQLite2中一样承担着很多的工作. 该函数的第二个参数中可以编译和执行零个或多个SQL语句. 查询的结果返回给回调函数. 更多地信息可以查看API 参考.

在SQLite3里,sqlite3_exec一般是被准备SQL语句接口封装起来使用的.

typedef struct sqlite3_stmt sqlite3_stmt;int sqlite3_prepare(sqlite3*, const char*, int, sqlite3_stmt**, const char**);int sqlite3_prepare16(sqlite3*, const void*, int, sqlite3_stmt**, const void**);int sqlite3_finalize(sqlite3_stmt*);int sqlite3_reset(sqlite3_stmt*);

sqlite3_prepare 接口把一条SQL语句编译成字节码留给后面的执行函数. 使用该接口访问数据库是当前比较好的的一种方法.

sqlite3_prepare() 处理的SQL语句应该是UTF-8编码的. 而sqlite3_prepare16() 则要求是UTF-16编码的. 输入的参数中只有第一个SQL语句会被编译. 第四个参数则用来指向输入参数中下一个需要编译的SQL语句存放的SQLite statement对象的指针,任何时候如果调用 sqlite3_finalize() 将销毁一个准备好的SQL声明. 在数据库关闭之前,所有准备好的声明都必须被释放销毁. sqlite3_reset() 函数用来重置一个SQL声明的状态,使得它可以被再次执行.

SQL声明可以包含一些型如“?” 或 “?nnn” 或 “:aaa”的标记, 其中“nnn” 是一个整数,“aaa” 是一个字符串. 这些标记代表一些不确定的字符值(或者说是通配符),可以在后面用sqlite3_bind 接口来填充这些值. 每一个通配符都被分配了一个编号(由它在SQL声明中的位置决定,从1开始),此外也可以用 “nnn” 来表示 “?nnn” 这种情况. 允许相同的通配符在同一个SQL声明中出现多次, 在这种情况下所有相同的通配符都会被替换成相同的值. 没有被绑定的通配符将自动取NULL值.

int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));int sqlite3_bind_double(sqlite3_stmt*, int, double);int sqlite3_bind_int(sqlite3_stmt*, int, int);int sqlite3_bind_int64(sqlite3_stmt*, int, long long int);int sqlite3_bind_null(sqlite3_stmt*, int);int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int n, void(*)(void*));int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);

以上是 sqlite3_bind 所包含的全部接口,它们是用来给SQL声明中的通配符赋值的. 没有绑定的通配符则被认为是空值.绑定上的值不会被sqlite3_reset()函数重置. 但是在调用了sqlite3_reset()之后所有的通配符都可以被重新赋值.

在SQL声明准备好之后(其中绑定的步骤是可选的), 需要调用以下的方法来执行:

int sqlite3_step(sqlite3_stmt*);

如果SQL返回了一个单行结果集,sqlite3_step() 函数将返回 SQLITE_ROW , 如果SQL语句执行成功或者正常将返回SQLITE_DONE , 否则将返回错误代码. 如果不能打开数据库文件则会返回 SQLITE_BUSY . 如果函数的返回值是SQLITE_ROW, 那么下边的这些方法可以用来获得记录集行中的数据:

const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);int sqlite3_column_bytes(sqlite3_stmt*, int iCol);int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);int sqlite3_column_count(sqlite3_stmt*);const char *sqlite3_column_decltype(sqlite3_stmt *, int iCol);const void *sqlite3_column_decltype16(sqlite3_stmt *, int iCol);double sqlite3_column_double(sqlite3_stmt*, int iCol);int sqlite3_column_int(sqlite3_stmt*, int iCol);long long int sqlite3_column_int64(sqlite3_stmt*, int iCol);const char *sqlite3_column_name(sqlite3_stmt*, int iCol);const void *sqlite3_column_name16(sqlite3_stmt*, int iCol);const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);int sqlite3_column_type(sqlite3_stmt*, int iCol);

sqlite3_column_count()函数返回结果集中包含的列数. sqlite3_column_count() 可以在执行了 sqlite3_prepare()之后的任何时刻调用. sqlite3_data_count()除了必需要在sqlite3_step()之后调用之外,其他跟sqlite3_column_count() 大同小异. 如果调用sqlite3_step() 返回值是 SQLITE_DONE 或者一个错误代码, 则此时调用sqlite3_data_count() 将返回 0 ,然而sqlite3_column_count() 仍然会返回结果集中包含的列数.

返回的记录集通过使用其它的几个 sqlite3_column_***() 函数来提取, 所有的这些函数都把列的编号作为第二个参数. 列编号从左到右以零起始. 请注意它和之前那些从1起始的参数的不同.

sqlite3_column_type()函数返回第N列的值的数据类型. 具体的返回值如下:

#define SQLITE_INTEGER 1#define SQLITE_FLOAT 2#define SQLITE_TEXT 3#define SQLITE_BLOB 4#define SQLITE_NULL 5

sqlite3_column_decltype() 则用来返回该列在 CREATE TABLE 语句中声明的类型. 它可以用在当返回类型是空字符串的时候. sqlite3_column_name() 返回第N列的字段名. sqlite3_column_bytes() 用来返回 UTF-8 编码的BLOBs列的字节数或者TEXT字符串的字节数. sqlite3_column_bytes16() 对于BLOBs列返回同样的结果,但是对于TEXT字符串则按 UTF-16 的编码来计算字节数. sqlite3_column_blob() 返回 BLOB 数据. sqlite3_column_text() 返回 UTF-8 编码的 TEXT 数据. sqlite3_column_text16() 返回 UTF-16 编码的 TEXT 数据. sqlite3_column_int() 以本地主机的整数格式返回一个整数值. sqlite3_column_int64() 返回一个64位的整数. 最后, sqlite3_column_double() 返回浮点数.

不一定非要按照sqlite3_column_type()接口返回的数据类型来获取数据. 数据类型不同时软件将自动转换.

(3)用户自定义函数

可以使用以下的方法来创建用户自定义的SQL函数:

typedef struct sqlite3_value sqlite3_value;int sqlite3_create_function( sqlite3 *, const char *zFunctionName, int nArg, int eTextRep, void*, void (*xFunc)(sqlite3_context*,int,sqlite3_value**), void (*xStep)(sqlite3_context*,int,sqlite3_value**), void (*xFinal)(sqlite3_context*) ); int sqlite3_create_function16( sqlite3*, const void *zFunctionName, int nArg, int eTextRep, void*, void (*xFunc)(sqlite3_context*,int,sqlite3_value**), void (*xStep)(sqlite3_context*,int,sqlite3_value**), void (*xFinal)(sqlite3_context*) ); #define SQLITE_UTF8 1 #define SQLITE_UTF16 2 #define SQLITE_UTF16BE 3 #define SQLITE_UTF16LE 4 #define SQLITE_ANY 5

nArg 参数用来表明自定义函数的参数个数. 如果参数值为0,则表示接受任意个数的参数. 用 eTextRep 参数来表明传入参数的编码形式. 参数值可以是上面的五种预定义值. SQLite3 允许同一个自定义函数有多种不同的编码参数的版本. 数据库引擎会自动选择转换参数编码个数最少的版本使用.

普通的函数只需要设置 xFunc 参数,而把 xStep 和 xFinal 设为NULL. 聚合函数则需要设置 xStep 和 xFinal 参数,然后把 xFunc 设为NULL. 该方法和使用sqlite3_create_aggregate() API一样.

sqlite3_create_function16()和sqlite_create_function()的不同就在于自定义的函数名一个要求是 UTF-16 编码,而另一个则要求是 UTF-8.

请注意自定函数的参数目前使用了sqlite3_value结构体指针替代了SQLite version 2.X中的字符串指针. 下面的函数用来从sqlite3_value结构体中提取数据:

const void *sqlite3_value_blob(sqlite3_value*); int sqlite3_value_bytes(sqlite3_value*); int sqlite3_value_bytes16(sqlite3_value*); double sqlite3_value_double(sqlite3_value*); int sqlite3_value_int(sqlite3_value*); long long int sqlite3_value_int64(sqlite3_value*); const unsigned char *sqlite3_value_text(sqlite3_value*); const void *sqlite3_value_text16(sqlite3_value*); int sqlite3_value_type(sqlite3_value*);

上面的函数调用以下的API来获得上下文内容和返回结果:

void *sqlite3_aggregate_context(sqlite3_context*, int nbyte); void *sqlite3_user_data(sqlite3_context*); void sqlite3_result_blob(sqlite3_context*, const void*, int n, void(*)(void*)); void qlite3_result_double(sqlite3_context*, double); void sqlite3_result_error(sqlite3_context*, const char*, int); void sqlite3_result_error16(sqlite3_context*, const void*, int); void sqlite3_result_int(sqlite3_context*, int); void sqlite3_result_int64(sqlite3_context*, long long int); void sqlite3_result_null(sqlite3_context*); void sqlite3_result_text(sqlite3_context*, const char*, int n, void(*)(void*)); void sqlite3_result_text16(sqlite3_context*, const void*, int n, void(*)(void*)); void sqlite3_result_value(sqlite3_context*, sqlite3_value*); void *sqlite3_get_auxdata(sqlite3_context*, int); void sqlite3_set_auxdata(sqlite3_context*, int, void*, void (*)(void*));

(4)用户自定义排序规则

下面的函数用来实现用户自定义的排序规则:

sqlite3_create_collation(sqlite3*, const char *zName, int eTextRep, void*,int(*xCompare)(void*,int,const void*,int,const void*));sqlite3_create_collation16(sqlite3*, const void *zName, int eTextRep, void*,int(*xCompare)(void*,int,const void*,int,const void*));sqlite3_collation_needed(sqlite3*, void*,void(*)(void*,sqlite3*,int eTextRep,const char*));sqlite3_collation_needed16(sqlite3*, void*,void(*)(void*,sqlite3*,int eTextRep,const void*));

sqlite3_create_collation() 函数用来声明一个排序序列和实现它的比较函数. 比较函数只能用来做文本的比较. eTextRep 参数可以取如下的预定义值 SQLITE_UTF8, SQLITE_UTF16LE, SQLITE_UTF16BE, SQLITE_ANY,用来表示比较函数所处理的文本的编码方式. 同一个自定义的排序规则的同一个比较函数可以有 UTF-8, UTF-16LE 和 UTF-16BE 等多个编码的版本. sqlite3_create_collation16()和sqlite3_create_collation() 的区别也仅仅在于排序名称的编码是 UTF-16 还是 UTF-8.

可以使用 sqlite3_collation_needed() 函数来注册一个回调函数,当数据库引擎遇到未知的排序规则时会自动调用该函数. 在回调函数中可以查找一个相似的比较函数,并激活相应的sqlite_3_create_collation()函数. 回调函数的第四个参数是排序规则的名称,同样sqlite3_collation_needed采用 UTF-8 编码. sqlite3_collation_need16() 采用 UTF-16 编码.

五、给数据库加密

前面所说的内容网上已经有很多资料,虽然比较零散,但是花点时间也还是可以找到的,

现在要说的这个――数据库加密,资料就很难找。也可能是我操作水平不够,找不到对应资料。但不管这样,我还是通过网上能找到的很有限的资料,探索出了给sqlite数据库加密的完整步骤。

这里要提一下,虽然 sqlite 很好用,速度快、体积小巧。但是它保存的文件却是明文的。若不信可以用 NotePad 打开数据库文件瞧瞧,里面 insert 的内容几乎一览无余。这样赤裸裸的展现自己,可不是我们的初衷。当然,如果你在嵌入式系统、智能手机上使用 sqlite,最好是不加密,因为这些系统运算能力有限,你做为一个新功能提供者,不能把用户有限的运算能力全部花掉。

Sqlite为了速度而诞生。因此Sqlite本身不对数据库加密,要知道,如果你选择标准AES算法加密,那么一定有接近50%的时间消耗在加解密算法上,甚至更多(性能主要取决于你算法编写水平以及你是否能使用cpu提供的底层运算能力,比如MMX或sse系列指令可以大幅度提升运算速度)。

Sqlite免费版本是不提供加密功能的,当然你也可以选择他们的收费版本,那你得支付2000块钱,而且是USD。我这里也不是说支付钱不好,如果只为了数据库加密就去支付2000块,我觉得划不来。因为下面我将要告诉你如何为免费的Sqlite扩展出加密模块――自己动手扩展,这是Sqlite允许,也是它提倡的。

那么,就让我们一起开始为 sqlite3.c 文件扩展出加密模块。

1 必要的宏

通过阅读 Sqlite 代码(当然没有全部阅读完,6万多行代码,没有一行是我习惯的风格,我可没那么多眼神去看),我搞清楚了两件事:

Sqlite是支持加密扩展的;

需要 #define 一个宏才能使用加密扩展。

这个宏就是 SQLITE_HAS_CODEC。

你在代码最前面(也可以在 sqlite3.h 文件第一行)定义:

#ifndef SQLITE_HAS_CODEC

#define SQLITE_HAS_CODEC

#endif

如果你在代码里定义了此宏,但是还能够正常编译,那么应该是操作没有成功。因为你应该会被编译器提示有一些函数无法链接才对。如果你用的是 VC 2003,你可以在“解决方案”里右键点击你的工程,然后选“属性”,找到“C/C++”,再找到“命令行”,在里面手工添加“/D “SQLITE_HAS_CODEC””。

定义了这个宏,一些被 Sqlite 故意屏蔽掉的代码就被使用了。这些代码就是加解密的接口。

尝试编译,vc会提示你有一些函数无法链接,因为找不到他们的实现。

如果你也用的是VC2003,那么会得到下面的提示:

error LNK2019: 无法解析的外部符号 _sqlite3CodecGetKey ,该符号在函数 _attachFunc 中被引用

error LNK2019: 无法解析的外部符号 _sqlite3CodecAttach ,该符号在函数 _attachFunc 中被引用

error LNK2019: 无法解析的外部符号 _sqlite3_activate_see ,该符号在函数 _sqlite3Pragma 中被引用

error LNK2019: 无法解析的外部符号 _sqlite3_key ,该符号在函数 _sqlite3Pragma 中被引用

fatal error LNK1120: 4 个无法解析的外部命令

这是正常的,因为Sqlite只留了接口而已,并没有给出实现。

下面就让我来实现这些接口。

2自己实现加解密接口函数

如果真要我从一份 www.sqlite.org 网上down下来的 sqlite3.c 文件,直接摸索出这些接口的实现,我认为我还没有这个能力。

好在网上还有一些代码已经实现了这个功能。通过参照他们的代码以及不断编译中vc给出的错误提示,最终我把整个接口整理出来。

实现这些预留接口不是那么容易,要重头说一次怎么回事很困难。我把代码都写好了,直接把他们按我下面的说明拷贝到 sqlite3.c 文件对应地方即可。我在下面也提供了sqlite3.c 文件,可以直接参考或取下来使用。

这里要说一点的是,我另外新建了两个文件:crypt.c和crypt.h。

其中crypt.h如此定义:

#ifndef DCG_SQLITE_CRYPT_FUNC_#define DCG_SQLITE_CRYPT_FUNC_/***********董淳光写的 SQLITE 加密关键函数库***********//***********关键加密函数***********/int My_Encrypt_Func( unsigned char * pData, unsigned int data_len, const char * key, unsigned int len_of_key );/***********关键解密函数***********/int My_DeEncrypt_Func( unsigned char * pData, unsigned int data_len, const char * key, unsigned intlen_of_key );#endif其中的 crypt.c 如此定义:#include “./crypt.h”#include “memory.h”/***********关键加密函数***********/int My_Encrypt_Func( unsigned char * pData, unsigned int data_len, const char * key, unsigned int len_of_key ){return 0;}/***********关键解密函数***********/int My_DeEncrypt_Func( unsigned char * pData, unsigned int data_len, const char * key, unsigned intlen_of_key ){return 0;}

这个文件很容易看,就两函数,一个加密一个解密。传进来的参数分别是待处理的数据、数据长度、密钥、密钥长度。

处理时直接把结果作用于 pData 指针指向的内容。

你需要定义自己的加解密过程,就改动这两个函数,其它部分不用动。扩展起来很简单。

这里有个特点,data_len 一般总是 1024 字节。正因为如此,你可以在你的算法里使用一些特定长度的加密算法,比如AES要求被加密数据一定是128位(16字节)长。这个1024不是碰巧,而是 Sqlite 的页定义是1024字节,在sqlite3.c文件里有定义:

# define SQLITE_DEFAULT_PAGE_SIZE 1024

你可以改动这个值,不过还是建议没有必要不要去改它。

上面写了两个扩展函数,如何把扩展函数跟 Sqlite 挂接起来,这个过程说起来比较麻烦。我直接贴代码。

分3个步骤。

首先,在 sqlite3.c 文件顶部,添加下面内容:

#ifdef SQLITE_HAS_CODEC#include “./crypt.h”/***********

用于在 sqlite3 最后关闭时释放一些内存

***********/void sqlite3pager_free_codecarg(void *pArg);#endif

这个函数之所以要在 sqlite3.c 开头声明,是因为下面在 sqlite3.c 里面某些函数里要插入这个函数调用。所以要提前声明。

其次,在sqlite3.c文件里搜索“sqlite3PagerClose”函数,要找到它的实现代码(而不是声明代码)。

实现代码里一开始是:

#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT /* A malloc() cannot fail in sqlite3ThreadData() as one or more calls to ** malloc() must have already been made by this thread before it gets ** to this point. This means the ThreadData must have been allocated already ** so that ThreadData.nAlloc can be set. */ ThreadData *pTsd = sqlite3ThreadData(); assert( pPager ); assert( pTsd && pTsd->nAlloc );#endif

需要在这部分后面紧接着插入:

#ifdef SQLITE_HAS_CODEC sqlite3pager_free_codecarg(pPager->pCodecArg);#endif

这里要注意,sqlite3PagerClose 函数大概也是 3.3.17版本左右才改名的,以前版本里是叫 “sqlite3pager_close”。因此你在老版本sqlite代码里搜索“sqlite3PagerClose”是搜不到的。

类似的还有“sqlite3pager_get”、“sqlite3pager_unref”、“sqlite3pager_write”、“sqlite3pager_pagecount”等都是老版本函数,它们在 pager.h 文件里定义。新版本对应函数是在 sqlite3.h 里定义(因为都合并到 sqlite3.c和sqlite3.h两文件了)。所以,如果你在使用老版本的sqlite,先看看 pager.h 文件,这些函数不是消失了,也不是新蹦出来的,而是老版本函数改名得到的。

最后,往sqlite3.c 文件下找。找到最后一行:

/************** End of main.c ************************************************/

在这一行后面,接上本文最下面的代码段。

这些代码很长,我不再解释,直接接上去就得了。

唯一要提的是 DeriveKey 函数。这个函数是对密钥的扩展。比如,你要求密钥是128位,即是16字节,但是如果用户只输入 1个字节呢?2个字节呢?或输入50个字节呢?你得对密钥进行扩展,使之符合16字节的要求。

DeriveKey 函数就是做这个扩展的。有人把接收到的密钥求md5,这也是一个办法,因为md5运算结果固定16字节,不论你有多少字符,最后就是16字节。这是md5算法的特点。但是我不想用md5,因为还得为它添加包含一些 md5 的.c或.cpp文件。我不想这么做。我自己写了一个算法来扩展密钥,很简单的算法。当然,你也可以使用你的扩展方法,也而可以使用md5 算法。只要修改 DeriveKey 函数就可以了。

在 DeriveKey 函数里,只管申请空间构造所需要的密钥,不需要释放,因为在另一个函数里有释放过程,而那个函数会在数据库关闭时被调用。参考我的 DeriveKey 函数来申请内存。

这里我给出我已经修改好的 sqlite3.c 和 sqlite3.h 文件。

如果太懒,就直接使用这两个文件,编译肯定能通过,运行也正常。当然,你必须按我前面提的,新建 crypt.h 和crypt.c 文件,而且函数要按我前面定义的要求来做。

3 加密使用方法

现在,你代码已经有了加密功能。

你要把加密功能给用上,除了改 sqlite3.c 文件、给你工程添加 SQLITE_HAS_CODEC 宏,还得修改你的数据库调用函数。

前面提到过,要开始一个数据库操作,必须先 sqlite3_open 。

加解密过程就在 sqlite3_open 后面操作。

假设你已经 sqlite3_open 成功了,紧接着写下面的代码:

int i;

//添加、使用密码

i = sqlite3_key( db, “dcg”, 3 );

//修改密码

i = sqlite3_rekey( db, “dcg”, 0 );

用 sqlite3_key 函数来提交密码。

第1个参数是 sqlite3 * 类型变量,代表着用 sqlite3_open 打开的数据库(或新建数据库)。

第2个参数是密钥。

第3个参数是密钥长度。

用 sqlite3_rekey 来修改密码。参数含义同 sqlite3_key。

实际上,你可以在sqlite3_open函数之后,到 sqlite3_close 函数之前任意位置调用 sqlite3_key 来设置密码。

但是如果你没有设置密码,而数据库之前是有密码的,那么你做任何操作都会得到一个返回值:SQLITE_NOTADB,并且得到错误提示:“file is encrypted or is not a database”。

只有当你用 sqlite3_key 设置了正确的密码,数据库才会正常工作。

如果你要修改密码,前提是你必须先 sqlite3_open 打开数据库成功,然后 sqlite3_key 设置密钥成功,之后才能用sqlite3_rekey 来修改密码。

如果数据库有密码,但你没有用 sqlite3_key 设置密码,那么当你尝试用 sqlite3_rekey 来修改密码时会得到SQLITE_NOTADB 返回值。

如果你需要清空密码,可以使用:

//修改密码

i = sqlite3_rekey( db, NULL, 0 );

来完成密码清空功能。

4 sqlite3.c 最后添加代码段

/***董淳光定义的加密函数***/#ifdef SQLITE_HAS_CODEC/***加密结构***/#define CRYPT_OFFSET 8typedef struct _CryptBlock{BYTE* ReadKey; // 读数据库和写入事务的密钥BYTE* WriteKey; // 写入数据库的密钥int PageSize; // 页的大小BYTE* Data;} CryptBlock, *LPCryptBlock;#ifndef DB_KEY_LENGTH_BYTE /*密钥长度*/#define DB_KEY_LENGTH_BYTE 16 /*密钥长度*/#endif#ifndef DB_KEY_PADDING /*密钥位数不足时补充的字符*/#define DB_KEY_PADDING 0x33 /*密钥位数不足时补充的字符*/#endif/*** 下面是编译时提示缺少的函数 ***//** 这个函数不需要做任何处理,获取密钥的部分在下面 DeriveKey 函数里实现 **/void sqlite3CodecGetKey(sqlite3* db, int nDB, void** Key, int* nKey){return ;}/*被sqlite 和 sqlite3_key_interop 调用, 附加密钥到数据库.*/int sqlite3CodecAttach(sqlite3 *db, int nDb, const void *pKey, int nKeyLen);/**这个函数好像是 sqlite 3.3.17前不久才加的,以前版本的sqlite里没有看到这个函数这个函数我还没有搞清楚是做什么的,它里面什么都不做直接返回,对加解密没有影响**/void sqlite3_activate_see(const char* right ){ return;}int sqlite3_key(sqlite3 *db, const void *pKey, int nKey);int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey);/***下面是上面的函数的辅助处理函数***/// 从用户提供的缓冲区中得到一个加密密钥// 用户提供的密钥可能位数上满足不了要求,使用这个函数来完成密钥扩展static unsigned char * DeriveKey(const void *pKey, int nKeyLen);//创建或更新一个页的加密算法索引.此函数会申请缓冲区.static LPCryptBlock CreateCryptBlock(unsigned char* hKey, Pager *pager, LPCryptBlock pExisting);//加密/解密函数, 被pager调用void * sqlite3Codec(void *pArg, unsigned char *data, Pgno nPageNum, int nMode);//设置密码函数int __stdcall sqlite3_key_interop(sqlite3 *db, const void *pKey, int nKeySize);// 修改密码函数int __stdcall sqlite3_rekey_interop(sqlite3 *db, const void *pKey, int nKeySize);//销毁一个加密块及相关的缓冲区,密钥.static void DestroyCryptBlock(LPCryptBlock pBlock);static void * sqlite3pager_get_codecarg(Pager *pPager);void sqlite3pager_set_codec(Pager *pPager,void *(*xCodec)(void*,void*,Pgno,int),void *pCodecArg );//加密/解密函数, 被pager调用void * sqlite3Codec(void *pArg, unsigned char *data, Pgno nPageNum, int nMode){LPCryptBlock pBlock = (LPCryptBlock)pArg;unsigned int dwPageSize = 0;if (!pBlock) return data;// 确保pager的页长度和加密块的页长度相等.如果改变,就需要调整.if (nMode != 2){ PgHdr *pageHeader; pageHeader = DATA_TO_PGHDR(data); if (pageHeader->pPager->pageSize != pBlock->PageSize) { CreateCryptBlock(0, pageHeader->pPager, pBlock); }}switch(nMode){case 0: // Undo a “case 7” journal file encryptioncase 2: //重载一个页case 3: //载入一个页 if (!pBlock->ReadKey) break; dwPageSize = pBlock->PageSize; My_DeEncrypt_Func(data, dwPageSize, pBlock->ReadKey, DB_KEY_LENGTH_BYTE ); /*调用我的解密函数*/ break;case 6: //加密一个主数据库文件的页 if (!pBlock->WriteKey) break; memcpy(pBlock->Data + CRYPT_OFFSET, data, pBlock->PageSize); data = pBlock->Data + CRYPT_OFFSET; dwPageSize = pBlock->PageSize; My_Encrypt_Func(data , dwPageSize, pBlock->WriteKey, DB_KEY_LENGTH_BYTE ); /*调用我的加密函数*/ break;case 7: //加密事务文件的页 /*在正常环境下, 读密钥和写密钥相同. 当数据库是被重新加密的,读密钥和写密钥未必相同. 回滚事务必要用数据库文件的原始密钥写入.因此,当一次回滚被写入,总是用数据库的读密钥, 这是为了保证与读取原始数据的密钥相同. */ if (!pBlock->ReadKey) break; memcpy(pBlock->Data + CRYPT_OFFSET, data, pBlock->PageSize); data = pBlock->Data + CRYPT_OFFSET; dwPageSize = pBlock->PageSize; My_Encrypt_Func( data, dwPageSize, pBlock->ReadKey, DB_KEY_LENGTH_BYTE ); /*调用我的加密函数*/ break;}return data;}//销毁一个加密块及相关的缓冲区,密钥.static void DestroyCryptBlock(LPCryptBlock pBlock){//销毁读密钥.if (pBlock->ReadKey){ sqliteFree(pBlock->ReadKey);}//如果写密钥存在并且不等于读密钥,也销毁.if (pBlock->WriteKey && pBlock->WriteKey != pBlock->ReadKey){ sqliteFree(pBlock->WriteKey);}if(pBlock->Data){ sqliteFree(pBlock->Data);}//释放加密块.sqliteFree(pBlock);}static void * sqlite3pager_get_codecarg(Pager *pPager){return (pPager->xCodec) ? pPager->pCodecArg: NULL;}// 从用户提供的缓冲区中得到一个加密密钥static unsigned char * DeriveKey(const void *pKey, int nKeyLen){unsigned char * hKey = NULL;int j;if( pKey == NULL || nKeyLen == 0 ){ return NULL;}hKey = sqliteMalloc( DB_KEY_LENGTH_BYTE + 1 );if( hKey == NULL ){ return NULL;}hKey[ DB_KEY_LENGTH_BYTE ] = 0;if( nKeyLen < DB_KEY_LENGTH_BYTE ){ memcpy( hKey, pKey, nKeyLen ); //先拷贝得到密钥前面的部分 j = DB_KEY_LENGTH_BYTE - nKeyLen; //补充密钥后面的部分 memset( hKey + nKeyLen, DB_KEY_PADDING, j );}else{ //密钥位数已经足够,直接把密钥取过来 memcpy( hKey, pKey, DB_KEY_LENGTH_BYTE );}return hKey;}//创建或更新一个页的加密算法索引.此函数会申请缓冲区.static LPCryptBlock CreateCryptBlock(unsigned char* hKey, Pager *pager, LPCryptBlock pExisting){LPCryptBlock pBlock;if (!pExisting) //创建新加密块{ pBlock = sqliteMalloc(sizeof(CryptBlock)); memset(pBlock, 0, sizeof(CryptBlock)); pBlock->ReadKey = hKey; pBlock->WriteKey = hKey; pBlock->PageSize = pager->pageSize; pBlock->Data = (unsigned char*)sqliteMalloc(pBlock->PageSize + CRYPT_OFFSET);}else //更新存在的加密块{ pBlock = pExisting; if ( pBlock->PageSize != pager->pageSize && !pBlock->Data){ sqliteFree(pBlock->Data); pBlock->PageSize = pager->pageSize; pBlock->Data = (unsigned char*)sqliteMalloc(pBlock->PageSize + CRYPT_OFFSET); }}memset(pBlock->Data, 0, pBlock->PageSize + CRYPT_OFFSET);return pBlock;}/*** Set the codec for this pager*/void sqlite3pager_set_codec( Pager *pPager, void *(*xCodec)(void*,void*,Pgno,int), void *pCodecArg ){pPager->xCodec = xCodec;pPager->pCodecArg = pCodecArg;}int sqlite3_key(sqlite3 *db, const void *pKey, int nKey){return sqlite3_key_interop(db, pKey, nKey);}int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey){return sqlite3_rekey_interop(db, pKey, nKey);}/*被sqlite 和 sqlite3_key_interop 调用, 附加密钥到数据库.*/int sqlite3CodecAttach(sqlite3 *db, int nDb, const void *pKey, int nKeyLen){ int rc = SQLITE_ERROR; unsigned char* hKey = 0; //如果没有指定密匙,可能标识用了主数据库的加密或没加密. if (!pKey || !nKeyLen) { if (!nDb) {return SQLITE_OK; //主数据库, 没有指定密钥所以没有加密. } else //附加数据库,使用主数据库的密钥. {//获取主数据库的加密块并复制密钥给附加数据库使用LPCryptBlock pBlock = (LPCryptBlock)sqlite3pager_get_codecarg(sqlite3BtreePager(db->aDb[0].pBt));if (!pBlock) return SQLITE_OK; //主数据库没有加密if (!pBlock->ReadKey) return SQLITE_OK; //没有加密memcpy(pBlock->ReadKey, &hKey, 16); } } else //用户提供了密码,从中创建密钥. { hKey = DeriveKey(pKey, nKeyLen); } //创建一个新的加密块,并将解码器指向新的附加数据库. if (hKey) { LPCryptBlock pBlock = CreateCryptBlock(hKey, sqlite3BtreePager(db->aDb[nDb].pBt), NULL); sqlite3pager_set_codec(sqlite3BtreePager(db->aDb[nDb].pBt), sqlite3Codec, pBlock); rc = SQLITE_OK; } return rc;}// Changes the encryption key for an existing database.int __stdcall sqlite3_rekey_interop(sqlite3 *db, const void *pKey, int nKeySize){Btree *pbt = db->aDb[0].pBt;Pager *p = sqlite3BtreePager(pbt);LPCryptBlock pBlock = (LPCryptBlock)sqlite3pager_get_codecarg(p);unsigned char * hKey = DeriveKey(pKey, nKeySize);int rc = SQLITE_ERROR;if (!pBlock && !hKey) return SQLITE_OK;//重新加密一个数据库,改变pager的写密钥, 读密钥依旧保留.if (!pBlock) //加密一个未加密的数据库{ pBlock = CreateCryptBlock(hKey, p, NULL); pBlock->ReadKey = 0; // 原始数据库未加密 sqlite3pager_set_codec(sqlite3BtreePager(pbt), sqlite3Codec, pBlock);}else // 改变已加密数据库的写密钥{ pBlock->WriteKey = hKey;}// 开始一个事务rc = sqlite3BtreeBeginTrans(pbt, 1);if (!rc){ // 用新密钥重写所有的页到数据库。 Pgno nPage = sqlite3PagerPagecount(p); Pgno nSkip = PAGER_MJ_PGNO(p); void *pPage; Pgno n; for(n = 1; rc == SQLITE_OK && n <= nPage; n ++) { if (n == nSkip) continue; rc = sqlite3PagerGet(p, n, &pPage); if(!rc) { rc = sqlite3PagerWrite(pPage); sqlite3PagerUnref(pPage); } }}// 如果成功,提交事务。if (!rc){ rc = sqlite3BtreeCommit(pbt);}// 如果失败,回滚。if (rc){ sqlite3BtreeRollback(pbt);}// 如果成功,销毁先前的读密钥。并使读密钥等于当前的写密钥。if (!rc){ if (pBlock->ReadKey) { sqliteFree(pBlock->ReadKey); } pBlock->ReadKey = pBlock->WriteKey;}else// 如果失败,销毁当前的写密钥,并恢复为当前的读密钥。{ if (pBlock->WriteKey) { sqliteFree(pBlock->WriteKey); } pBlock->WriteKey = pBlock->ReadKey;}// 如果读密钥和写密钥皆为空,就不需要再对页进行编解码。// 销毁加密块并移除页的编解码器if (!pBlock->ReadKey && !pBlock->WriteKey){ sqlite3pager_set_codec(p, NULL, NULL); DestroyCryptBlock(pBlock);}return rc;}/***下面是加密函数的主体***/int __stdcall sqlite3_key_interop(sqlite3 *db, const void *pKey, int nKeySize){ return sqlite3CodecAttach(db, 0, pKey, nKeySize);}// 释放与一个页相关的加密块void sqlite3pager_free_codecarg(void *pArg){if (pArg) DestroyCryptBlock((LPCryptBlock)pArg);}#endif //#ifdef SQLITE_HAS_CODEC

五、性能优化

很多人直接就使用了,并未注意到SQLite也有配置参数,可以对性能进行调整。有时候,产生的结果会有很大影响。

主要通过pragma指令来实现。

比如: 空间释放、磁盘同步、Cache大小等。

不要打开。前文提高了,Vacuum的效率非常低!

1 auto_vacuum

PRAGMA auto_vacuum;

PRAGMA auto_vacuum = 0 | 1;

查询或设置数据库的auto-vacuum标记。

正常情况下,当提交一个从数据库中删除数据的事务时,数据库文件不改变大小。未使用的文件页被标记并在以后的添加操作中再次使用。这种情况下使用VACUUM命令释放删除得到的空间。

当开启auto-vacuum,当提交一个从数据库中删除数据的事务时,数据库文件自动收缩, (VACUUM命令在auto-vacuum开启的数据库中不起作用)。数据库会在内部存储一些信息以便支持这一功能,这使得数据库文件比不开启该选项时稍微大一些。

只有在数据库中未建任何表时才能改变auto-vacuum标记。试图在已有表的情况下修改不会导致报错。

2 cache_size

建议改为8000

PRAGMA cache_size;

PRAGMA cache_size = Number-of-pages;

查询或修改SQLite一次存储在内存中的数据库文件页数。每页使用约1.5K内存,缺省的缓存大小是2000. 若需要使用改变大量多行的UPDATE或DELETE命令,并且不介意SQLite使用更多的内存的话,可以增大缓存以提高性能。

当使用cache_size pragma改变缓存大小时,改变仅对当前对话有效,当数据库关闭重新打开时缓存大小恢复到缺省大小。 要想永久改变缓存大小,使用default_cache_size pragma.

3 case_sensitive_like

打开。不然搜索中文字串会出错。

PRAGMA case_sensitive_like;

PRAGMA case_sensitive_like = 0 | 1;

LIKE运算符的缺省行为是忽略latin1字符的大小写。因此在缺省情况下‘a‘ LIKE ‘A‘的值为真。可以通过打开case_sensitive_like pragma来改变这一缺省行为。当启用case_sensitive_like,‘a‘ LIKE ‘A‘为假而 ‘a‘ LIKE ‘a‘依然为真。

4 count_changes

打开。便于调试

PRAGMA count_changes;

PRAGMA count_changes = 0 | 1;

查询或更改count-changes标记。正常情况下INSERT, UPDATE和DELETE语句不返回数据。 当开启count-changes,以上语句返回一行含一个整数值的数据――该语句插入,修改或删除的行数。 返回的行数不包括由触发器产生的插入,修改或删除等改变的行数。

5 page_size

PRAGMA page_size;

PRAGMA page_size = bytes;

查询或设置page-size值。只有在未创建数据库时才能设置page-size。页面大小必须是2的整数倍且大于等于512小于等于8192。 上限可以通过在编译时修改宏定义SQLITE_MAX_PAGE_SIZE的值来改变。上限的上限是32768.

6 synchronous

如果有定期备份的机制,而且少量数据丢失可接受,用OFF

PRAGMA synchronous;

PRAGMA synchronous = FULL; (2)

PRAGMA synchronous = NORMAL; (1)

PRAGMA synchronous = OFF; (0)

查询或更改“synchronous”标记的设定。第一种形式(查询)返回整数值。 当synchronous设置为FULL (2), SQLite数据库引擎在紧急时刻会暂停以确定数据已经写入磁盘。 这使系统崩溃或电源出问题时能确保数据库在重起后不会损坏。FULL synchronous很安全但很慢。 当synchronous设置为NORMAL, SQLite数据库引擎在大部分紧急时刻会暂停,但不像FULL模式下那么频繁。 NORMAL模式下有很小的几率(但不是不存在)发生电源故障导致数据库损坏的情况。但实际上,在这种情况下很可能你的硬盘已经不能使用,或者发生了其他的不可恢复的硬件错误。 设置为synchronous OFF (0)时,SQLite在传递数据给系统以后直接继续而不暂停。若运行SQLite的应用程序崩溃, 数据不会损伤,但在系统崩溃或写入数据时意外断电的情况下数据库可能会损坏。另一方面,在synchronous OFF时 一些操作可能会快50倍甚至更多。

在SQLite 2中,缺省值为NORMAL.而在3中修改为FULL.

7 temp_store

使用2,内存模式。

PRAGMA temp_store;

PRAGMA temp_store = DEFAULT; (0)

PRAGMA temp_store = FILE; (1)

PRAGMA temp_store = MEMORY; (2)

查询或更改“temp_store”参数的设置。当temp_store设置为DEFAULT (0),使用编译时的C预处理宏 TEMP_STORE来定义储存临时表和临时索引的位置。当设置为MEMORY (2)临时表和索引存放于内存中。 当设置为FILE (1)则存放于文件中。temp_store_directorypragma 可用于指定存放该文件的目录。当改变temp_store设置,所有已存在的临时表,索引,触发器及视图将被立即删除。

经测试,在类BBS应用上,通过以上调整,效率可以提高2倍以上。

六、后记

(原文后记)

写此教程,可不是一个累字能解释。

但是我还是觉得欣慰的,因为我很久以前就想写 sqlite 的教程,一来自己备忘,二而已造福大众,大家不用再走弯路。

本人第一次写教程,不足的地方请大家指出。

本文可随意转载、修改、引用。但无论是转载、修改、引用,都请附带我的名字:董淳光。以示对我劳动的肯定。

(补充后记)

篇8:专项资金使用总结

根据省环境保护厅统一安排,芜湖县环境保护监测站于20xx年9月申报了《安徽省20xx年中央财政主要污染物减排专项资金项目建设方案》,共计总资金93。4万元。同年10月16日,财政部以财建〔20xx〕676号《财政部关于下达20xx年主要污染物减排专项资金项目预算的通知》的文件,安排了我县52万元的专项资金,随即安徽省环境保护厅以皖环传〔20xx〕19号下达了《关于召开20xx年监测能力建设项目实施工作会议的通知》,并于12月9日召开了专题会议,进一步规范环境监测能力建设专项资金使用,要求不得挪用、挤占或截留,仅限用于规定的环境监测仪器和设备。

会后,芜湖县环境保护局高度重视,确定监测站站长为项目落实的首要责任人,具体落实项目实施。县环境监测站非常重视专项资金的使用,按照省环保厅的要求,于20xx年2月23日上报了20xx年中央财政主要污染物减排专项资金项目采购计划,并附所采购的仪器设备名称、数量及产品技术参数及要求,在得到省环境监测中心站同意后进入招标采购程序,并与县政府招标采购中心取得联系,进行公开招标采购。为考虑采购方便,经与采购中心协商,本次专项资金共分四个包进行采购,一是环境空气监测仪器,二是水质理化、采样及其他仪器,三是电脑,四是环境监测车,预算总资金52万元。采购工作分别于20xx年4月12日——4月29日完成,并在招标中心的鉴证下签订相关合同,完成了53万元的采购任务。所采购的仪器设备分别于20xx年6月2日——7月21日送达到监测站,并进行相关验收工作,对于大型仪器,生产厂家也即时进行了现场培训。

本次仪器设备的采购得到了省环境监测中心站的大力支持,专项资金所采购的仪器设备部分补充了我站仪器设备的不足,提高了我县环境监测能力,对照《全国环境监测站建设标准》,目前我县监测站与标准仍存在很大的差距,特别是缺乏应急监测仪器和装备,望得到上级进一步支持和关心,我们将用好资金,发挥专项资金应有的作用,为环境管理和环境监督提供更好更快的监测数据。

篇9:mysqlslap 使用总结

mysqlslap 可以用于模拟服务器的负载,并输出计时信息,其被包含在 MySQL 5.1 的发行包中。测试时,可以指定并发连接数,可以指定 SQL 语句。如果没有指定 SQL 语句,mysqlslap 会自动生成查询 schema 的 SELECT 语句。

1. 查看帮助信息。

[root@Betty libmysql]# mysqlslap --helpmysqlslap Ver 1.0 Distrib 5.6.10, for Linux (x86_64)Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.Oracle is a registered trademark of Oracle Corporation and/or itsaffiliates. Other names may be trademarks of their respectiveowners.Run a query multiple times against the server.Usage: mysqlslap [OPTIONS]Default options are read from the following files in the given order:/etc/my.cnf /etc/mysql/my.cnf /usr/local/mysql/etc/my.cnf ~/.my.cnf The following groups are read: mysqlslap clientThe following options may be given as the first argument:--print-defaults Print the program argument list and exit.--no-defaults Don't read default options from any option file,except for login file.--defaults-file=# Only read default options from the given file #.--defaults-extra-file=# Read this file after the global files are read.--defaults-group-suffix=#Also read groups with concat(group, suffix)--login-path=# Read this path from the login file. -?, --help Display this help and exit. -a, --auto-generate-sql 自动生成测试表和数据 Generate SQL where not supplied by file or command line. --auto-generate-sql-add-autoincrement 增加auto_increment一列 Add an AUTO_INCREMENT column to auto-generated tables. --auto-generate-sql-execute-number=# 自动生成的查询的个数 Set this number to generate a set number of queries to run. --auto-generate-sql-guid-primary 增加基于GUID的主键 Add GUID based primary keys to auto-generated tables. --auto-generate-sql-load-type=name 测试语句的类型。取值包括:read,key,write,update和mixed(默认) read:查询 write:插入 key:读主键 update:更新主键 mixed:一半插入一半查询 Specify test load type: mixed, update, write, key, or read; default is mixed. --auto-generate-sql-secondary-indexes=# 增加二级索引的个数,默认是0 Number of secondary indexes to add to auto-generated tables. --auto-generate-sql-unique-query-number=# 不同查询的数量,默认值是10 Number of unique queries to generate for automatic tests. --auto-generate-sql-unique-write-number=# 不同插入的数量,默认是100 Number of unique queries to generate for auto-generate-sql-write-number. --auto-generate-sql-write-number=# Number of row inserts to perform. for each thread (default is 100). --commit=# 多少条DML后提交一次 Commit records every X number of statements. -C, --compress如果服务器和客户端支持都压缩,则压缩信息传递 Use compression in server/client protocol. -c, --concurrency=name 模拟N个客户端并发执行select。可指定多个值,以逗号或者 --delimiter 参数指定的值做为分隔符 Number of clients to simulate for query to run. --create=name 指定用于创建表的.sql文件或者字串 File or string to use create tables. --create-schema=name 指定待测试的数据库名,MySQL中schema也就是database,默认是mysqlslap Schema to run tests in. --csv[=name] Generate CSV output to named file or to stdout if no file is named. -#, --debug[=#] This is a non-debug version. Catch this and exit. --debug-check Check memory and open file usage at exit. -T, --debug-info 打印内存和CPU的信息 Print some debug info at exit. --default-auth=name Default authentication client-side plugin to use. -F, --delimiter=name 文件中的SQL语句使用分割符号 Delimiter to use in SQL statements supplied in file or command line. --detach=# 每执行完N个语句,先断开再重新打开连接 Detach (close and reopen) connections after X number of requests. --enable-cleartext-plugin Enable/disable the clear text authentication plugin. -e, --engine=name 创建测试表所使用的存储引擎,可指定多个 Storage engine to use for creating the table. -h, --host=name Connect to host. -i, --iterations=# 迭代执行的次数 Number of times to run the tests. --no-drop Do not drop the schema after the test. -x, --number-char-cols=name 自动生成的测试表中包含多少个字符类型的列,默认1 Number of VARCHAR columns to create in table if specifying --auto-generate-sql. -y, --number-int-cols=name 自动生成的测试表中包含多少个数字类型的列,默认1 Number of INT columns to create in table if specifying --auto-generate-sql. --number-of-queries=# 总的测试查询次数(并发客户数×每客户查询次数) Limit each client to this number of queries (this is not exact). --only-print 只输出模拟执行的结果,不实际执行 Do not connect to the databases, but instead print out what would have been done. -p, --password[=name] Password to use when connecting to server. If password is not given it's asked from the tty. --plugin-dir=name Directory for client-side plugins. -P, --port=# Port number to use for connection. --post-query=name 测试完成以后执行的SQL语句的文件或者字符串 这个过程不影响时间计算 Query to run or file containing query to execute after tests have completed. --post-system=name 测试完成以后执行的系统语句 这个过程不影响时间计算 system string to execute after tests have completed. --pre-query=name 测试执行之前执行的SQL语句的文件或者字符串 这个过程不影响时间计算 Query to run or file containing query to execute before running tests. --pre-system=name 测试执行之前执行的系统语句 这个过程不影响时间计算 system() string to execute before running tests. --protocol=name The protocol to use for connection (tcp, socket, pipe, memory). -q, --query=name 指定自定义.sql脚本执行测试。例如可以调用自定义的一个存储过程或者sql语句来执行测试 Query to run or file containing query to run. -s, --silent 不输出 Run program in silent mode - no output. -S, --socket=name The socket file to use for connection. --ssl Enable SSL for connection (automatically enabled with other flags). --ssl-ca=name CA file in PEM format (check OpenSSL docs, implies --ssl). --ssl-capath=name CA directory (check OpenSSL docs, implies --ssl). --ssl-cert=name X509 cert in PEM format (implies --ssl). --ssl-cipher=name SSL cipher to use (implies --ssl). --ssl-key=nameX509 key in PEM format (implies --ssl). --ssl-crl=nameCertificate revocation list (implies --ssl). --ssl-crlpath=name Certificate revocation list path (implies --ssl). --ssl-verify-server-cert Verify server's “Common Name” in its cert against hostname used when connecting. This option is disabled by default. -u, --user=name User for login if not current user. -v, --verbose 输出更多的信息 More verbose output; you can use this multiple times to get even more verbose output. -V, --version Output version information and exit.[root@Betty libmysql]#

2. 以自动生成测试表和数据的形式,分别模拟 50 和 100 个客户端并发连接处理 1000 个 query 的情况。

[root@Betty libmysql]# mysqlslap -a --concurrency=50,100 --number-of-queries=1000 Benchmark Average number of seconds to run all queries: 0.148 seconds Minimum number of seconds to run all queries: 0.148 seconds Maximum number of seconds to run all queries: 0.148 seconds Number of clients running queries: 50 Average number of queries per client: 20Benchmark Average number of seconds to run all queries: 0.246 seconds Minimum number of seconds to run all queries: 0.246 seconds Maximum number of seconds to run all queries: 0.246 seconds Number of clients running queries: 100 Average number of queries per client: 10[root@Betty libmysql]#

3.增加 --debug-info 选项,可以输出内存和CPU信息。

[root@Betty libmysql]# mysqlslap -a --concurrency=50,100 --number-of-queries=1000 --debug-infoBenchmark Average number of seconds to run all queries: 0.202 seconds Minimum number of seconds to run all queries: 0.202 seconds Maximum number of seconds to run all queries: 0.202 seconds Number of clients running queries: 50 Average number of queries per client: 20Benchmark Average number of seconds to run all queries: 0.193 seconds Minimum number of seconds to run all queries: 0.193 seconds Maximum number of seconds to run all queries: 0.193 seconds Number of clients running queries: 100 Average number of queries per client: 10User time 0.09, System time 0.05Maximum resident set size 7848, Integral resident set size 0Non-physical pagefaults 4221, Physical pagefaults 0, Swaps 0Blocks in 0 out 0, Messages in 0 out 0, Signals 0Voluntary context switches 7314, Involuntary context switches 1400

4. 增加 --iterations 选项,可以重复执行 5 次

[root@Betty libmysql]# [root@Betty libmysql]# mysqlslap -a --concurrency=50,100 --number-of-queries=1000 --iterations=5 --debug-infoBenchmark Average number of seconds to run all queries: 0.168 seconds Minimum number of seconds to run all queries: 0.147 seconds Maximum number of seconds to run all queries: 0.217 seconds Number of clients running queries: 50 Average number of queries per client: 20Benchmark Average number of seconds to run all queries: 0.209 seconds Minimum number of seconds to run all queries: 0.156 seconds Maximum number of seconds to run all queries: 0.280 seconds Number of clients running queries: 100 Average number of queries per client: 10User time 0.47, System time 0.25Maximum resident set size 9848, Integral resident set size 0Non-physical pagefaults 16880, Physical pagefaults 0, Swaps 0Blocks in 0 out 0, Messages in 0 out 0, Signals 0Voluntary context switches 35954, Involuntary context switches 6583[root@Betty libmysql]#

5. 可以针对远程主机上的 mysql 进行测试。

[root@Betty Shell]# mysqlslap -a --concurrency=50,100 --number-of-queries=1000 -h 172.16.81.99 -P 3306 -pEnter password: Benchmark Average number of seconds to run all queries: 2.009 seconds Minimum number of seconds to run all queries: 2.009 seconds Maximum number of seconds to run all queries: 2.009 seconds Number of clients running queries: 50 Average number of queries per client: 20Benchmark Average number of seconds to run all queries: 4.519 seconds Minimum number of seconds to run all queries: 4.519 seconds Maximum number of seconds to run all queries: 4.519 seconds Number of clients running queries: 100 Average number of queries per client: 10[root@Betty Shell]#

6. 使用 --only-print 选项,可以查看 mysqlslap 在测试过程中如何执行的 sql 语句。在这种方式下,仅会对数据库进行模拟操作。如下显示的自动产生测试表和数据的情况下,mysqlslap 的执行过程:创建一个临时的库 mysqlslap ,并在测试结束是会将其删除。

[root@Betty libmysql]# mysqlslap -a --only-print DROP SCHEMA IF EXISTS `mysqlslap`;CREATE SCHEMA `mysqlslap`;use mysqlslap;CREATE TABLE `t1` (intcol1 INT(32) ,charcol1 VARCHAR(128));INSERT INTO t1 VALUES (1804289383,'mxvtvmC9127qJNm06sGB8R92q2j7vTiiITRDGXM9ZLzkdekbWtmXKwZ2qG1llkRw5m9DHOFilEREk3q7oce8O3BEJC0woJsm6uzFAEynLH2xCsw1KQ1lT4zg9rdxBL');INSERT INTO t1 VALUES (822890675,'97RGHZ65mNzkSrYT3zWoSbg9cNePQr1bzSk81qDgE4Oanw3rnPfGsBHSbnu1evTdFDe83ro9w4jjteQg4yoo9xHck3WNqzs54W5zEm92ikdRF48B2oz3m8gMBAl11W');INSERT INTO t1 VALUES (1308044878,'50w46i58Giekxik0cYzfA8BZBLADEg3JhzGfZDoqvQQk0Akcic7lcJInYSsf9wqin6LDC1vzJLkJXKn5onqOy04MTw1WksCYqPl2Jg2eteqOqTLfGCvE4zTZwWvgMz');INSERT INTO t1 VALUES (964445884,'DPh7kD1E6f4MMQk1ioopsoIIcoD83DD8Wu7689K6oHTAjD3Hts6lYGv8x9G0EL0k87q8G2ExJjz2o3KhnIJBbEJYFROTpO5pNvxgyBT9nSCbNO9AiKL9QYhi0x3hL9');INSERT INTO t1 VALUES (1586903190,'lwRHuWm4HE8leYmg66uGYIp6AnAr0BDd7YmuvYqCfqp9EbhKZRSymA4wx6gpHlJHI53DetH9j7Ixar90Jey5outd1ZIAJdJTjMaD7rMiqYXHFhHaB7Xr1HKuqe51GG');INSERT INTO t1 VALUES (962033002,'rfw4egILWisfxPwOc3nJx4frnAwgI539kr5EXFbupSZelM2MHqZEmD6ZNuEZzHib8fqYuHQbdrDND8lXqIdcNbAeWOBLZlpZOX5AoNlQFzpK7QjxcLP0wbWIriYGJL');INSERT INTO t1 VALUES (1910858270,'ksnug3YyANnWWDEJiRkiFC4a3e6KyJ2i3hSjksiuFLHlRXw9yhjDtnfoQd0OouyrcIbCB9zQWG4pf0yTZhaIT67nj7BY21FWJqaWrZxEh13Kt2hRbGl4MsrxsuLmvd');INSERT INTO t1 VALUES (63299708,'FJid3GaHpRC2L6jgirPm5AW3uGGgCloJ5Ww0eNHSiLWvS5bAxto23AxxR6TXr9qofeoAtxWcJsXnxzxmsdhvoekFc5mSES8tyxvsuPK5Hjs7ihtaJaLz5xEh2s1GCA');INSERT INTO t1 VALUES (737703662,'2zxutF6rOqjXYHHzSrKRwAhWCPXTdhNXYKQIRO9sEkFf1YeTGqw40Ta5u6QNfpvC1DWTTXDkFSFHtte9bbDSwgZjmryHglLhqjAKEF4MkJfT49eXcjzZNOG1F6BnsY');INSERT INTO t1 VALUES (1348361729,'i8X2EnycNH7sDHMltxcILtQE0ZPoPq9zyg24J0hiAgQNpg8jedtrWK5WtXIALR9B03FJ4ou6TCTAtWtN7fETzBzkiAmvTv6LrEZn2RtNfMaOkJfjytCp54ZfEJbb7Z');INSERT INTO t1 VALUES (1804289383,'mxvtvmC9127qJNm06sGB8R92q2j7vTiiITRDGXM9ZLzkdekbWtmXKwZ2qG1llkRw5m9DHOFilEREk3q7oce8O3BEJC0woJsm6uzFAEynLH2xCsw1KQ1lT4zg9rdxBL');INSERT INTO t1 VALUES (822890675,'97RGHZ65mNzkSrYT3zWoSbg9cNePQr1bzSk81qDgE4Oanw3rnPfGsBHSbnu1evTdFDe83ro9w4jjteQg4yoo9xHck3WNqzs54W5zEm92ikdRF48B2oz3m8gMBAl11W');INSERT INTO t1 VALUES (1308044878,'50w46i58Giekxik0cYzfA8BZBLADEg3JhzGfZDoqvQQk0Akcic7lcJInYSsf9wqin6LDC1vzJLkJXKn5onqOy04MTw1WksCYqPl2Jg2eteqOqTLfGCvE4zTZwWvgMz');INSERT INTO t1 VALUES (964445884,'DPh7kD1E6f4MMQk1ioopsoIIcoD83DD8Wu7689K6oHTAjD3Hts6lYGv8x9G0EL0k87q8G2ExJjz2o3KhnIJBbEJYFROTpO5pNvxgyBT9nSCbNO9AiKL9QYhi0x3hL9');INSERT INTO t1 VALUES (1586903190,'lwRHuWm4HE8leYmg66uGYIp6AnAr0BDd7YmuvYqCfqp9EbhKZRSymA4wx6gpHlJHI53DetH9j7Ixar90Jey5outd1ZIAJdJTjMaD7rMiqYXHFhHaB7Xr1HKuqe51GG');INSERT INTO t1 VALUES (962033002,'rfw4egILWisfxPwOc3nJx4frnAwgI539kr5EXFbupSZelM2MHqZEmD6ZNuEZzHib8fqYuHQbdrDND8lXqIdcNbAeWOBLZlpZOX5AoNlQFzpK7QjxcLP0wbWIriYGJL');INSERT INTO t1 VALUES (1910858270,'ksnug3YyANnWWDEJiRkiFC4a3e6KyJ2i3hSjksiuFLHlRXw9yhjDtnfoQd0OouyrcIbCB9zQWG4pf0yTZhaIT67nj7BY21FWJqaWrZxEh13Kt2hRbGl4MsrxsuLmvd');INSERT INTO t1 VALUES (63299708,'FJid3GaHpRC2L6jgirPm5AW3uGGgCloJ5Ww0eNHSiLWvS5bAxto23AxxR6TXr9qofeoAtxWcJsXnxzxmsdhvoekFc5mSES8tyxvsuPK5Hjs7ihtaJaLz5xEh2s1GCA');INSERT INTO t1 VALUES (737703662,'2zxutF6rOqjXYHHzSrKRwAhWCPXTdhNXYKQIRO9sEkFf1YeTGqw40Ta5u6QNfpvC1DWTTXDkFSFHtte9bbDSwgZjmryHglLhqjAKEF4MkJfT49eXcjzZNOG1F6BnsY');INSERT INTO t1 VALUES (1348361729,'i8X2EnycNH7sDHMltxcILtQE0ZPoPq9zyg24J0hiAgQNpg8jedtrWK5WtXIALR9B03FJ4ou6TCTAtWtN7fETzBzkiAmvTv6LrEZn2RtNfMaOkJfjytCp54ZfEJbb7Z');INSERT INTO t1 VALUES (1804289383,'mxvtvmC9127qJNm06sGB8R92q2j7vTiiITRDGXM9ZLzkdekbWtmXKwZ2qG1llkRw5m9DHOFilEREk3q7oce8O3BEJC0woJsm6uzFAEynLH2xCsw1KQ1lT4zg9rdxBL');INSERT INTO t1 VALUES (822890675,'97RGHZ65mNzkSrYT3zWoSbg9cNePQr1bzSk81qDgE4Oanw3rnPfGsBHSbnu1evTdFDe83ro9w4jjteQg4yoo9xHck3WNqzs54W5zEm92ikdRF48B2oz3m8gMBAl11W');INSERT INTO t1 VALUES (1308044878,'50w46i58Giekxik0cYzfA8BZBLADEg3JhzGfZDoqvQQk0Akcic7lcJInYSsf9wqin6LDC1vzJLkJXKn5onqOy04MTw1WksCYqPl2Jg2eteqOqTLfGCvE4zTZwWvgMz');INSERT INTO t1 VALUES (964445884,'DPh7kD1E6f4MMQk1ioopsoIIcoD83DD8Wu7689K6oHTAjD3Hts6lYGv8x9G0EL0k87q8G2ExJjz2o3KhnIJBbEJYFROTpO5pNvxgyBT9nSCbNO9AiKL9QYhi0x3hL9');INSERT INTO t1 VALUES (1586903190,'lwRHuWm4HE8leYmg66uGYIp6AnAr0BDd7YmuvYqCfqp9EbhKZRSymA4wx6gpHlJHI53DetH9j7Ixar90Jey5outd1ZIAJdJTjMaD7rMiqYXHFhHaB7Xr1HKuqe51GG');INSERT INTO t1 VALUES (962033002,'rfw4egILWisfxPwOc3nJx4frnAwgI539kr5EXFbupSZelM2MHqZEmD6ZNuEZzHib8fqYuHQbdrDND8lXqIdcNbAeWOBLZlpZOX5AoNlQFzpK7QjxcLP0wbWIriYGJL');INSERT INTO t1 VALUES (1910858270,'ksnug3YyANnWWDEJiRkiFC4a3e6KyJ2i3hSjksiuFLHlRXw9yhjDtnfoQd0OouyrcIbCB9zQWG4pf0yTZhaIT67nj7BY21FWJqaWrZxEh13Kt2hRbGl4MsrxsuLmvd');INSERT INTO t1 VALUES (63299708,'FJid3GaHpRC2L6jgirPm5AW3uGGgCloJ5Ww0eNHSiLWvS5bAxto23AxxR6TXr9qofeoAtxWcJsXnxzxmsdhvoekFc5mSES8tyxvsuPK5Hjs7ihtaJaLz5xEh2s1GCA');INSERT INTO t1 VALUES (737703662,'2zxutF6rOqjXYHHzSrKRwAhWCPXTdhNXYKQIRO9sEkFf1YeTGqw40Ta5u6QNfpvC1DWTTXDkFSFHtte9bbDSwgZjmryHglLhqjAKEF4MkJfT49eXcjzZNOG1F6BnsY');INSERT INTO t1 VALUES (1348361729,'i8X2EnycNH7sDHMltxcILtQE0ZPoPq9zyg24J0hiAgQNpg8jedtrWK5WtXIALR9B03FJ4ou6TCTAtWtN7fETzBzkiAmvTv6LrEZn2RtNfMaOkJfjytCp54ZfEJbb7Z');INSERT INTO t1 VALUES (1804289383,'mxvtvmC9127qJNm06sGB8R92q2j7vTiiITRDGXM9ZLzkdekbWtmXKwZ2qG1llkRw5m9DHOFilEREk3q7oce8O3BEJC0woJsm6uzFAEynLH2xCsw1KQ1lT4zg9rdxBL');INSERT INTO t1 VALUES (822890675,'97RGHZ65mNzkSrYT3zWoSbg9cNePQr1bzSk81qDgE4Oanw3rnPfGsBHSbnu1evTdFDe83ro9w4jjteQg4yoo9xHck3WNqzs54W5zEm92ikdRF48B2oz3m8gMBAl11W');INSERT INTO t1 VALUES (1308044878,'50w46i58Giekxik0cYzfA8BZBLADEg3JhzGfZDoqvQQk0Akcic7lcJInYSsf9wqin6LDC1vzJLkJXKn5onqOy04MTw1WksCYqPl2Jg2eteqOqTLfGCvE4zTZwWvgMz');INSERT INTO t1 VALUES (964445884,'DPh7kD1E6f4MMQk1ioopsoIIcoD83DD8Wu7689K6oHTAjD3Hts6lYGv8x9G0EL0k87q8G2ExJjz2o3KhnIJBbEJYFROTpO5pNvxgyBT9nSCbNO9AiKL9QYhi0x3hL9');INSERT INTO t1 VALUES (1586903190,'lwRHuWm4HE8leYmg66uGYIp6AnAr0BDd7YmuvYqCfqp9EbhKZRSymA4wx6gpHlJHI53DetH9j7Ixar90Jey5outd1ZIAJdJTjMaD7rMiqYXHFhHaB7Xr1HKuqe51GG');INSERT INTO t1 VALUES (962033002,'rfw4egILWisfxPwOc3nJx4frnAwgI539kr5EXFbupSZelM2MHqZEmD6ZNuEZzHib8fqYuHQbdrDND8lXqIdcNbAeWOBLZlpZOX5AoNlQFzpK7QjxcLP0wbWIriYGJL');INSERT INTO t1 VALUES (1910858270,'ksnug3YyANnWWDEJiRkiFC4a3e6KyJ2i3hSjksiuFLHlRXw9yhjDtnfoQd0OouyrcIbCB9zQWG4pf0yTZhaIT67nj7BY21FWJqaWrZxEh13Kt2hRbGl4MsrxsuLmvd');INSERT INTO t1 VALUES (63299708,'FJid3GaHpRC2L6jgirPm5AW3uGGgCloJ5Ww0eNHSiLWvS5bAxto23AxxR6TXr9qofeoAtxWcJsXnxzxmsdhvoekFc5mSES8tyxvsuPK5Hjs7ihtaJaLz5xEh2s1GCA');INSERT INTO t1 VALUES (737703662,'2zxutF6rOqjXYHHzSrKRwAhWCPXTdhNXYKQIRO9sEkFf1YeTGqw40Ta5u6QNfpvC1DWTTXDkFSFHtte9bbDSwgZjmryHglLhqjAKEF4MkJfT49eXcjzZNOG1F6BnsY');INSERT INTO t1 VALUES (1348361729,'i8X2EnycNH7sDHMltxcILtQE0ZPoPq9zyg24J0hiAgQNpg8jedtrWK5WtXIALR9B03FJ4ou6TCTAtWtN7fETzBzkiAmvTv6LrEZn2RtNfMaOkJfjytCp54ZfEJbb7Z');INSERT INTO t1 VALUES (1804289383,'mxvtvmC9127qJNm06sGB8R92q2j7vTiiITRDGXM9ZLzkdekbWtmXKwZ2qG1llkRw5m9DHOFilEREk3q7oce8O3BEJC0woJsm6uzFAEynLH2xCsw1KQ1lT4zg9rdxBL');INSERT INTO t1 VALUES (822890675,'97RGHZ65mNzkSrYT3zWoSbg9cNePQr1bzSk81qDgE4Oanw3rnPfGsBHSbnu1evTdFDe83ro9w4jjteQg4yoo9xHck3WNqzs54W5zEm92ikdRF48B2oz3m8gMBAl11W');INSERT INTO t1 VALUES (1308044878,'50w46i58Giekxik0cYzfA8BZBLADEg3JhzGfZDoqvQQk0Akcic7lcJInYSsf9wqin6LDC1vzJLkJXKn5onqOy04MTw1WksCYqPl2Jg2eteqOqTLfGCvE4zTZwWvgMz');INSERT INTO t1 VALUES (964445884,'DPh7kD1E6f4MMQk1ioopsoIIcoD83DD8Wu7689K6oHTAjD3Hts6lYGv8x9G0EL0k87q8G2ExJjz2o3KhnIJBbEJYFROTpO5pNvxgyBT9nSCbNO9AiKL9QYhi0x3hL9');INSERT INTO t1 VALUES (1586903190,'lwRHuWm4HE8leYmg66uGYIp6AnAr0BDd7YmuvYqCfqp9EbhKZRSymA4wx6gpHlJHI53DetH9j7Ixar90Jey5outd1ZIAJdJTjMaD7rMiqYXHFhHaB7Xr1HKuqe51GG');INSERT INTO t1 VALUES (962033002,'rfw4egILWisfxPwOc3nJx4frnAwgI539kr5EXFbupSZelM2MHqZEmD6ZNuEZzHib8fqYuHQbdrDND8lXqIdcNbAeWOBLZlpZOX5AoNlQFzpK7QjxcLP0wbWIriYGJL');INSERT INTO t1 VALUES (1910858270,'ksnug3YyANnWWDEJiRkiFC4a3e6KyJ2i3hSjksiuFLHlRXw9yhjDtnfoQd0OouyrcIbCB9zQWG4pf0yTZhaIT67nj7BY21FWJqaWrZxEh13Kt2hRbGl4MsrxsuLmvd');INSERT INTO t1 VALUES (63299708,'FJid3GaHpRC2L6jgirPm5AW3uGGgCloJ5Ww0eNHSiLWvS5bAxto23AxxR6TXr9qofeoAtxWcJsXnxzxmsdhvoekFc5mSES8tyxvsuPK5Hjs7ihtaJaLz5xEh2s1GCA');INSERT INTO t1 VALUES (737703662,'2zxutF6rOqjXYHHzSrKRwAhWCPXTdhNXYKQIRO9sEkFf1YeTGqw40Ta5u6QNfpvC1DWTTXDkFSFHtte9bbDSwgZjmryHglLhqjAKEF4MkJfT49eXcjzZNOG1F6BnsY');INSERT INTO t1 VALUES (1348361729,'i8X2EnycNH7sDHMltxcILtQE0ZPoPq9zyg24J0hiAgQNpg8jedtrWK5WtXIALR9B03FJ4ou6TCTAtWtN7fETzBzkiAmvTv6LrEZn2RtNfMaOkJfjytCp54ZfEJbb7Z');INSERT INTO t1 VALUES (1804289383,'mxvtvmC9127qJNm06sGB8R92q2j7vTiiITRDGXM9ZLzkdekbWtmXKwZ2qG1llkRw5m9DHOFilEREk3q7oce8O3BEJC0woJsm6uzFAEynLH2xCsw1KQ1lT4zg9rdxBL');INSERT INTO t1 VALUES (822890675,'97RGHZ65mNzkSrYT3zWoSbg9cNePQr1bzSk81qDgE4Oanw3rnPfGsBHSbnu1evTdFDe83ro9w4jjteQg4yoo9xHck3WNqzs54W5zEm92ikdRF48B2oz3m8gMBAl11W');INSERT INTO t1 VALUES (1308044878,'50w46i58Giekxik0cYzfA8BZBLADEg3JhzGfZDoqvQQk0Akcic7lcJInYSsf9wqin6LDC1vzJLkJXKn5onqOy04MTw1WksCYqPl2Jg2eteqOqTLfGCvE4zTZwWvgMz');INSERT INTO t1 VALUES (964445884,'DPh7kD1E6f4MMQk1ioopsoIIcoD83DD8Wu7689K6oHTAjD3Hts6lYGv8x9G0EL0k87q8G2ExJjz2o3KhnIJBbEJYFROTpO5pNvxgyBT9nSCbNO9AiKL9QYhi0x3hL9');INSERT INTO t1 VALUES (1586903190,'lwRHuWm4HE8leYmg66uGYIp6AnAr0BDd7YmuvYqCfqp9EbhKZRSymA4wx6gpHlJHI53DetH9j7Ixar90Jey5outd1ZIAJdJTjMaD7rMiqYXHFhHaB7Xr1HKuqe51GG');INSERT INTO t1 VALUES (962033002,'rfw4egILWisfxPwOc3nJx4frnAwgI539kr5EXFbupSZelM2MHqZEmD6ZNuEZzHib8fqYuHQbdrDND8lXqIdcNbAeWOBLZlpZOX5AoNlQFzpK7QjxcLP0wbWIriYGJL');INSERT INTO t1 VALUES (1910858270,'ksnug3YyANnWWDEJiRkiFC4a3e6KyJ2i3hSjksiuFLHlRXw9yhjDtnfoQd0OouyrcIbCB9zQWG4pf0yTZhaIT67nj7BY21FWJqaWrZxEh13Kt2hRbGl4MsrxsuLmvd');INSERT INTO t1 VALUES (63299708,'FJid3GaHpRC2L6jgirPm5AW3uGGgCloJ5Ww0eNHSiLWvS5bAxto23AxxR6TXr9qofeoAtxWcJsXnxzxmsdhvoekFc5mSES8tyxvsuPK5Hjs7ihtaJaLz5xEh2s1GCA');INSERT INTO t1 VALUES (737703662,'2zxutF6rOqjXYHHzSrKRwAhWCPXTdhNXYKQIRO9sEkFf1YeTGqw40Ta5u6QNfpvC1DWTTXDkFSFHtte9bbDSwgZjmryHglLhqjAKEF4MkJfT49eXcjzZNOG1F6BnsY');INSERT INTO t1 VALUES (1348361729,'i8X2EnycNH7sDHMltxcILtQE0ZPoPq9zyg24J0hiAgQNpg8jedtrWK5WtXIALR9B03FJ4ou6TCTAtWtN7fETzBzkiAmvTv6LrEZn2RtNfMaOkJfjytCp54ZfEJbb7Z');INSERT INTO t1 VALUES (1804289383,'mxvtvmC9127qJNm06sGB8R92q2j7vTiiITRDGXM9ZLzkdekbWtmXKwZ2qG1llkRw5m9DHOFilEREk3q7oce8O3BEJC0woJsm6uzFAEynLH2xCsw1KQ1lT4zg9rdxBL');INSERT INTO t1 VALUES (822890675,'97RGHZ65mNzkSrYT3zWoSbg9cNePQr1bzSk81qDgE4Oanw3rnPfGsBHSbnu1evTdFDe83ro9w4jjteQg4yoo9xHck3WNqzs54W5zEm92ikdRF48B2oz3m8gMBAl11W');INSERT INTO t1 VALUES (1308044878,'50w46i58Giekxik0cYzfA8BZBLADEg3JhzGfZDoqvQQk0Akcic7lcJInYSsf9wqin6LDC1vzJLkJXKn5onqOy04MTw1WksCYqPl2Jg2eteqOqTLfGCvE4zTZwWvgMz');INSERT INTO t1 VALUES (964445884,'DPh7kD1E6f4MMQk1ioopsoIIcoD83DD8Wu7689K6oHTAjD3Hts6lYGv8x9G0EL0k87q8G2ExJjz2o3KhnIJBbEJYFROTpO5pNvxgyBT9nSCbNO9AiKL9QYhi0x3hL9');INSERT INTO t1 VALUES (1586903190,'lwRHuWm4HE8leYmg66uGYIp6AnAr0BDd7YmuvYqCfqp9EbhKZRSymA4wx6gpHlJHI53DetH9j7Ixar90Jey5outd1ZIAJdJTjMaD7rMiqYXHFhHaB7Xr1HKuqe51GG');INSERT INTO t1 VALUES (962033002,'rfw4egILWisfxPwOc3nJx4frnAwgI539kr5EXFbupSZelM2MHqZEmD6ZNuEZzHib8fqYuHQbdrDND8lXqIdcNbAeWOBLZlpZOX5AoNlQFzpK7QjxcLP0wbWIriYGJL');INSERT INTO t1 VALUES (1910858270,'ksnug3YyANnWWDEJiRkiFC4a3e6KyJ2i3hSjksiuFLHlRXw9yhjDtnfoQd0OouyrcIbCB9zQWG4pf0yTZhaIT67nj7BY21FWJqaWrZxEh13Kt2hRbGl4MsrxsuLmvd');INSERT INTO t1 VALUES (63299708,'FJid3GaHpRC2L6jgirPm5AW3uGGgCloJ5Ww0eNHSiLWvS5bAxto23AxxR6TXr9qofeoAtxWcJsXnxzxmsdhvoekFc5mSES8tyxvsuPK5Hjs7ihtaJaLz5xEh2s1GCA');INSERT INTO t1 VALUES (737703662,'2zxutF6rOqjXYHHzSrKRwAhWCPXTdhNXYKQIRO9sEkFf1YeTGqw40Ta5u6QNfpvC1DWTTXDkFSFHtte9bbDSwgZjmryHglLhqjAKEF4MkJfT49eXcjzZNOG1F6BnsY');INSERT INTO t1 VALUES (1348361729,'i8X2EnycNH7sDHMltxcILtQE0ZPoPq9zyg24J0hiAgQNpg8jedtrWK5WtXIALR9B03FJ4ou6TCTAtWtN7fETzBzkiAmvTv6LrEZn2RtNfMaOkJfjytCp54ZfEJbb7Z');INSERT INTO t1 VALUES (1804289383,'mxvtvmC9127qJNm06sGB8R92q2j7vTiiITRDGXM9ZLzkdekbWtmXKwZ2qG1llkRw5m9DHOFilEREk3q7oce8O3BEJC0woJsm6uzFAEynLH2xCsw1KQ1lT4zg9rdxBL');INSERT INTO t1 VALUES (822890675,'97RGHZ65mNzkSrYT3zWoSbg9cNePQr1bzSk81qDgE4Oanw3rnPfGsBHSbnu1evTdFDe83ro9w4jjteQg4yoo9xHck3WNqzs54W5zEm92ikdRF48B2oz3m8gMBAl11W');INSERT INTO t1 VALUES (1308044878,'50w46i58Giekxik0cYzfA8BZBLADEg3JhzGfZDoqvQQk0Akcic7lcJInYSsf9wqin6LDC1vzJLkJXKn5onqOy04MTw1WksCYqPl2Jg2eteqOqTLfGCvE4zTZwWvgMz');INSERT INTO t1 VALUES (964445884,'DPh7kD1E6f4MMQk1ioopsoIIcoD83DD8Wu7689K6oHTAjD3Hts6lYGv8x9G0EL0k87q8G2ExJjz2o3KhnIJBbEJYFROTpO5pNvxgyBT9nSCbNO9AiKL9QYhi0x3hL9');INSERT INTO t1 VALUES (1586903190,'lwRHuWm4HE8leYmg66uGYIp6AnAr0BDd7YmuvYqCfqp9EbhKZRSymA4wx6gpHlJHI53DetH9j7Ixar90Jey5outd1ZIAJdJTjMaD7rMiqYXHFhHaB7Xr1HKuqe51GG');INSERT INTO t1 VALUES (962033002,'rfw4egILWisfxPwOc3nJx4frnAwgI539kr5EXFbupSZelM2MHqZEmD6ZNuEZzHib8fqYuHQbdrDND8lXqIdcNbAeWOBLZlpZOX5AoNlQFzpK7QjxcLP0wbWIriYGJL');INSERT INTO t1 VALUES (1910858270,'ksnug3YyANnWWDEJiRkiFC4a3e6KyJ2i3hSjksiuFLHlRXw9yhjDtnfoQd0OouyrcIbCB9zQWG4pf0yTZhaIT67nj7BY21FWJqaWrZxEh13Kt2hRbGl4MsrxsuLmvd');INSERT INTO t1 VALUES (63299708,'FJid3GaHpRC2L6jgirPm5AW3uGGgCloJ5Ww0eNHSiLWvS5bAxto23AxxR6TXr9qofeoAtxWcJsXnxzxmsdhvoekFc5mSES8tyxvsuPK5Hjs7ihtaJaLz5xEh2s1GCA');INSERT INTO t1 VALUES (737703662,'2zxutF6rOqjXYHHzSrKRwAhWCPXTdhNXYKQIRO9sEkFf1YeTGqw40Ta5u6QNfpvC1DWTTXDkFSFHtte9bbDSwgZjmryHglLhqjAKEF4MkJfT49eXcjzZNOG1F6BnsY');INSERT INTO t1 VALUES (1348361729,'i8X2EnycNH7sDHMltxcILtQE0ZPoPq9zyg24J0hiAgQNpg8jedtrWK5WtXIALR9B03FJ4ou6TCTAtWtN7fETzBzkiAmvTv6LrEZn2RtNfMaOkJfjytCp54ZfEJbb7Z');INSERT INTO t1 VALUES (1804289383,'mxvtvmC9127qJNm06sGB8R92q2j7vTiiITRDGXM9ZLzkdekbWtmXKwZ2qG1llkRw5m9DHOFilEREk3q7oce8O3BEJC0woJsm6uzFAEynLH2xCsw1KQ1lT4zg9rdxBL');INSERT INTO t1 VALUES (822890675,'97RGHZ65mNzkSrYT3zWoSbg9cNePQr1bzSk81qDgE4Oanw3rnPfGsBHSbnu1evTdFDe83ro9w4jjteQg4yoo9xHck3WNqzs54W5zEm92ikdRF48B2oz3m8gMBAl11W');INSERT INTO t1 VALUES (1308044878,'50w46i58Giekxik0cYzfA8BZBLADEg3JhzGfZDoqvQQk0Akcic7lcJInYSsf9wqin6LDC1vzJLkJXKn5onqOy04MTw1WksCYqPl2Jg2eteqOqTLfGCvE4zTZwWvgMz');INSERT INTO t1 VALUES (964445884,'DPh7kD1E6f4MMQk1ioopsoIIcoD83DD8Wu7689K6oHTAjD3Hts6lYGv8x9G0EL0k87q8G2ExJjz2o3KhnIJBbEJYFROTpO5pNvxgyBT9nSCbNO9AiKL9QYhi0x3hL9');INSERT INTO t1 VALUES (1586903190,'lwRHuWm4HE8leYmg66uGYIp6AnAr0BDd7YmuvYqCfqp9EbhKZRSymA4wx6gpHlJHI53DetH9j7Ixar90Jey5outd1ZIAJdJTjMaD7rMiqYXHFhHaB7Xr1HKuqe51GG');INSERT INTO t1 VALUES (962033002,'rfw4egILWisfxPwOc3nJx4frnAwgI539kr5EXFbupSZelM2MHqZEmD6ZNuEZzHib8fqYuHQbdrDND8lXqIdcNbAeWOBLZlpZOX5AoNlQFzpK7QjxcLP0wbWIriYGJL');INSERT INTO t1 VALUES (1910858270,'ksnug3YyANnWWDEJiRkiFC4a3e6KyJ2i3hSjksiuFLHlRXw9yhjDtnfoQd0OouyrcIbCB9zQWG4pf0yTZhaIT67nj7BY21FWJqaWrZxEh13Kt2hRbGl4MsrxsuLmvd');INSERT INTO t1 VALUES (63299708,'FJid3GaHpRC2L6jgirPm5AW3uGGgCloJ5Ww0eNHSiLWvS5bAxto23AxxR6TXr9qofeoAtxWcJsXnxzxmsdhvoekFc5mSES8tyxvsuPK5Hjs7ihtaJaLz5xEh2s1GCA');INSERT INTO t1 VALUES (737703662,'2zxutF6rOqjXYHHzSrKRwAhWCPXTdhNXYKQIRO9sEkFf1YeTGqw40Ta5u6QNfpvC1DWTTXDkFSFHtte9bbDSwgZjmryHglLhqjAKEF4MkJfT49eXcjzZNOG1F6BnsY');INSERT INTO t1 VALUES (1348361729,'i8X2EnycNH7sDHMltxcILtQE0ZPoPq9zyg24J0hiAgQNpg8jedtrWK5WtXIALR9B03FJ4ou6TCTAtWtN7fETzBzkiAmvTv6LrEZn2RtNfMaOkJfjytCp54ZfEJbb7Z');INSERT INTO t1 VALUES (1804289383,'mxvtvmC9127qJNm06sGB8R92q2j7vTiiITRDGXM9ZLzkdekbWtmXKwZ2qG1llkRw5m9DHOFilEREk3q7oce8O3BEJC0woJsm6uzFAEynLH2xCsw1KQ1lT4zg9rdxBL');INSERT INTO t1 VALUES (822890675,'97RGHZ65mNzkSrYT3zWoSbg9cNePQr1bzSk81qDgE4Oanw3rnPfGsBHSbnu1evTdFDe83ro9w4jjteQg4yoo9xHck3WNqzs54W5zEm92ikdRF48B2oz3m8gMBAl11W');INSERT INTO t1 VALUES (1308044878,'50w46i58Giekxik0cYzfA8BZBLADEg3JhzGfZDoqvQQk0Akcic7lcJInYSsf9wqin6LDC1vzJLkJXKn5onqOy04MTw1WksCYqPl2Jg2eteqOqTLfGCvE4zTZwWvgMz');INSERT INTO t1 VALUES (964445884,'DPh7kD1E6f4MMQk1ioopsoIIcoD83DD8Wu7689K6oHTAjD3Hts6lYGv8x9G0EL0k87q8G2ExJjz2o3KhnIJBbEJYFROTpO5pNvxgyBT9nSCbNO9AiKL9QYhi0x3hL9');INSERT INTO t1 VALUES (1586903190,'lwRHuWm4HE8leYmg66uGYIp6AnAr0BDd7YmuvYqCfqp9EbhKZRSymA4wx6gpHlJHI53DetH9j7Ixar90Jey5outd1ZIAJdJTjMaD7rMiqYXHFhHaB7Xr1HKuqe51GG');INSERT INTO t1 VALUES (962033002,'rfw4egILWisfxPwOc3nJx4frnAwgI539kr5EXFbupSZelM2MHqZEmD6ZNuEZzHib8fqYuHQbdrDND8lXqIdcNbAeWOBLZlpZOX5AoNlQFzpK7QjxcLP0wbWIriYGJL');INSERT INTO t1 VALUES (1910858270,'ksnug3YyANnWWDEJiRkiFC4a3e6KyJ2i3hSjksiuFLHlRXw9yhjDtnfoQd0OouyrcIbCB9zQWG4pf0yTZhaIT67nj7BY21FWJqaWrZxEh13Kt2hRbGl4MsrxsuLmvd');INSERT INTO t1 VALUES (63299708,'FJid3GaHpRC2L6jgirPm5AW3uGGgCloJ5Ww0eNHSiLWvS5bAxto23AxxR6TXr9qofeoAtxWcJsXnxzxmsdhvoekFc5mSES8tyxvsuPK5Hjs7ihtaJaLz5xEh2s1GCA');INSERT INTO t1 VALUES (737703662,'2zxutF6rOqjXYHHzSrKRwAhWCPXTdhNXYKQIRO9sEkFf1YeTGqw40Ta5u6QNfpvC1DWTTXDkFSFHtte9bbDSwgZjmryHglLhqjAKEF4MkJfT49eXcjzZNOG1F6BnsY');INSERT INTO t1 VALUES (100669,'qnMdipW5KkXdTjGCh2PNzLoeR0527frpQDQ8uw67Ydk1K06uuNHtkxYBxT5w8plb2BbpzhwYBgPNYX9RmICWGkZD6fAESvhMzH3yqzMtXoH4BQNylbK1CmEIPGYlC6');SELECT intcol1,charcol1 FROM t1;INSERT INTO t1 VALUES (73673339,'BN3152Gza4GW7atxJKACYwJqDbFynLxqc0kh30YTwgz3FktQ43XTrqJ4PQ25frn7kXhfXD8RuzN1j8Rf3y8ugKy6es3IbqPJM6ylCyD6xS7YcQCfHKZxYNvB7yTahm');SELECT intcol1,charcol1 FROM t1;INSERT INTO t1 VALUES (1759592334,'3lkoxjtvgLu5xKHSTTtJuGE5F5QqmCcppCTmvFZScRZQgim93gSxwb24gKmIPEzEQStMjQiCu7WapGbkw4ilXch3xRLMhKSzgLDOovSi2qGj6rKvnuYAWDDJgaZDu2');SELECT intcol1,charcol1 FROM t1;INSERT INTO t1 VALUES (95275444,'bNIrBDBl81tjzdvuOpQRCXgX37xGtzLKEXBIcE3k7xK7aFtqxC99jqYnpTviK83bf6lGDgsKd4R3KLmHPnI8TqnIKj1gjw7N2sXFZNS2Svyg8cpZN7atxL39w4igsp');SELECT intcol1,charcol1 FROM t1;INSERT INTO t1 VALUES (866596855,'naQuzhMt1IrZIJMkbLAKBNNKKK2sCknzI5uHeGAgQuDd5SLgpN0smODyc7qorTo1QaI5qLl97qmCIzl0Mds81x7TxpIoJyqlY0iEDRNKA1PS0AKEn5NhuMAr3KgEIM');SELECT intcol1,charcol1 FROM t1;INSERT INTO t1 VALUES (364531492,'qMa5SuKo4M5OM7ldvisSc6WK9rsG9E8sSixocHdgfa5uiiNTGFxkDJ4EAwWC2e4NL1BpAgWiFRcp1zIH6F1BayPdmwphatwnmzdwgzWnQ6SRxmcvtd6JRYwEKdvuWr');DROP SCHEMA IF EXISTS `mysqlslap`;[root@Betty libmysql]#

7. 实际测试中的复杂情况,

使用 --defaults-file 选项,指定从配置文件中读取选项配置。

使用 --number-int-cols 选项,指定表中会包含 4 个 int 型的列。

使用 --number-char-cols 选项,指定表中会包含 35 个 char 型的列。

使用 --engine 选项,指定针对何种存储引擎进行测试。

[root@Betty ~]# mysqlslap --defaults-file=/etc/my.cnf --concurrency=50,100,200 --iterations=1 --number-int-cols=4 --number-char-cols=35 --auto-generate-sql --auto-generate-sql-add-autoincrement --auto-generate-sql-load-type=mixed --engine=myisam,innodb --number-of-queries=200 --debug-info -S /tmp/mysql.sockBenchmark Running for engine myisam Average number of seconds to run all queries: 0.015 seconds Minimum number of seconds to run all queries: 0.015 seconds Maximum number of seconds to run all queries: 0.015 seconds Number of clients running queries: 50 Average number of queries per client: 4Benchmark Running for engine myisam Average number of seconds to run all queries: 0.024 seconds Minimum number of seconds to run all queries: 0.024 seconds Maximum number of seconds to run all queries: 0.024 seconds Number of clients running queries: 100 Average number of queries per client: 2Benchmark Running for engine myisam Average number of seconds to run all queries: 0.028 seconds Minimum number of seconds to run all queries: 0.028 seconds Maximum number of seconds to run all queries: 0.028 seconds Number of clients running queries: 200 Average number of queries per client: 1Benchmark Running for engine innodb Average number of seconds to run all queries: 0.112 seconds Minimum number of seconds to run all queries: 0.112 seconds Maximum number of seconds to run all queries: 0.112 seconds Number of clients running queries: 50 Average number of queries per client: 4Benchmark Running for engine innodb Average number of seconds to run all queries: 0.042 seconds Minimum number of seconds to run all queries: 0.042 seconds Maximum number of seconds to run all queries: 0.042 seconds Number of clients running queries: 100 Average number of queries per client: 2Benchmark Running for engine innodb Average number of seconds to run all queries: 0.105 seconds Minimum number of seconds to run all queries: 0.105 seconds Maximum number of seconds to run all queries: 0.105 seconds Number of clients running queries: 200 Average number of queries per client: 1User time 0.05, System time 0.06Maximum resident set size 8332, Integral resident set size 0Non-physical pagefaults 5388, Physical pagefaults 0, Swaps 0Blocks in 0 out 0, Messages in 0 out 0, Signals 0Voluntary context switches 7484, Involuntary context switches 2839[root@Betty ~]#

8. 使用存储过程进行测试。

========== 我是分割线=============

mysqlslap 运行分三个阶段:

创建 schema,table 和任何用来测试的已经存储了的程序和数据。这个阶段使用单客户端连接;

进行负载测试。这个阶段使用多客户端连接;

清除(断开连接,删除指定表)。这个阶段使用单客户端连接。

例子:

a. 提供你自己的创建 SQL 语句和查询 SQL 语句,有 50 个客户端查询,每个查询 200 次(在单行上输入命令):

[root@Betty ~]# mysqlslap --delimiter=“;” --create=“CREATE TABLE a (b int);INSERT INTO a VALUES (23)” --query=“SELECT * FROM a” --concurrency=50 --iterations=200Benchmark Average number of seconds to run all queries: 0.005 seconds Minimum number of seconds to run all queries: 0.003 seconds Maximum number of seconds to run all queries: 0.007 seconds Number of clients running queries: 50 Average number of queries per client: 1[root@Betty ~]#

b. 让 mysqlslap 创建查询的 SQL 语句,使用的表有 2 个 INT 行和 3 个 VARCHAR 行。使用 5 个客户端,每一个查询 20 次!不要创建表或插入数据。(换言之,用之前测试的模式和数据):

[root@Betty ~]# mysqlslap --concurrency=5 --iterations=20 --number-int-cols=2 --number-char-cols=3 --auto-generate-sqlBenchmark Average number of seconds to run all queries: 0.025 seconds Minimum number of seconds to run all queries: 0.012 seconds Maximum number of seconds to run all queries: 0.084 seconds Number of clients running queries: 5 Average number of queries per client: 0[root@Betty ~]#

c. 告诉程序从指定的 create.sql 文件去加载 create,insert 和查询等 SQL 语句。该文件有多个表的 create 和insert 语句, 它们都是通过“;”分隔开的。query.sql 文件则有多个查询语句, 分隔符也是“;”。执行所有的加载语句,然后通过查询文件执行所有的查询语句,分别在 5 个客户端上每个执行 5 次:

[root@Betty ~]# mysqlslap --concurrency=5 --iterations=5 --query=query.sql --create=create.sql --delimiter=“;”

========== 我是分割线=============

mysqlslap 对于模拟多个用户同时对 MySQL 发起“进攻”提供了方便。同时详细的提供了“高负荷攻击 MySQL”的详细数据报告。

来自:my.oschina.net/moooofly/blog/152547

篇10:微信使用倡议书

当前,微信已经成为网民分享资讯、交流观点的重要平台,在方便我们工作和生活的同时,也有一些微信不良信息污染网络环境,败坏社会风气。为营造健康文明的网络环境,推动我市新媒体行业健康可持续发展,XX发布、XX教育、XX公安、XX发布等22个市县两级官方微信的公众号,XX晚报、中国XX网、600全民新闻、XX在线等14个市级媒体微信的公众号,XX19楼、新XX、XX生活网、XX信息港、XX百事通、微XX、微XX、大XX、XX包子微生活、XX小助手、XX信息港、XX天台、XX微生活、微笑XX、XX微生活、XX青年、XX网站等21个影响力较大的市内社会微信公众帐号,联合发起成立“清朗XX”微信联盟,并向全市微信用户(包括公众帐号)发出如下倡议:

一、大力加强行业自律。

微信的公众号要严格遵守国家和行业主管部门制定的各项法律法规,强化内部监管机制和内容审核把关机制;做到文明办网,不以吸引眼球为目的,肆意传播庸俗、低俗、媚俗信息;积极响应“打击网络谣言,让网络空间清朗起来”专项行动,主动开展自查自纠,决不给谣言信息提供传播渠道和平台;开通网民举报渠道,自觉接受公众监督,实行对虚假有害信息的联动处置机制,共同净化互联网环境。

二、努力坚持自我约束。

微信个人用户要严格遵守网络空间“七条底线”,自觉做到不造谣、不信谣、不传谣,做网络健康环境的维护者,发现网络谣言积极向行业主管部门举报。要树立新型网络道德规范,自觉抵制网络低俗、有害信息,自觉规范网络行为,用理性的态度上网,用文明的语言发表观点和看法,做到文明上网、科学用网。

三、共同传播网络正能量。

广大微信用户要主动争当网络文明志愿者,让社会主义先进文化占领网络阵地,以健康向上、丰富多彩的内容影响感动身边的每一个人,形成知荣辱、讲正气、树新风、促和谐的文明上网新风尚。要善于用发现的眼光多挖掘、宣传身边的山水之美、人文之美、发展之美,积极传播健康积极的网络信息。

“XX”微信联盟

20XX年5月22日

篇11:微信使用倡议书

当您和朋友徜徉在微博、微信世界,发送语音短信、视频、图片和文字,发表观点,交流思想,联络感情时,请您更多关注身边的发展变化,关注我们美丽的家园——多彩XX。

在这片17万平方公里的土地上,自然风光优美,奇山秀水、飞瀑秘洞、深涧幽谷等等构成了迷人的“天然公园”。这里历史悠久、文化灿烂,孕育了悠远深邃的人类原始文明,积淀了绚烂多彩的民族文化遗存和原生文化形态。这里是中国革命的“福地”和“圣地”,留下了厚重的红色文化。如今,坚持加速发展、加快转型、推动跨越,坚持发展为要、民生为本、企业为基、环境为重,XX城乡面貌发生了巨大变化,正日新月异更换着发展影像。

热爱XX,关心XX的朋友们,请拿起您的相机、手机,随手拍下身边越来越优美的环境,越来越美丽的风景,随手记录越来越快的发展变化,越来越打动人心的人文风物。哪怕只有二三幅图、四五行话,编辑、发送、分享,让您的朋友在您的微博微信上发现XX的美丽、XX的发展、XX的进步。我们相信,有您的参与,有您的接力,有您的分享,多彩的XX将会更加多彩。

XX省互联网信息办公室

XX省互联网协会

20XX年9月23日

篇12:怎么使用两个微信

使用两个微信的方法

手机先安装一个微信,可从手机助手下载安装,也可电脑上下载安装包传到手机安装,相信大家都已经安装过了吧。

再安装“微信多开宝”(多开就靠它了),可从手机助手下载安装,也可电脑上下载安装包传到手机安装。

打开微信多开宝,点击右上角的云按钮,安装您的第一个微信。

自此已安装另一个微信了,打开微信01,登录即可。

按照同样方法可再安装微信,官方称可支持100个微信,大家不会那么疯狂吧,哈哈。

使用注意事项

此软件可免费安装1个微信,安装多个需要付费,天下没有免费的午餐,这句话哪都适用。

免费安装的一个微信可能是较低版本的,建议较不常用的账号登录。

docker使用的个人学习总结

新教材使用总结

个人征信宣传活动总结

信合信贷员工个人总结

员工年终个个人总结报告

个人的信

陕西信合员工年度考核个人总结

销售个人月总结优秀

房产销售个人月总结

团队合作个人小总结

个信个人使用总结(精选12篇)

欢迎下载DOC格式的个信个人使用总结,但愿能给您带来参考作用!
推荐度: 推荐 推荐 推荐 推荐 推荐
点击下载文档 文档为doc格式
点击下载本文文档