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

相关推荐
Hello.Reader2 小时前
Flink OLAP Quickstart把 Flink 当成“秒级交互查询”的 OLAP 服务来用
数据库·sql·flink
你要飞2 小时前
Part 1 行列式
笔记·线性代数·考研
chenyuhao20244 小时前
Linux网络编程:传输层协议UDP
linux·服务器·网络·后端·udp
小鹏linux4 小时前
【linux】进程与服务管理命令 - batch
linux·运维·服务器
じ☆冷颜〃7 小时前
分布式系统中网络技术的演进与异构融合架构(HFNA)
笔记·python·物联网·设计模式·架构·云计算
米羊1218 小时前
fastjson (3修复)
网络·网络协议·安全
人工智能训练10 小时前
OpenEnler等Linux系统中安装git工具的方法
linux·运维·服务器·git·vscode·python·ubuntu
点云SLAM10 小时前
BOOS库中Graph模块boost::edge_reverse_t和boost::vertex_color_t解读
数据库·edge·图论·bfs·dfs/拓扑排序·boost库、
尽兴-10 小时前
《深入剖析:全面理解 MySQL 的架构设计》
数据库·mysql·数据库架构设计·理解mysql架构