19. 数据库的理解和使用

1.前言

本章并不会教你如何学会使用某一个具体的数据库。

如果需要可以参考本站的其它教程,对于仅仅只是应用来说,它并不复杂,只是有点繁琐而已,需要记忆的东西比较多。

本文的目的是尝试从比较宏观的角度来看待数据库,以及在不同的地方,使用合适的数据库。

2.理解数据库

首先我们还是要来理解一下数据库的本质。

看数据库这个名字,我们就能看出一二,数据库即数据的库存,用于数据的存储与取出,乃至一些更高级的操作。

我们最常见的数据库,可能就是我们windows电脑上自带的注册表了(不知道如何打开?浏览器搜一搜):

image-20231227193056097

注册表里面就存储了我们电脑所有的信息,在一些时候会进行写入,同时有些时候会进行读取操作,因为它是独立于各个应用程序的。

独立于应用程序,这一点很重要,即一个数据库,可以被不同程序访问,它并不属于某个应用程序。

比如我们常用的QQ,微信,为什么我们登录各种游戏,很多都可以用QQ、微信登录?

那就是因为它们可以向你申请权限来访问腾讯存储你信息的数据库,即它们也可以通过一些腾讯提供的接口,来访问腾讯的数据库。

3.配置文件

在真正使用数据库前,要搞懂自己是否需要数据库,因为即使是最简单的数据库,操作难度都比较高,且都需要一定的条件。

比如我们现在需要写一个应用程序,仅仅只是需要记录一下用户的设定。

这种很常见,比如程序启动时用什么主题、有没有声音、是否弹窗、上次用户的操作记录等等需要记录的信息。

那此时用数据库就大可不必了,因为你完全可以将这些信息写入一个文件,然后在下次程序启动时读出即可。

除了这种你自己设计格式来读取、写入的数据文件,windows其实有一种专门的配置文件用来记录信息,也许你见过:

image-20231227193342854

这种文件以.ini结尾,其格式十分简单:

image-20231227193402219

之所以它很常见,就是因为这是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 //进行写入的文件名(注意要写成相对路径或者绝对路径的格式,直接写文件名会失败)
);

上面代码的执行结果:

image-20231227193605166

节名称就是[main][second]这种,键名就是test1test2等等,值名就是键名后面等于号紧跟的内容。

这是存取数据的过程,非常简单,当然也还有读出数据的过程:

#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

上面谈到的配置文件,虽然简单易用,但同时也由于其太简单,虽然常用,但其实它的使用范围并不是太广。

所以就有了更近一步的格式文件,即jsonxml,但xml这种存储数据的文件格式如今使用范围并不如json

首先来看一看xml格式文件长什么样,比如我们常用的VS,它的项目属性就是靠xml格式组织的:

image-20231227193740100

.sln文件是解决方案的管理文件,而.vcxprof则是具体某个项目的数据管理文件,用记事本打开它看一看?

image-20231227193818929

可以看到,xml格式的文件,采用的是一种标签模式存储数据,和html很像。

比如<Platform>Win32</Platform>,就是用<></> 形式组织数据的,Platform为标签名,Win32为该标签的数据。

VS打开项目,实际就是在解析这个文件中的项目数据,然后做进一步的处理罢了。

C/C++本身并不自带解析XML的库,所以想要使用的话,还得自己去网上查找、下载、编译对应的库,才能够使用,非常麻烦。

后面要提到的json也是如此,所以这里不过多深入的探究,等到后面学习Qt的时候我会进行讲解,因为Qt本身自带这些解析库,使用起来更加方便!

上面的xml虽然看起来不太难,但却着实不方便我们查看,因为各种标签杂糅,所以就又有了json这种存储数据的格式。

json格式的数据,目前已经大范围的在互联网上进行使用了,不仅仅只是互联网,甚至很多本地的应用程序也会采用json格式来存储数据。

比如vscode,它的配置文件就是用的json格式:

image-20231227194556902

虽然这里看起来似乎你依旧会觉得有点复杂,但相比于xml而言,这已经简化很多了,至于其具体的使用方法,就留到后面再讲解了。

5.Sqlite数据库

经过上面一步一步推进,接下来就正式进入数据库的环节了,即Sqlite3这个数据库,它是目前使用、操作起来最简单的一种数据库。

简单,肯定也是与mysql等数据库相比较而言的,如果是与上面那几种数据存储格式比较的话,那还是很复杂的。

因为Sqlite数据库不像mysql那样:需要下载一大堆东西,启动对应的服务,最终才能使用,即使使用起来了,大多数时候你甚至可能都不知道它把数据存在了哪里。

而使用Sqlite,我们只需要包含一个头文件、一个源文件,即可在C++的程序中使用了。

同时它存储的数据就在一个文件里面,且一般就在应用程序旁边,你可以随意备份、删除等等

因为它的简单、易用、小巧,目前也是被广泛使用在一些小型设备上,比如我们常用的安卓手机,里面一般就会有这个数据库的影子,只是我们看不到罢了。

麻雀虽小五脏俱全,它的功能与mysql这种大型数据库而言,虽然有不少差距,但使用方法却差的并不多,至少SQL语句都是通用的。

5.1 下载

可以点击这里去官方下载:

image-20231227194933544

这里直接下载源码即可,只有不到3M,是不是相当的小巧!

下载解压后,可以看到里面只有4个文件:

image-20231227195131633

  1. shell.c:命令行方式操作数据库文件的可执行文件的源码,我们用不着
  2. sqlite3.c:代码操作数据库的源码文件
  3. sqlite3.h:对应的头文件
  4. sqlite3ext.h:如果想用动态库链接的方式同时没有对应的.lib库,可以用这个文件代替,不过我们用不着

虽然有四个文件,但其实我们用到的文件依旧只是两个源代码文件而已,即sqlite3.csqlite3.h

只要将这两个文件复制到我们的项目中就可以使用了,是不是非常的方便!

5.2 使用

直接将上面两个文件,复制到我们项目中即可:

image-20231227195357343

然后添加到我们的项目中:

image-20231227195435272

作者:余识
全部文章:0
会员文章:0
总阅读量:0
c/c++pythonrustJavaScriptwindowslinux