1.前言
本章并不会教你如何学会使用某一个具体的数据库。
如果需要可以参考本站的其它教程,对于仅仅只是应用来说,它并不复杂,只是有点繁琐而已,需要记忆的东西比较多。
本文的目的是尝试从比较宏观的角度来看待数据库,以及在不同的地方,使用合适的数据库。
2.理解数据库
首先我们还是要来理解一下数据库的本质。
看数据库这个名字,我们就能看出一二,数据库即数据的库存,用于数据的存储与取出,乃至一些更高级的操作。
我们最常见的数据库,可能就是我们windows
电脑上自带的注册表了(不知道如何打开?浏览器搜一搜):
注册表里面就存储了我们电脑所有的信息,在一些时候会进行写入,同时有些时候会进行读取操作,因为它是独立于各个应用程序的。
独立于应用程序,这一点很重要,即一个数据库,可以被不同程序访问,它并不属于某个应用程序。
比如我们常用的QQ,微信,为什么我们登录各种游戏,很多都可以用QQ、微信登录?
那就是因为它们可以向你申请权限来访问腾讯存储你信息的数据库,即它们也可以通过一些腾讯提供的接口,来访问腾讯的数据库。
3.配置文件
在真正使用数据库前,要搞懂自己是否需要数据库,因为即使是最简单的数据库,操作难度都比较高,且都需要一定的条件。
比如我们现在需要写一个应用程序,仅仅只是需要记录一下用户的设定。
这种很常见,比如程序启动时用什么主题、有没有声音、是否弹窗、上次用户的操作记录等等需要记录的信息。
那此时用数据库就大可不必了,因为你完全可以将这些信息写入一个文件,然后在下次程序启动时读出即可。
除了这种你自己设计格式来读取、写入的数据文件,windows
其实有一种专门的配置文件用来记录信息,也许你见过:
这种文件以.ini
结尾,其格式十分简单:
之所以它很常见,就是因为这是window自带的一种格式,有现成的函数可以让我们使用这种格式,所以下面我们首先就来使用一下这种格式文件。
随便建立一个控制台项目即可:
#include<iostream>
#include<Windows.h>
using namespace std;
int main() {
WritePrivateProfileStringA("main", "test1", "www.kucoding.com", ".\\1.ini");
WritePrivateProfileStringA("main", "test2", "hah", ".\\1.ini");
WritePrivateProfileStringA("main", "test3", "rebr", ".\\1.ini");
WritePrivateProfileStringA("second", "test4", "vferg", ".\\1.ini");
WritePrivateProfileStringA("second", "test5", "we23v", ".\\1.ini");
WritePrivateProfileStringA("second", "test6", "ntres", ".\\1.ini");
WritePrivateProfileStringA("second", "test7", "cewef", ".\\1.ini");
}
对于写入配置文件,一般我们只需要调用WritePrivateProfileStringA这个函数:
BOOL WritePrivateProfileStringA(
[in] LPCSTR lpAppName, //节名称
[in] LPCSTR lpKeyName, //键名
[in] LPCSTR lpString, //值名
[in] LPCSTR lpFileName //进行写入的文件名(注意要写成相对路径或者绝对路径的格式,直接写文件名会失败)
);
上面代码的执行结果:
节名称就是[main]
与[second]
这种,键名就是test1
、test2
等等,值名就是键名后面等于号紧跟的内容。
这是存取数据的过程,非常简单,当然也还有读出数据的过程:
#include<iostream>
#include<Windows.h>
using namespace std;
int main() {
char buf[0xFF];
GetPrivateProfileStringA("main", "test1", "", buf, 0xFF, ".\\1.ini");
cout << buf << endl;
GetPrivateProfileStringA("main", "test2", "", buf, 0xFF, ".\\1.ini");
cout << buf << endl;
GetPrivateProfileStringA("main", "test3", "", buf, 0xFF, ".\\1.ini");
cout << buf << endl;
GetPrivateProfileStringA("second", "test4", "", buf, 0xFF, ".\\1.ini");
cout << buf << endl;
GetPrivateProfileStringA("second", "test5", "", buf, 0xFF, ".\\1.ini");
cout << buf << endl;
GetPrivateProfileStringA("second", "test6", "", buf, 0xFF, ".\\1.ini");
cout << buf << endl;
GetPrivateProfileStringA("second", "test7", "", buf, 0xFF, ".\\1.ini");
cout << buf << endl;
}
这里也只是调用了一个函数GetPrivateProfileStringA而已:
DWORD GetPrivateProfileStringA(
[in] LPCSTR lpAppName, //节名
[in] LPCSTR lpKeyName, //键名
[in] LPCSTR lpDefault, //如果键名不在配置文件中,将返回这个值
[out] LPSTR lpReturnedString, //得到键值的缓存区
[in] DWORD nSize, //缓存区大小
[in] LPCSTR lpFileName //文件名
);
通过上面这两个函数,我们就已经能够完成基本的数据存储与读取,甚至我们同样也可以将它称为一个最简单的数据库,因为它真的很简单,但同样也很好用不是吗?
很多时候,我们的程序使用这种配置文件进行存取数据,其实就已经可以满足基本要求了。
当然,上面两个函数只能操作字符串的读取与写入,如果配置文件中有数字的话,其实也可以使用GetPrivateProfileIntA 这个函数来读取。
4.json与XML
上面谈到的配置文件,虽然简单易用,但同时也由于其太简单,虽然常用,但其实它的使用范围并不是太广。
所以就有了更近一步的格式文件,即json
与xml
,但xml
这种存储数据的文件格式如今使用范围并不如json
。
首先来看一看xml
格式文件长什么样,比如我们常用的VS,它的项目属性就是靠xml
格式组织的:
.sln
文件是解决方案的管理文件,而.vcxprof
则是具体某个项目的数据管理文件,用记事本打开它看一看?
可以看到,xml
格式的文件,采用的是一种标签模式存储数据,和html
很像。
比如<Platform>Win32</Platform>
,就是用<></>
形式组织数据的,Platform
为标签名,Win32
为该标签的数据。
VS打开项目,实际就是在解析这个文件中的项目数据,然后做进一步的处理罢了。
C/C++本身并不自带解析XML
的库,所以想要使用的话,还得自己去网上查找、下载、编译对应的库,才能够使用,非常麻烦。
后面要提到的json
也是如此,所以这里不过多深入的探究,等到后面学习Qt的时候我会进行讲解,因为Qt本身自带这些解析库,使用起来更加方便!
上面的xml
虽然看起来不太难,但却着实不方便我们查看,因为各种标签杂糅,所以就又有了json
这种存储数据的格式。
json
格式的数据,目前已经大范围的在互联网上进行使用了,不仅仅只是互联网,甚至很多本地的应用程序也会采用json格式来存储数据。
比如vscode
,它的配置文件就是用的json
格式:
虽然这里看起来似乎你依旧会觉得有点复杂,但相比于xml而言,这已经简化很多了,至于其具体的使用方法,就留到后面再讲解了。
5.Sqlite数据库
经过上面一步一步推进,接下来就正式进入数据库的环节了,即Sqlite3
这个数据库,它是目前使用、操作起来最简单的一种数据库。
简单,肯定也是与mysql等数据库相比较而言的,如果是与上面那几种数据存储格式比较的话,那还是很复杂的。
因为Sqlite
数据库不像mysql那样:需要下载一大堆东西,启动对应的服务,最终才能使用,即使使用起来了,大多数时候你甚至可能都不知道它把数据存在了哪里。
而使用Sqlite
,我们只需要包含一个头文件、一个源文件,即可在C++的程序中使用了。
同时它存储的数据就在一个文件里面,且一般就在应用程序旁边,你可以随意备份、删除等等
因为它的简单、易用、小巧,目前也是被广泛使用在一些小型设备上,比如我们常用的安卓手机,里面一般就会有这个数据库的影子,只是我们看不到罢了。
麻雀虽小五脏俱全,它的功能与mysql
这种大型数据库而言,虽然有不少差距,但使用方法却差的并不多,至少SQL语句都是通用的。
5.1 下载
可以点击这里去官方下载:
这里直接下载源码即可,只有不到3M
,是不是相当的小巧!
下载解压后,可以看到里面只有4个文件:
shell.c
:命令行方式操作数据库文件的可执行文件的源码,我们用不着sqlite3.c
:代码操作数据库的源码文件sqlite3.h
:对应的头文件sqlite3ext.h
:如果想用动态库链接的方式同时没有对应的.lib
库,可以用这个文件代替,不过我们用不着
虽然有四个文件,但其实我们用到的文件依旧只是两个源代码文件而已,即sqlite3.c
与sqlite3.h
只要将这两个文件复制到我们的项目中就可以使用了,是不是非常的方便!
5.2 使用
直接将上面两个文件,复制到我们项目中即可:
然后添加到我们的项目中: