数据存储与SQLite数据库
一、数据存储结构分类
数据存储按“掉电/程序结束后数据是否保留”分为两类,核心差异及示例如下:
存储介质 | 数据保留特性 | 典型存储形式 |
---|---|---|
内存 | 掉电/程序结束后数据丢失 | 数组、变量 |
硬盘 | 掉电/程序结束后数据不丢失 | 文件、数据库 |
二、常用数据库分类
数据库按数据存储结构分为“关系型”和“非关系型”,具体特点及代表产品如下:
1. 关系型数据库
- 核心特点:将复杂数据简化为二维表格形式,结构固定。
- 按规模分类:
- 大型:Oracle、DB2
- 中型:MySQL、SQL Server
- 小型:SQLite
2. 非关系型数据库
- 核心特点:以键值对(如JSON格式)存储,数据结构不固定,灵活性高。
- 代表产品:Redis、MongoDB
三、SQLite数据库核心特性
SQLite是轻量级小型关系型数据库,核心优势如下:
- 开源免费:基于C语言开发,开源免费,无版权费用。
- 体积轻量:代码量约1万行,总大小控制在10M以内。
- 跨平台易移植:文件型数据库(数据库对应单个文件),可直接移动使用,跨平台移植性好。
- 容量充足:理论最大数据容量可达2T。
四、SQLite3安装与测试
1. 安装命令(Linux环境)
- 安装SQLite3本体:
sudo apt-get install sqlite3
(指定版本为3.22.0) - 安装相关开发库:
sudo apt-get install libsqlite3-dev
2. 测试:创建数据库
执行命令 :sqlite3 xxx.db
(将“xxx”替换为自定义数据库名),即可创建并进入目标数据库。
五、SQLite3学习要点
1. 支持的数据类型
类型 | 说明 |
---|---|
NULL | 空值 |
INTEGER | 整数类型 |
REAL | 浮点型(小数) |
TEXT | 字符串类型 |
BLOB | 按输入原始格式存储 |
2. SQLite3常用命令(以“.”开头)
命令 | 功能描述 |
---|---|
.help | 查看所有支持的命令 |
.tables | 查看当前数据库中的所有表 |
.headers on/off | 开启/隐藏查询结果的表头 |
.mode column | 设置查询结果列左对齐 |
.quit | 退出SQLite数据库环境 |
3. SQLite3支持的SQL语句(关键规则:末尾必须加“ ; ”,不区分大小写)
(1)创建表
- 语法:
create table 表名(列名1 数据类型, 列名2 数据类型, ...);
- 示例:
create table class1(id INTEGER, name TEXT, age INTEGER, score REAL);
(2)插入数据
- 语法:
insert into 表名 values(值1, 值2, ...);
(值需与列顺序匹配) - 示例:
insert into class1 values(1, "zhangsan", 19, 88.5);
(3)查询数据
- 查所有列:
select * from 表名;
- 查指定列:
select 列名1, 列名2 from 表名;
(注意“from”勿错写) - 条件查询:
select * from 表名 where 列 条件;
- 关系运算符:
>、<、>=、<=、=、!=
,逻辑符and
(与)、or
(或) - 模糊查找(字符串):
%
匹配多个字符:select * from 表名 where 列 like "%梅";
(匹配“XX梅”“梅”等)_
匹配1个字符:select * from 表名 where 列 like "__梅";
(仅匹配“XX梅”)
- 关系运算符:
- 排序查找:
- 升序(默认):
select * from 表名 order by 列名 ASC;
- 降序:
select * from 表名 order by 列名 DESC;
- 升序(默认):
(4)删除数据
- 语法:
delete from 表名 where 删除条件;
(无条件会删除全表数据) - 示例:
delete from class1 where score < 80;
(删除分数低于80的记录)
(5)修改数据
- 语法:
update 表名 set 列 = 新值 where 条件;
(无条件会修改全表该列) - 示例:
update class1 set score=100 where name="wanger";
(将“wanger”的分数改为100)
(6)删除表
- 语法:
drop table 表名;
(删除整个表结构及数据,不可恢复)
(7)设置主键自动增长列
- 关键规则:
- 自动增长列必须是
INTEGER
类型; - 创建表时需加
PRIMARY KEY AUTOINCREMENT
; - 插入数据时,该列传
NULL
即可自动增长。
- 自动增长列必须是
- 示例:
- 创建表:
create table class2(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, score REAL);
- 插入数据:
insert into class2 values(NULL, "张三", 90);
- 创建表:
(8)时间相关函数
- 获取当前日期(年-月-日):
date("now");
- 获取当前时间(年-月-日 时:分:秒,+8小时时区):
datetime("now", "+8 hours");
4. SQLite可视化工具
- 安装:
sudo apt-get install sqlitebrowser
- 启动并打开数据库:
sqlitebrowser xxx.db
(“xxx.db”为目标数据库文件)
六、SQLite3的C/C++ API接口
1. sqlite3_open(打开数据库)
- 功能:打开指定名称的数据库文件(若不存在则创建)。
- 参数:
filename
:数据库文件名(UTF-8格式);ppDb
:保存数据库句柄(handle)的指针地址(用于后续操作)。
- 返回值:成功返回
SQLITE_OK
,失败返回错误码。 - 代码
#include <stdio.h>
#include <sqlite3.h>int main(int argc, char const *argv[])
{sqlite3 *pdb;int ret = sqlite3_open("./stu.db", &pdb);if(ret != SQLITE_OK){fprintf(stderr, "sqlite3_open error : %s\n", sqlite3_errmsg(pdb));return -1;}char *psql = "create table if not exists class3(id INTEGER, name TEXT, score REAL);";ret = sqlite3_exec(pdb, psql, NULL,NULL,NULL);if(ret != SQLITE_OK){fprintf(stderr, "sqlite3_open error : %s\n", sqlite3_errmsg(pdb));sqlite3_close(pdb);return -1;}char sql[128] = {"insert into class3 values(1, \"马超\", 99);"};ret = sqlite3_exec(pdb, sql, NULL,NULL,NULL);if(ret != SQLITE_OK){fprintf(stderr, "sqlite3_open error : %s\n", sqlite3_errmsg(pdb));sqlite3_close(pdb);return -1;}sqlite3_close(pdb);return 0;
}
2. sqlite3_close(关闭数据库)
- 功能:关闭已打开的数据库句柄,释放资源。
- 参数:
sqlite3*
类型的数据库句柄。
3. sqlite3_exec(执行SQL语句)
- 功能:执行任意SQL语句(如创建表、插入、删除等,查询语句需配合回调函数)。
- 参数:
pdb
:已打开的数据库句柄;sql
:待执行的SQL语句字符串;callback
:执行select
查询时的回调函数(非查询语句可传NULL
);arg
:传递给回调函数的自定义参数;errmsg
:保存执行错误信息的指针(需手动释放)。
- 返回值:成功返回
SQLITE_OK
,失败返回错误码。
4. 回调函数(仅select
查询时使用)
- 定义:
int (*callback)(void* arg, int column, char** column_values, char** column_name);
- 功能:查询到一条数据就调用一次,用于处理查询结果。
- 参数:
arg
:sqlite3_exec
传递的第4个自定义参数;column
:当前查询结果的列数;column_values
:指针数组,每个元素指向一列数据的字符串(所有数据均以字符串形式返回);column_name
:指针数组,每个元素指向一列的列名。
- 注意事项:
- 回调函数成功执行后必须返回
0
,否则会提示“sqlite3_exec error : query aborted”; - 数据库查询结果全部以字符串类型返回(需自行转换为目标类型,如整数、浮点);
- 查询到
N
条数据,回调函数就会被调用N
次。
- 回调函数成功执行后必须返回
- 代码
#include <stdio.h>
#include <sqlite3.h>int flag = 0;int callback(void *arg, int column, char **values, char **name)
{if(flag == 0){for(int i = 0; i < column; i++){printf("%s ", name[i]);}printf("\n");flag = 1;}for(int i = 0; i < column; i++){printf("%s ", values[i]);}printf("\n");return 0; // 必须要有返回值 成功 返回 0
}int main(int argc, char const *argv[])
{sqlite3 *pdb;int ret = sqlite3_open("./stu.db", &pdb);if(ret != SQLITE_OK){fprintf(stderr, "sqlite3_open error : %s\n", sqlite3_errmsg(pdb));return -1;}char *psql = "select * from data;";ret = sqlite3_exec(pdb, psql, callback, NULL, NULL);if(ret != SQLITE_OK){fprintf(stderr, "sqlite3_exec error : %s\n", sqlite3_errmsg(pdb));sqlite3_close(pdb);return -1;}sqlite3_close(pdb);return 0;
}