Linux---sqlite3数据库

一、数据库分类

1. 按数据关系分类
类型 特点 代表产品
关系型数据库 - 使用 SQL(结构化查询语言)<br>- 数据以行列形式存储,支持事务和复杂查询 MySQL、Oracle、SQLite
非关系型数据库 - 无固定表结构(如键值对、文档、图)<br>- 高扩展性,适合非结构化数据 MongoDB、Redis
2. 按功能规模分类
类型 特点 代表产品
大型数据库 高并发、高可用性,支持企业级应用 Oracle、DB2
中型数据库 适用于中小型企业,跨平台支持 MySQL、MSSQL
小型数据库 轻量级,嵌入式或单机应用 SQLite

注:以上分类中的代表产品均为关系型数据库。


二、核心概念与术语

1. 基础术语
  • DB(Database):存储数据的集合(如:用户表、订单表)。
  • DBMS(Database Management System):管理数据库的软件(如:MySQL、Oracle)。
  • MIS(Management Information System):集成数据库的管理信息系统(如:ERP系统)。
  • OA(Office Automation):基于数据库的办公自动化系统(如:审批流程系统)。
2. 数据库结构层次
复制代码
数据库(DB)
├── 表(Table)
│   ├── 字段(Field,最小单位,如:姓名、年龄)
│   └── 记录(Record,由字段组成的一行数据)
└── 其他表...
  • 字段 :表的列,定义数据类型(如:VARCHARINT)。
  • 记录:表的行,表示一条完整数据。

三、SQLite 数据库特点

1. 核心特性
特性 说明
开源与轻量 使用 C 语言开发,代码量约 1 万行,体积小于 10MB
无需安装 绿色软件,直接集成到应用中
文件型数据库 数据存储在单一文件中(如:data.db),便于迁移和备份
高兼容性 支持跨平台(Windows/Linux/嵌入式设备)
容量限制 单库最大支持 2TB 数据
2. 适用场景
  • 移动应用(如:Android/iOS 本地存储)
  • 嵌入式设备(如:智能硬件)
  • 小型项目原型开发

四、数据库文件操作

1. 创建/打开数据库
复制代码
sqlite3 test.db    # 创建或打开 test.db 数据库文件

提示符变为 sqlite> 表示进入交互模式

2. 导入导出数据
复制代码
# 导出数据库到 SQL 脚本
sqlite3 test.db .dump > backup.sql

# 从 SQL 脚本导入数据
sqlite3 new.db < backup.sql

五、数据表操作 (DDL)

1. 创建表
复制代码
-- 基础表结构
CREATE TABLE users (
    id INTEGER PRIMARY KEY,   -- 主键约束
    name TEXT NOT NULL,       -- 非空约束
    age INTEGER,
    reg_date DATETIME DEFAULT CURRENT_TIMESTAMP
);

-- 带自增主键
CREATE TABLE user3 (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name CHAR(20),
    age INT
);

SQLite 是弱类型数据库,字段类型仅为建议类型

2. 删除表
复制代码
DROP TABLE users;  -- 慎用!会删除表结构和所有数据

六、数据操作 (DML)

1. 插入数据
复制代码
-- 全字段插入
INSERT INTO users VALUES (1, '张三', 25, '2023-08-20 10:00:00');

-- 指定字段插入
INSERT INTO users (name, age) VALUES ('李四', 30);

-- 插入当前时间
INSERT INTO user1 VALUES (2, '王五', 28, datetime('now','+8 hours'));
2. 更新数据
复制代码
-- 修改指定记录
UPDATE users SET age = 26 WHERE name = '张三';

-- 多条件更新
UPDATE users SET age = 27 WHERE name = '李四' AND id = 2;
3. 删除数据
复制代码
-- 清空表 (保留结构)
DELETE FROM users;

-- 条件删除
DELETE FROM users WHERE age < 18;
DELETE FROM users WHERE id = 3 OR name = 'test';

七、数据查询 (DQL)

1. 基础查询
复制代码
-- 查询所有字段
SELECT * FROM users;

-- 查询指定字段
SELECT name, age FROM users;

-- 条件查询
SELECT * FROM users WHERE age BETWEEN 20 AND 30;
2. 复杂查询
复制代码
-- 排序查询
SELECT * FROM users ORDER BY age DESC;

-- 模糊查询
SELECT * FROM users WHERE name LIKE '张%';

-- 分页查询
SELECT * FROM users LIMIT 10 OFFSET 5;  -- 第6-15条记录

八、系统命令(以 . 开头)

命令 功能
.tables 显示所有表
.schema users 查看 users 表结构
.dump users 导出 users 表的 SQL 脚本
.mode column 列式显示结果
.headers on 显示列标题
.q 退出 SQLite

九、数据类型与约束

1. 常用数据类型
类型 描述
INTEGER 整型 (支持自增 AUTOINCREMENT)
TEXT 字符串
REAL 浮点数
BLOB 二进制数据
DATETIME 日期时间 (需用函数处理)
2. 常用约束
约束 说明
PRIMARY KEY 主键 (唯一标识记录)
NOT NULL 禁止空值
DEFAULT 设置默认值
UNIQUE 值必须唯一

十、SQLite C 语言接口编程


(一)核心操作流程

复制代码
graph TD
    A[打开数据库 sqlite3_open] --> B[执行操作]
    B --> C{操作类型}
    C -->|查询| D[使用 sqlite3_get_table]
    C -->|增删改| E[使用 sqlite3_exec]
    B --> F[关闭数据库 sqlite3_close]

(二)核心函数详解

1. 打开数据库 sqlite3_open
复制代码
int sqlite3_open(const char *filename, sqlite3 **ppDb);
参数 说明
filename 数据库文件路径 (若不存在则自动创建)
ppDb 输出参数,用于接收数据库句柄指针

返回值

  • SQLITE_OK (0):成功
  • 其他值:错误代码 (需用 sqlite3_errmsg() 获取错误信息)

示例

复制代码
sqlite3 *db = NULL;
int rc = sqlite3_open("test.db", &db);
if (rc != SQLITE_OK) {
    fprintf(stderr, "无法打开数据库: %s\n", sqlite3_errmsg(db));
    exit(1);
}

2. 执行查询操作 sqlite3_get_table
复制代码
int sqlite3_get_table(
    sqlite3 *db,          // 数据库句柄
    const char *zSql,     // SQL 语句
    char ***pazResult,    // 结果集指针
    int *pnRow,           // 返回行数
    int *pnColumn,        // 返回列数
    char **pzErrmsg       // 错误信息指针
);

结果集结构

复制代码
// 假设查询返回 2 列 (name, age) 和 3 行数据
pazResult[0] = "name"
pazResult[1] = "age"
pazResult[2] = "Alice"
pazResult[3] = "25"
pazResult[4] = "Bob"
pazResult[5] = "30"

示例

复制代码
char **result;
int rows, cols;
char *errmsg = NULL;

rc = sqlite3_get_table(db, "SELECT name, age FROM users", 
                      &result, &rows, &cols, &errmsg);

if (rc == SQLITE_OK) {
    // 处理结果集
    for (int i = 0; i <= rows; i++) { // 第0行是列名
        for (int j = 0; j < cols; j++) {
            printf("%s\t", result[i*cols + j]);
        }
        printf("\n");
    }
    sqlite3_free_table(result); // 必须释放内存!
} else {
    fprintf(stderr, "SQL错误: %s\n", errmsg);
    sqlite3_free(errmsg);
}

3. 执行非查询操作 sqlite3_exec
复制代码
int sqlite3_exec(
    sqlite3 *db,               // 数据库句柄
    const char *sql,           // SQL 语句
    int (*callback)(void*,int,char**,char**), // 回调函数
    void *arg,                 // 回调函数参数
    char **errmsg              // 错误信息指针
);

回调函数原型

复制代码
int callback(
    void *arg,        // 用户传递的参数
    int num_cols,     // 结果列数
    char **col_values, // 当前行的列值
    char **col_names   // 列名数组
);

示例

复制代码
// 插入数据
rc = sqlite3_exec(db, "INSERT INTO users VALUES(3, 'Charlie', 28)", 
                  NULL, NULL, &errmsg);

// 带回调的查询
int print_callback(void *arg, int cols, char **values, char **names) {
    for (int i = 0; i < cols; i++) {
        printf("%s: %s\t", names[i], values[i]);
    }
    printf("\n");
    return 0; // 必须返回0
}

rc = sqlite3_exec(db, "SELECT * FROM users", 
                 print_callback, NULL, &errmsg);

4. 关闭数据库 sqlite3_close
复制代码
int sqlite3_close(sqlite3 *db);

注意事项

  • 关闭前必须完成所有事务
  • 返回 SQLITE_BUSY 表示仍有未完成的查询

(三)内存管理与错误处理

1. 释放资源
复制代码
sqlite3_free_table(char **result);  // 释放 sqlite3_get_table 的结果
sqlite3_free(void *ptr);           // 释放错误信息内存
2. 错误信息获取
复制代码
const char *errmsg = sqlite3_errmsg(db);
printf("错误信息: %s\n", errmsg);

实例:

程序用于将一个文本格式的字典文件(每行包含一个单词及其解释)转换为 SQLite 数据库格式,便于后续的查询和管理。

bash 复制代码
#include <stdio.h>
#include <sqlite3.h>
#include <string.h>
#include <unistd.h>

// 主函数,参数为字典文本文件和目标数据库文件
int main(int argc, const char *argv[])
{
    // 检查命令行参数是否正确
    if (argc != 3)
    {
        printf("Usage: %s <*.txt> <*.db>\n", argv[0]);
        return -1;
    }

    // 打开字典文本文件
    FILE *fp = fopen(argv[1], "r");
    if (fp == NULL)
    {
        perror("fopen fail");
        return -1;
    }

    // 初始化 SQLite 数据库
    sqlite3 *db;
    int ret = sqlite3_open("dict.db", &db); // 打开或创建数据库文件
    if (ret != SQLITE_OK)
    {
        printf("sqlite3_open fail:%s\n", sqlite3_errmsg(db));
        return -1;
    }
    printf("sqlite3_open success\n");

    // 创建字典表
    char sql[1024] = {0};
    printf("Please create table:");
    fgets(sql, sizeof(sql), stdin); // 从标准输入读取创建表的 SQL 语句
    sql[strlen(sql) - 1] = '\0';     // 去除换行符

    char *errmsg = NULL;
    ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg); // 执行 SQL 语句
    if (ret != SQLITE_OK)
    {
        printf("sqlite3_exec fail : %s \n", errmsg);
        return -1;
    }

    // 读取字典文本文件并插入数据库
    char buf[1024] = {0};
    int i = 0;
    while (1)
    {
        char *pret = fgets(buf, sizeof(buf), fp); // 逐行读取文本文件
        if (pret == NULL)
        {
            break; // 读取完成
        }

        // 解析单词和解释
        char *pword = strtok(buf, " ");    // 提取单词
        char *pexplain = strtok(NULL, "\r"); // 提取解释

        printf("pword    = %s\n", pword);
        printf("pexplain = %s\n", pexplain);

        // 构造插入 SQL 语句
        sprintf(sql, "insert into dict values (%d,\"%s\",\"%s\");", i, pword, pexplain);

        ret = sqlite3_exec(db, sql, NULL, NULL, &errmsg); // 执行插入操作
        if (ret != SQLITE_OK)
        {
            printf("sqlite3_exec fail : %s \n", errmsg);
            return -1;
        }
        ++i;
        // sleep(1); // 如果需要控制插入速度,可以取消注释
    }

    // 关闭文件和数据库连接
    fclose(fp);
    sqlite3_close(db);

    return 0;
}
相关推荐
沉到海底去吧Go11 分钟前
【图片自动识别改名】识别图片中的文字并批量改名的工具,根据文字对图片批量改名,基于QT和腾讯OCR识别的实现方案
数据库·qt·ocr·图片识别自动改名·图片区域识别改名·pdf识别改名
yzx99101323 分钟前
Linux 系统中的算法技巧与性能优化
linux·算法·性能优化
fengyehongWorld23 分钟前
Linux Docker的简介
linux·docker
老纪的技术唠嗑局28 分钟前
重剑无锋,大巧不工 —— OceanBase 中的 Nest Loop Join 使用技巧分享
数据库·sql
曹瑞曹瑞1 小时前
VMware导入vmdk文件
linux·运维·服务器
未来之窗软件服务1 小时前
JAVASCRIPT 前端数据库-V6--仙盟数据库架构-—-—仙盟创梦IDE
数据库·数据库架构·仙盟创梦ide·东方仙盟·东方仙盟数据库
Johny_Zhao1 小时前
2025年6月Docker镜像加速失效终极解决方案
linux·网络·网络安全·docker·信息安全·kubernetes·云计算·containerd·yum源·系统运维
hello kitty w1 小时前
Python学习(7) ----- Python起源
linux·python·学习
十年磨一剑~2 小时前
centos查看开启关闭防火墙状态
linux·运维·centos
一只爱撸猫的程序猿2 小时前
构建一个简单的智能文档问答系统实例
数据库·spring boot·aigc