复习——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 命令备份数据库

相关推荐
大树889 小时前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠9 小时前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
bush410 小时前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行52010 小时前
Linux 11 动态监控指令top
linux
小宇宙Zz10 小时前
Maven依赖冲突
java·服务器·maven
麦聪聊数据11 小时前
数据服务化时代:企业数据能力输出的核心路径
数据库
不会C语言的男孩11 小时前
Linux 系统编程 · 第 8 章:进程基础
linux·c语言
shushangyun_11 小时前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化
闪闪发亮的小星星11 小时前
高斯光以及高斯光公式解释
笔记
古城小栈11 小时前
Unix 与 Linux 异同小叙
linux·服务器·unix