一、数据库基础认知
1. 什么是数据库?
数据库是专门用于高效管理大批量数据的软件,核心价值在于结构化存储、快速检索和便捷修改数据,避免了纯文本文件管理数据的混乱与低效。
2. 数据库的核心分类
表格
| 类型 | 特点 | 代表产品 |
|---|---|---|
| 关系型数据库 | 基于表结构,支持 SQL,数据关联性强 | Oracle、MySQL、SQLServer、SQLite |
| 非关系型数据库 | 无固定表结构,灵活度高,适合海量非结构化数据 | Redis(注:原文 Redit 为笔误)、MongoDB |
二、SQLite 数据库快速上手
SQLite 是轻量级关系型数据库,无需安装服务端,单文件即可运行,适合嵌入式开发、小型应用和学习场景。
1. SQLite 安装(Linux 环境)
确保虚拟机网络连通、apt-get 工具配置正常后,执行以下命令:
bash
运行
# 安装SQLite3客户端
sudo apt-get install sqlite3
# 安装开发库(C/C++编程必备)
sudo apt-get install libsqlite3-dev
# 可选:安装可视化管理工具
sudo apt-get install sqlitebrowser
# 可选:Windows/Mac推荐可视化工具Navicat
2. 启动与退出 SQLite
bash
运行
# 启动SQLite(临时内存数据库)
sqlite3
# 启动并关联本地数据库文件(持久化)
sqlite3 test.db
# 退出SQLite
.quit
启动后会看到如下提示,代表成功:
plaintext
SQLite version 3.22.0 2018-01-22 18:45:57
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite>
3. SQLite 常用交互命令
表格
| 命令 | 功能 | 示例 |
|---|---|---|
.databases |
查看当前数据库信息 | .databases |
.tables |
查看所有表名 | .tables |
.headers ON/OFF |
开启 / 关闭查询结果的列名显示 | .headers ON |
.mode MODE |
设置数据显示格式 | .mode column(列对齐显示) |
.schema [表名] |
查看表的创建语句 | .schema student |
.quit |
退出 SQLite | .quit |
三、核心 SQL 语句实战
SQL 是操作所有关系型数据库的通用语言,以下基于student表演示核心语法。
1. 表操作
创建表(CREATE TABLE)
sql
-- 语法:CREATE TABLE 表名 (列名1 类型, 列名2 类型, ...);
-- 示例:创建学生表,学号为主键(唯一标识)
CREATE TABLE student (
学号 INTEGER PRIMARY KEY,
姓名 TEXT,
性别 TEXT,
年龄 INTEGER,
成绩 INTEGER
);
删除表(DROP TABLE)
sql
-- 语法:DROP TABLE 表名;
DROP TABLE student;
2. 数据操作(增删改)
插入数据(INSERT INTO)
sql
-- 方式1:插入所有列
INSERT INTO student VALUES (1002, "李四", "女", 13, 80);
-- 方式2:指定列插入(未指定列赋默认值)
INSERT INTO student (学号,姓名,性别) VALUES (1009, "熊大", "男");
删除数据(DELETE FROM)
sql
-- 语法:DELETE FROM 表名 WHERE 条件;
DELETE FROM student WHERE 姓名 = "赵五";
修改数据(UPDATE)
sql
-- 语法:UPDATE 表名 SET 列1=值1, 列2=值2 WHERE 条件;
UPDATE student SET 年龄=16,成绩=85 WHERE 姓名="熊大";
3. 数据查询(SELECT)
查询是 SQL 最核心的操作,支持条件、模糊、排序、多表联合等复杂逻辑。
基础查询
sql
-- 查询所有列
SELECT * FROM student;
-- 查询指定列
SELECT 学号,成绩 FROM student;
-- 条件查询(AND/OR)
SELECT 姓名 FROM student WHERE 成绩<60 AND 性别="男";
-- 模糊查询(%匹配任意字符)
SELECT 姓名 FROM student WHERE 姓名 LIKE "%田%";
排序查询(ORDER BY)
sql
-- 语法:ORDER BY 列名 ASC(升序,默认)/DESC(降序)
-- 成绩>60的学生按成绩降序排列
SELECT 学号,姓名 FROM student WHERE 成绩 > 60 ORDER BY 成绩 DESC;
多表联合查询
假设有学生信息、学生课程、学生成绩三张表,演示常用联合查询:
sql
-- 1. 交叉连接(笛卡尔积,所有组合)
SELECT 学生信息.姓名 as 姓名, 学生课程.名称 as 课程 FROM 学生信息 CROSS JOIN 学生课程;
-- 2. 内连接(只返回匹配的数据)
SELECT 学生信息.姓名 as 姓名, 学生成绩.成绩 as 成绩
FROM 学生信息 INNER JOIN 学生成绩
ON 学生信息.学号 = 学生成绩.学号;
-- 3. 左外连接(返回左表所有数据,右表无匹配则为NULL)
SELECT 学生信息.姓名 as 姓名, 学生成绩.成绩 as 成绩
FROM 学生信息 LEFT OUTER JOIN 学生成绩
ON 学生信息.学号 = 学生成绩.学号;
-- 4. 三表联合查询(查询学生-课程-成绩)
SELECT 学生信息.姓名 as 姓名, 学生课程.名称 as 课程, 学生成绩.成绩 as 成绩
FROM 学生信息 LEFT OUTER JOIN 学生成绩 ON 学生信息.学号 = 学生成绩.学号
LEFT OUTER JOIN 学生课程 ON 学生成绩.课程编号 = 学生课程.编号
WHERE 成绩 > 60
ORDER BY 成绩 DESC;
四、SQLite C 语言编程(核心 API)
在代码中操作 SQLite,核心依赖以下 5 个 API,以下是关键说明和使用逻辑。
1. 核心 API 详解
表格
| API | 功能 | 关键参数 / 返回值 |
|---|---|---|
sqlite3_open |
打开数据库,获取操作句柄 | 参数:数据库路径、句柄指针;返回:成功 = SQLITE_OK |
sqlite3_errmsg |
获取错误信息 | 参数:数据库句柄;返回:错误描述字符串 |
sqlite3_exec |
执行 SQL 语句 | 参数:句柄、SQL 语句、回调函数(查询用)、错误信息指针;返回:成功 = SQLITE_OK |
sqlite3_free |
释放内存 | 参数:需要释放的内存地址 |
sqlite3_close |
关闭数据库句柄 | 参数:数据库句柄 |
关键 API 原型
c
运行
// 打开数据库
int sqlite3_open(const char *filename, sqlite3 **ppDb);
// 获取错误信息
const char *sqlite3_errmsg(sqlite3*);
// 执行SQL语句
int sqlite3_exec(
sqlite3*, // 打开的数据库句柄
const char *sql, // 要执行的SQL语句
int (*callback)(void*,int,char**,char**), // 查询回调函数
void *, // 传给回调函数的参数
char **errmsg // 错误信息存储地址
);
// 释放内存
void sqlite3_free(void*);
// 关闭数据库
int sqlite3_close(sqlite3*);
2. 编程核心逻辑
c
运行
#include <sqlite3.h>
#include <stdio.h>
// 查询回调函数(处理SELECT结果)
int callback(void *data, int argc, char **argv, char **azColName) {
// argc:列数;argv:列值;azColName:列名
for(int i=0; i<argc; i++) {
printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
}
return 0;
}
int main() {
sqlite3 *db;
char *err_msg = NULL;
int rc;
// 1. 打开数据库
rc = sqlite3_open("test.db", &db);
if (rc != SQLITE_OK) {
printf("打开失败:%s\n", sqlite3_errmsg(db));
sqlite3_close(db);
return -1;
}
// 2. 执行SQL语句(示例:查询学生表)
char *sql = "SELECT * FROM student;";
rc = sqlite3_exec(db, sql, callback, NULL, &err_msg);
if (rc != SQLITE_OK) {
printf("执行失败:%s\n", err_msg);
sqlite3_free(err_msg);
}
// 3. 关闭数据库
sqlite3_close(db);
return 0;
}
编译运行
bash
运行
# 编译:链接sqlite3库
gcc test.c -o test -lsqlite3
# 运行
./test
五、实战案例:单词查询系统(作业实现)
1. 需求
- 把单词文件(单词 含义)导入 SQLite 数据库;
- 终端输入单词,查询含义,无匹配则提示错误。
2. 完整代码
c
运行
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sqlite3.h>
// 查询回调函数
int query_callback(void *data, int argc, char **argv, char **azColName) {
printf("单词含义:%s\n", argv[0]);
return 0;
}
int main() {
sqlite3 *db;
char *err_msg = NULL;
int rc;
// 1. 打开/创建数据库
rc = sqlite3_open("words.db", &db);
if (rc != SQLITE_OK) {
printf("数据库打开失败:%s\n", sqlite3_errmsg(db));
sqlite3_close(db);
return -1;
}
// 2. 创建单词表
char *create_sql = "CREATE TABLE IF NOT EXISTS words (word TEXT PRIMARY KEY, meaning TEXT);";
rc = sqlite3_exec(db, create_sql, NULL, NULL, &err_msg);
if (rc != SQLITE_OK) {
printf("创建表失败:%s\n", err_msg);
sqlite3_free(err_msg);
sqlite3_close(db);
return -1;
}
// 3. 从文件导入单词(假设words.txt格式:单词 含义)
FILE *fp = fopen("words.txt", "r");
if (!fp) {
perror("打开单词文件失败");
sqlite3_close(db);
return -1;
}
char word[100], meaning[200], insert_sql[300];
while (fscanf(fp, "%s %[^\n]", word, meaning) != EOF) {
sprintf(insert_sql, "INSERT OR REPLACE INTO words VALUES ('%s', '%s');", word, meaning);
sqlite3_exec(db, insert_sql, NULL, NULL, &err_msg);
if (err_msg) {
printf("插入失败:%s\n", err_msg);
sqlite3_free(err_msg);
}
}
fclose(fp);
// 4. 终端查询
char input[100], query_sql[200];
while (1) {
printf("\n请输入要查询的单词(输入exit退出):");
scanf("%s", input);
if (strcmp(input, "exit") == 0) break;
// 拼接查询SQL
sprintf(query_sql, "SELECT meaning FROM words WHERE word = '%s';", input);
rc = sqlite3_exec(db, query_sql, query_callback, NULL, &err_msg);
// 无匹配结果
if (rc == SQLITE_OK && sqlite3_changes(db) == 0) {
printf("输入有误:未找到该单词!");
}
if (err_msg) {
printf("查询失败:%s\n", err_msg);
sqlite3_free(err_msg);
}
}
// 5. 关闭数据库
sqlite3_close(db);
return 0;
}
3. 运行步骤
- 创建
words.txt文件:
plaintext
apple 苹果
banana 香蕉
orange 橙子
grape 葡萄
- 编译:
gcc word_query.c -o word_query -lsqlite3 - 运行:
./word_query - 交互示例:
plaintext
请输入要查询的单词(输入exit退出):apple
单词含义:苹果
请输入要查询的单词(输入exit退出):test
输入有误:未找到该单词!
请输入要查询的单词(输入exit退出):exit
六、总结
核心知识点回顾
- SQLite 基础:轻量级无服务端数据库,通过 apt 安装,核心交互命令(.tables/.schema 等)用于快速操作;
- SQL 核心语法:CREATE/DROP 管理表,INSERT/DELETE/UPDATE 操作数据,SELECT 支持条件、排序、多表联合查询;
- C 语言编程 :核心依赖
sqlite3_open/sqlite3_exec/sqlite3_close,查询结果通过回调函数处理,需注意内存释放和错误处理。