Linux应用软件编程|嵌入式轻量级数据库SQLite3完整学习笔记(命令行+C语言API)

一、数据库基础概念

1.1 普通文件 VS 数据库

|-------------|------------------------|---------------------------|
| 对比项 | 普通文件 (txt/bin) | SQLite3 数据库 |
| 存储形式 | 文本 / 二进制文件 | 单 db 文件,包含表、索引、数据 |
| 增删改查 | 需要自己代码解析,效率低 | SQL 语句直接完成 CRUD,内置索引,查询高效 |
| 数据组织 | 自定义格式,无规范 | 二维表格,关系模型 |
| 并发访问 | 需要自己做读写保护 | 内置锁机制 |
| 部署 | 直接读写文件 | 链接 sqlite3 库,无后台服务进程 |

普通文件适合简单少量数据;当数据量大、频繁查询、条件筛选,优先选用数据库。

1.2 数据库分类

1. 关系型数据库:以二维表格存储数据

  • 大型:Oracle、DB2

  • 中型:MySQL、SQL Server

  • 小型嵌入式:SQLite3

2. 非关系型数据库:键值、文档存储

  • Redis(内存键值数据库)

  • MongoDB(文档数据库)

1.3 SQLite3数据库特点

  1. 开源免费,纯C语言开发,代码量小,库体积10M以内,资源占用极低。

  2. 文件型数据库:全部数据保存在一个xxx.db文件,可以直接拷贝、迁移。

  3. 无服务进程:应用程序直接调用sqlite3库访问数据库,不需要启动后台数据库服务。

  4. 跨平台:Linux、Windows、Android都可以使用。

  5. 最大支持2TB数据库文件,满足嵌入式设备存储需求。

缺点:不适合高并发大量写入;不支持网络远程访问,只能本地访问。

二、SQLite3命令行工具使用

2.1 安装sqlite3

bash

Ubuntu/Debian

sudo apt-get install sqlite3

sudo apt-get install libsqlite3-dev C语言开发库,编译程序必须安装

2.2 进入数据库命令行

bash

sqlite3 stu.db

  • 如果stu.db文件不存在,sqlite3会自动创建数据库文件;

  • 如果文件已经存在,直接打开数据库。

注意:sqlite3命令行中,以.开头是点命令(工具内置),不带分号;SQL语句必须以分号;结尾。

常用点命令

sql

.help -- 查看帮助

.tables -- 查看数据库中所有表名

.headers on -- 打开查询结果表头显示

.mode column -- 格式化输出,列对齐

.quit -- 退出sqlite3命令行

可视化工具

  • 命令行:sqlite3

  • 图形工具:sqlitebrowser,可以打开db文件可视化查看表与数据

bash

sudo apt-get install sqlitebrowser

sqlitebrowser stu.db

三、SQLite3基础SQL语句

SQLite数据类型:

  • NULL:空

  • INTEGER:整型

  • REAL:浮点

  • TEXT:字符串文本

  • BLOB:二进制原始数据

3.1 创建数据表 CREATE TABLE

语法:

sql

CREATE TABLE 表名(列名1 类型,列名2 类型,列名3 类型...);

示例,创建学生表:

sql

CREATE TABLE class1(

id INTEGER PRIMARY KEY AUTOINCREMENT,

name TEXT,

score REAL

);

  • PRIMARY KEY:主键,唯一标识一行记录;

  • AUTOINCREMENT:主键自动增长,插入数据不用手动填写id。

3.2 插入数据 INSERT

sql

--完整字段插入

INSERT INTO class1(name,score) VALUES("zhangsan",88.5);

--全部字段插入,主键自增写NULL

INSERT INTO class1 VALUES(NULL,"lisi",92.0);

TEXT字符串必须用双引号或者单引号包裹。

3.3 查询数据 SELECT

sql

--查询表全部列全部数据

SELECT FROM class1;

--只查询name、score两列

SELECT name,score FROM class1;

--条件查询,分数大于80

SELECT FROM class1 WHERE score80;

--多条件 and / or

SELECT FROM class1 WHERE score60 AND score<90;

--模糊匹配 %匹配任意多个字符,_匹配单个字符

SELECT FROM class1 WHERE name LIKE "zhang%";

--排序:ASC升序,DESC降序

SELECT FROM class1 ORDER BY score DESC;

3.4 修改数据 UPDATE

sql

UPDATE class1 SET score=95 WHERE id=1;

不加WHERE条件会修改表里面全部记录!开发务必小心。

3.5 删除数据 DELETE

sql

DELETE FROM class1 WHERE id=2;

不加WHERE条件会删除整张表全部数据。

3.6 删除表 DROP TABLE

sql

DROP TABLE class1;

四、SQLite3 C语言API编程

编译注意:使用sqlite3的C代码编译时,需要链接sqlite库:gcc main.c -o app -lsqlite3

4.1 核心API总览

|------------------|------------------------|
| 函数 | 功能 |
| sqlite3_open() | 打开 / 创建数据库,获取数据库句柄 |
| sqlite3_errmsg() | 获取错误信息字符串 |
| sqlite3_exec() | 执行 SQL 语句,支持回调函数处理查询结果 |
| sqlite3_close() | 关闭数据库,释放资源 |

1)sqlite3_open 打开数据库

include <sqlite3.h

int sqlite3_open(const char filename, sqlite3 ppDb);

  • filename:数据库文件路径,如"./stu.db";文件不存在自动创建;

  • ppDb:输出参数,数据库句柄指针,后续所有操作都使用这个句柄;

  • 返回值:成功返回SQLITE_OK(0);失败返回非0错误码。

打开数据库不等于打开文件,sqlite内部会处理表、索引。

2)sqlite3_close 关闭数据库

int sqlite3_close(sqlite3 pDb);

用完数据库一定要close释放资源。

3)sqlite3_errmsg 获取错误信息

const char sqlite3_errmsg(sqlite3 pdb);

传入数据库句柄,返回错误描述字符串,方便打印调试。

4)sqlite3_exec(最重要)执行SQL语句

int sqlite3_exec(

sqlite3 pdb, //数据库句柄

const char sql, //要执行的SQL字符串

int (callback)(void,int,char,char), //查询回调函数

void arg, //传递给回调函数的自定义参数

char errmsg //输出错误信息

);

关键点:

  1. 增、删、改(INSERT / UPDATE / DELETE):没有返回结果集,callback填NULL;

  2. SELECT查询语句:必须传入回调函数;查询到每一行记录,就会调用一次callback回调;

  3. 返回值:成功返回SQLITE_OK;失败非0。

查询回调函数原型

int callback(void arg, int n, char value, char name);

  • arg:sqlite3_exec传入的第四个参数;

  • n:当前这一行有多少列;

  • value\[\]:字符串数组,保存这一行每一列的数据;

  • name\[\]:字符串数组,保存每一列的表头字段名;

  • 返回值:必须返回0,返回非0会终止查询。

4.2 完整C语言示例代码

include <stdio.h

include <sqlite3.h

include <string.h

/ 查询回调函数 /

int sql_callback(void arg, int col_cnt, char col_val, char col_name)

{

//打印一行数据

for(int i = 0; i < col_cnt; i++)

{

printf("%s = %s\t", col_namei, col_vali?col_vali:"NULL");

}

printf("\n");

return 0;

}

int main(void)

{

sqlite3 db;

char errmsg = NULL;

int ret;

//1.打开数据库,不存在则创建

ret = sqlite3_open("./stu.db", &db);

if(ret != SQLITE_OK)

{

printf("打开数据库失败:%s\n", sqlite3_errmsg(db));

return -1;

}

printf("数据库打开成功\n");

//2.创建表

char sql_create = "CREATE TABLE IF NOT EXISTS class1("

"id INTEGER PRIMARY KEY AUTOINCREMENT,"

"name TEXT,"

"score REAL);";

ret = sqlite3_exec(db, sql_create, NULL, NULL, &errmsg);

if(ret != SQLITE_OK)

{

printf("建表失败:%s\n", errmsg);

sqlite3_free(errmsg);

}

//3.插入数据

char sql_insert = "INSERT INTO class1(name,score) VALUES('zhangsan',88.5);";

ret = sqlite3_exec(db, sql_insert, NULL, NULL, &errmsg);

if(ret != SQLITE_OK)

{

printf("插入失败:%s\n", errmsg);

sqlite3_free(errmsg);

}

//4.查询数据,传入回调函数接收结果

char sql_select = "SELECT FROM class1;";

printf("====查询结果====\n");

ret = sqlite3_exec(db, sql_select, sql_callback, NULL, &errmsg);

if(ret != SQLITE_OK)

{

printf("查询失败:%s\n", errmsg);

sqlite3_free(errmsg);

}

//5.关闭数据库

sqlite3_close(db);

return 0;

}

编译命令:

bash

gcc sqlite_demo.c -o sqlite_demo -lsqlite3

./sqlite_demo

五、常见开发注意事项

  1. SQL注入风险:不要直接用sprintf拼接外部输入内容到SQL语句;正式项目建议使用预处理接口sqlite3_prepare_v2。

  2. errmsg内存:sqlite3_exec输出的errmsg,出错后需要调用sqlite3_free(errmsg)释放,避免内存泄漏。

  3. 回调函数:SELECT查询每一行调用一次回调;回调函数必须返回0,否则查询直接中断。

  4. SQLite3写锁:SQLite数据库文件写的时候会加文件锁,多进程同时写会阻塞或者报错。

  5. 数据库文件权限:嵌入式开发注意db文件的读写权限,否则打开失败。

小结

  1. SQLite3是嵌入式Linux首选轻量级关系数据库,单文件、无后台服务、C语言开发、资源占用低;适合设备本地存储。

  2. 掌握命令行工具sqlite3,熟悉点命令.tables .headers on .mode column .quit。

  3. 基础SQL:CREATE建表、INSERT插入、SELECT查询、UPDATE修改、DELETE删除、DROP删除表。

  4. C语言核心API:sqlite3_open打开数据库,sqlite3_exec执行SQL,查询要注册callback回调,sqlite3_close关闭数据库。

  5. 编译程序必须链接-lsqlite3;开发注意内存释放、SQL注入、文件锁问题。

相关推荐
神威难绷泪1 小时前
TCP并发服务器:多进程 多线程 IO多路复用(select poll epoll)
linux·ipc·tcp并发服务器
kruptos1 小时前
嵌入式 Linux 驱动开发:第一个内核模块怎么写?
linux·运维·驱动开发·嵌入式硬件
wangqiaowq1 小时前
langfuse linux下的安装部署
linux·运维·服务器
NeilYuen1 小时前
用RDMA实现文件传输
linux
Discipline~Hai1 小时前
Linux网络编程05-sqlite3数据库
linux·c语言·网络·数据库·sqlite·linux应用软件编程
Huangjin007_1 小时前
【Linux 系统篇(十七)】进程(五) :进程切换、O(1) 调度算法
linux·运维·服务器
weixin_464307631 小时前
linux虚拟机断网
linux·运维·服务器
λqaq72 小时前
Docker 容器入门基础:Cloud Studio 在线 Linux 环境上手
linux·运维·docker
en.en..2 小时前
LVGL 普通函数指针与结构体函数指针原理
linux·windows·microsoft