复习——SQLite3 数据库

SQLite3 数据库学习笔记

一、SQL 语言概述

1.1 SQL 分类

  • DDL (Data Definition Language) - 数据定义语言

    • 创建、修改、删除数据库对象(表、索引等)

    • 命令:CREATE, ALTER, DROP

  • DML (Data Manipulation Language) - 数据操作语言

    • 插入、更新、删除表中的数据

    • 命令:INSERT, UPDATE, DELETE

  • DQL (Data Query Language) - 数据查询语言

    • 查询表中的数据

    • 命令:SELECT

1.2 数据库分类

  • 关系型数据库:SQLite, MySQL, Oracle, MSSQL

  • 非关系型数据库:MongoDB, Redis

二、SQLite3 简介

2.1 特点

  1. 开源 - C语言开发

  2. 轻量级 - 代码约1万行,大小<10MB

  3. 绿色软件 - 无需安装,解压即用

  4. 文件型数据库 - 数据库存储在单个文件中

  5. 容量大 - 支持最大2TB数据

2.2 安装

复制代码
# Ubuntu 安装
sudo apt-get install sqlite3
sudo apt-get install libsqlite3-dev

# 验证安装
sqlite3 --version
sqlite3 --help

2.3 编译选项

复制代码
gcc program.c -lsqlite3 -lpthread

三、SQLite3 基本使用

3.1 启动和退出

复制代码
# 启动数据库
sqlite3 database.db

# 退出数据库
sqlite> .quit  或 .q

# 退出续行模式
...> ;

3.2 系统维护命令(以.开头)

命令 功能
.help 显示所有维护命令
.database 显示当前数据库
.tables 显示所有表
.schema 表名 显示表结构
.dump 导出数据库

3.3 创建数据库

复制代码
# 方法1
touch mydb.db
sqlite3 mydb.db

# 方法2
sqlite3 mydb.db

四、SQL 语句详解

4.1 DDL - 创建和删除表

复制代码
-- 创建表(简单形式)
CREATE TABLE user(id, name, age);

-- 创建表(指定数据类型)
CREATE TABLE user(
    id INTEGER,
    name CHAR(50),
    age INT
);

-- 创建表(带主键)
CREATE TABLE user(
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT,
    age INTEGER
);

-- 删除表
DROP TABLE user;

数据类型

  • INTEGER - 整型

  • TEXT - 文本

  • REAL - 浮点数

  • BLOB - 二进制数据

4.2 DML - 数据操作

4.2.1 插入数据
复制代码
-- 插入完整记录
INSERT INTO user VALUES(1, '张三', 20);

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

-- 插入多行
INSERT INTO user VALUES
    (1, '张三', 20),
    (2, '李四', 22);
4.2.2 更新数据
复制代码
-- 更新所有记录
UPDATE user SET age = 25;

-- 条件更新
UPDATE user SET age = 30 WHERE name = '张三';

-- 多条件更新
UPDATE user SET age = 18 
WHERE name = '张三' AND id = 1;

UPDATE user SET age = 20 
WHERE name = '张三' OR name = '李四';
4.2.3 删除数据
复制代码
-- 删除所有数据
DELETE FROM user;

-- 条件删除
DELETE FROM user WHERE id = 1;

-- 多条件删除
DELETE FROM user WHERE id = 1 AND name = '张三';
DELETE FROM user WHERE id = 1 OR id = 2;

4.3 DQL - 数据查询

4.3.1 基本查询
复制代码
-- 查询所有字段
SELECT * FROM user;

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

-- 条件查询
SELECT * FROM user WHERE age > 18;

-- 多条件查询
SELECT * FROM user 
WHERE age > 18 AND name LIKE '张%';

SELECT * FROM user 
WHERE age > 20 OR age < 15;
4.3.2 高级查询
复制代码
-- LIKE 模糊查询
SELECT * FROM user WHERE name LIKE '张%';  -- 以张开头的
SELECT * FROM user WHERE name LIKE '%三';  -- 以三结尾的
SELECT * FROM user WHERE name LIKE '%三%'; -- 包含三的

-- 排序
SELECT * FROM user ORDER BY age;           -- 升序
SELECT * FROM user ORDER BY age DESC;      -- 降序

-- 限制结果数量
SELECT * FROM user LIMIT 5;                -- 前5条
SELECT * FROM user LIMIT 5 OFFSET 10;      -- 跳过10条取5条

-- 分组
SELECT age, COUNT(*) FROM user 
GROUP BY age 
HAVING COUNT(*) > 1;

4.4 日期时间处理

复制代码
-- 创建带日期时间的表
CREATE TABLE user1(
    id INTEGER,
    name CHAR(50),
    age INTEGER,
    dt DATETIME
);

-- 插入当前时间
INSERT INTO user1 VALUES 
(1, '张三', 23, datetime('now'));

-- 插入北京时间(东八区)
INSERT INTO user1 VALUES 
(2, '李四', 24, datetime('now', '+8 hours'));

五、数据导入导出

5.1 导出数据库

复制代码
sqlite3 mydb.db .dump > backup.sql

5.2 导入数据库

复制代码
sqlite3 newdb.db < backup.sql

5.3 安装可视化工具

复制代码
sudo apt-get install sqlitebrowser

六、SQLite3 C 语言编程接口

6.1 头文件和编译

复制代码
#include <sqlite3.h>

// 编译
gcc program.c -lsqlite3 -lpthread

6.2 编程框架

  1. 打开数据库

  2. 执行SQL操作

  3. 关闭数据库

6.3 核心API函数

6.3.1 打开和关闭数据库
复制代码
int sqlite3_open(const char *filename, sqlite3 **ppDb);
int sqlite3_close(sqlite3 *db);

示例

复制代码
sqlite3 *db;
int rc;

rc = sqlite3_open("test.db", &db);
if (rc) {
    fprintf(stderr, "无法打开数据库: %s\n", sqlite3_errmsg(db));
    return 1;
}

// ... 数据库操作 ...

sqlite3_close(db);
6.3.2 执行非查询语句(INSERT/UPDATE/DELETE)
复制代码
int sqlite3_exec(
    sqlite3 *db,               // 数据库句柄
    const char *sql,           // SQL语句
    sqlite3_callback callback, // 回调函数(查询时使用)
    void *data,                // 回调函数参数
    char **errmsg              // 错误信息
);

示例

复制代码
char *err_msg = 0;
char *sql = "INSERT INTO user VALUES(1, '张三', 20);";

int rc = sqlite3_exec(db, sql, 0, 0, &err_msg);
if (rc != SQLITE_OK) {
    fprintf(stderr, "SQL错误: %s\n", err_msg);
    sqlite3_free(err_msg);
}
6.3.3 执行查询语句
复制代码
int sqlite3_get_table(
    sqlite3 *db,           // 数据库句柄
    const char *sql,       // SQL查询语句
    char ***resultp,       // 结果集
    int *nrow,            // 行数
    int *ncol,            // 列数
    char **errmsg         // 错误信息
);

void sqlite3_free_table(char **result);

示例

复制代码
char *err_msg = 0;
char **results = NULL;
int rows, columns;

char *sql = "SELECT * FROM user;";
int rc = sqlite3_get_table(db, sql, &results, &rows, &columns, &err_msg);

if (rc == SQLITE_OK) {
    // 打印表头
    for (int i = 0; i < columns; i++) {
        printf("%s\t", results[i]);
    }
    printf("\n");
    
    // 打印数据
    for (int i = 1; i <= rows; i++) {
        for (int j = 0; j < columns; j++) {
            printf("%s\t", results[i * columns + j]);
        }
        printf("\n");
    }
}

sqlite3_free_table(results);
6.3.4 回调函数方式查询
复制代码
// 回调函数原型
typedef int (*sqlite3_callback)(
    void *data,      // sqlite3_exec 第4个参数
    int argc,        // 字段数
    char **argv,     // 字段值
    char **azColName // 字段名
);

示例

复制代码
int callback(void *data, int argc, char **argv, char **azColName) {
    for (int i = 0; i < argc; i++) {
        printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
    }
    printf("\n");
    return 0;
}

// 执行查询
char *sql = "SELECT * FROM user;";
int rc = sqlite3_exec(db, sql, callback, 0, &err_msg);

七、完整编程示例

7.1 学生信息管理系统

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

int main() {
    sqlite3 *db;
    char *err_msg = 0;
    int rc;
    
    // 1. 打开数据库
    rc = sqlite3_open("student.db", &db);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "无法打开数据库: %s\n", sqlite3_errmsg(db));
        return 1;
    }
    
    // 2. 创建学生表
    char *sql = "CREATE TABLE IF NOT EXISTS students("
                "id INTEGER PRIMARY KEY AUTOINCREMENT,"
                "name TEXT NOT NULL,"
                "age INTEGER,"
                "major TEXT,"
                "phone TEXT,"
                "gender TEXT,"
                "create_time DATETIME DEFAULT CURRENT_TIMESTAMP);";
    
    rc = sqlite3_exec(db, sql, 0, 0, &err_msg);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "创建表失败: %s\n", err_msg);
        sqlite3_free(err_msg);
    }
    
    // 3. 插入学生数据
    sql = "INSERT INTO students (name, age, major, phone, gender) VALUES"
          "('张三', 20, '电信', '1101010010', '男'),"
          "('李四', 22, '测控', '1201010011', '女'),"
          "('王五', 19, '计算机', '1301010012', '男');";
    
    rc = sqlite3_exec(db, sql, 0, 0, &err_msg);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "插入数据失败: %s\n", err_msg);
        sqlite3_free(err_msg);
    }
    
    // 4. 查询回调函数
    int print_callback(void *data, int argc, char **argv, char **azColName) {
        for (int i = 0; i < argc; i++) {
            printf("%-15s: %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
        }
        printf("----------------------------------------\n");
        return 0;
    }
    
    // 5. 查询所有学生
    printf("所有学生信息:\n");
    printf("========================================\n");
    sql = "SELECT * FROM students;";
    rc = sqlite3_exec(db, sql, print_callback, 0, &err_msg);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "查询失败: %s\n", err_msg);
        sqlite3_free(err_msg);
    }
    
    // 6. 修改数据
    sql = "UPDATE students SET age = 21 WHERE name = '张三';";
    rc = sqlite3_exec(db, sql, 0, 0, &err_msg);
    
    // 7. 删除数据
    sql = "DELETE FROM students WHERE age < 20;";
    rc = sqlite3_exec(db, sql, 0, 0, &err_msg);
    
    // 8. 关闭数据库
    sqlite3_close(db);
    
    printf("操作完成!\n");
    return 0;
}

7.2 编译和运行

复制代码
gcc student_system.c -o student_system -lsqlite3
./student_system

八、实用技巧

8.1 创建成绩表

复制代码
-- 学生表
CREATE TABLE stu_info(
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    name TEXT NOT NULL,
    age INTEGER,
    phone TEXT,
    email TEXT,
    qq TEXT
);

-- 成绩表
CREATE TABLE scores(
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    stu_id INTEGER,
    subject TEXT,
    score REAL,
    exam_date DATE,
    FOREIGN KEY (stu_id) REFERENCES stu_info(id)
);

8.2 复杂查询示例

复制代码
-- 查询成绩及学生信息
SELECT s.name, sc.subject, sc.score
FROM stu_info s
JOIN scores sc ON s.id = sc.stu_id
WHERE sc.score > 60
ORDER BY sc.score DESC;

-- 统计每个学生的平均分
SELECT s.name, AVG(sc.score) as avg_score
FROM stu_info s
JOIN scores sc ON s.id = sc.stu_id
GROUP BY s.id
HAVING avg_score > 70;

8.3 事务处理

复制代码
// 开始事务
sqlite3_exec(db, "BEGIN TRANSACTION", 0, 0, 0);

// 执行多个SQL操作
sqlite3_exec(db, "INSERT INTO ...", 0, 0, 0);
sqlite3_exec(db, "UPDATE ...", 0, 0, 0);

// 提交事务
sqlite3_exec(db, "COMMIT", 0, 0, 0);

// 出错时回滚
sqlite3_exec(db, "ROLLBACK", 0, 0, 0);

九、常见问题解决

  1. 数据库被锁:检查是否有其他进程正在使用数据库

  2. 中文乱码:确保使用UTF-8编码

  3. 内存泄漏 :确保释放 sqlite3_free()sqlite3_free_table()

  4. 并发访问:使用SQLite的WAL模式提高并发性能

十、最佳实践

  1. 始终检查返回值:每个SQLite API调用都应检查返回值

  2. 使用预处理语句 :对于频繁执行的SQL,使用 sqlite3_prepare_v2()

  3. 错误处理:妥善处理错误信息并释放资源

  4. 关闭连接:确保在所有路径上都关闭数据库连接

  5. 备份数据 :定期使用 .dump 命令备份数据库

相关推荐
cur1es8 小时前
【UDP的报文结构】
网络·网络协议·udp·md5
驭渊的小故事9 小时前
简单模板笔记
数据结构·笔记·算法
开开心心就好9 小时前
发票合并打印工具,多页布局设置实时预览
linux·运维·服务器·windows·pdf·harmonyos·1024程序员节
闲人编程9 小时前
使用FastAPI和WebSocket构建高性能实时聊天系统
websocket·网络协议·网络编程·fastapi·持久化·实时聊天·codecapsule
惊讶的猫9 小时前
OpenFeign(声明式HTTP客户端)
网络·网络协议·http·微服务·openfeign
css趣多多9 小时前
add组件增删改的表单处理
java·服务器·前端
予枫的编程笔记9 小时前
【Linux进阶篇】从基础到实战:grep高亮、sed流编辑、awk分析,全场景覆盖
linux·sed·grep·awk·shell编程·文本处理三剑客·管道命令
Sheep Shaun9 小时前
揭开Linux的隐藏约定:你的第一个文件描述符为什么是3?
linux·服务器·ubuntu·文件系统·缓冲区
devmoon9 小时前
在 Polkadot Runtime 中添加多个 Pallet 实例实战指南
java·开发语言·数据库·web3·区块链·波卡
Tfly__9 小时前
在PX4 gazebo仿真中加入Mid360(最新)
linux·人工智能·自动驾驶·ros·无人机·px4·mid360