一、數據庫基礎概念
1.1 數據庫分類
根據規模和應用場景,數據庫可分為以下幾類:
- 大型數據庫:Oracle(適用于企業級高并發、大容量場景)
- 中型數據庫:MySQL、MSSQL(適用于中小型系統、Web 應用)
- 小型數據庫:SQLite、DB2(適用于嵌入式設備、輕量應用)
1.2 常用核心名詞
縮寫 | 全稱 | 核心作用 |
---|---|---|
DB | Database(數據庫) | 用于數據的存儲、查詢和更新,是數據的集合 |
DBMS | Database Management System(數據庫管理系統) | 操作和管理數據庫的軟件,如 SQLite、MySQL |
MIS | Management Information System(管理信息系統) | 基于數據庫的企業管理系統,如 ERP、CRM |
OA | Office Automation(辦公自動化) | 基于數據庫的協同辦公系統,如考勤、審批 |
1.3 關系型數據庫與 SQL 分類
關系型數據庫基于表結構存儲數據,通過SQL(Structured Query Language,結構化查詢語言)?操作數據,SQL 按功能分為三類:
- DDL(數據定義語言):用于定義數據庫結構,如建表、刪表
- DML(數據操作語言):用于修改數據,如新增、更新、刪除數據
- DQL(數據查詢語言):用于查詢數據,如條件查詢、排序查詢
二、SQLite 核心特性
SQLite 是輕量級嵌入式數據庫,無需獨立服務器,核心特點如下:
- 開源免費:基于 C 語言開發,源代碼完全開放
- 極致輕量:核心代碼僅約 1 萬行,編譯后體積小于 10MB
- 無需安裝:綠色軟件,解壓即可使用,無復雜配置
- 文件存儲:整個數據庫存儲在單一文件中,便于移動和備份
- 容量充足:最大支持 2TB 數據存儲,滿足中小型應用需求
- 跨平臺兼容:支持 Windows、Linux、macOS 等主流操作系統
三、SQLite 安裝與基本使用
3.1 安裝方法(Ubuntu/Debian 系統)
# 安裝SQLite命令行工具
sudo apt-get install sqlite3
# 安裝開發庫(含頭文件和靜態庫,用于C語言開發)
sudo apt-get install libsqlite3-dev
驗證安裝
# 查看SQLite版本
sqlite3 --version
# 查看幫助信息
sqlite3 --help
編譯 C 程序
# 編譯時需鏈接SQLite庫和線程庫
gcc test.c -lsqlite3 -lpthread -o test
3.2 基本使用(命令行)
1. 啟動與退出
# 打開或創建名為test.db的數據庫文件(不存在則自動創建)
sqlite3 test.db# 退出SQLite命令行(兩種方式)
.q 或 .exit
- 成功啟動后顯示?
sqlite>
?提示符 - 若出現?
...>
?提示符,說明命令未結束,需輸入?;
?結束
2. 創建數據庫
# 方法1:先創建空文件,再打開
touch test.db
sqlite3 test.db# 方法2:直接通過sqlite3命令創建并打開(推薦)
sqlite3 test.db
3.3 系統維護命令(以.
開頭)
命令 | 功能描述 |
---|---|
.database | 列出當前數據庫及關聯文件路徑 |
.tables | 列出當前數據庫中的所有表 |
.schema [表名] | 顯示指定表的結構(CREATE 語句),無表名則顯示所有表 |
.dump [表名] | 導出數據庫或指定表的 SQL 腳本 |
.headers on/off | 開啟 / 關閉查詢結果的列標題顯示 |
.exit | 退出 SQLite 程序 |
3.4 數據庫導入與導出
導出數據庫(備份)
# 將test.db數據庫導出為SQL腳本backup.sql
sqlite3 test.db .dump > backup.sql
導入數據庫(恢復)
# 將backup.sql腳本導入到new.db數據庫(new.db不存在則創建)
sqlite3 new.db < backup.sql
四、SQL 基本語法
4.1 DDL(數據定義語言)
1. 創建表
-- 方式1:默認字段類型為TEXT
CREATE TABLE user(id, name, age);-- 方式2:指定字段類型(推薦)
CREATE TABLE user(id INT, -- 整數類型name TEXT, -- 文本類型age INT, -- 整數類型dt DATETIME -- 時間類型
);
- SQLite 支持的數據類型:
INT
(整數)、TEXT
(文本)、REAL
(浮點數)、BLOB
(二進制) - 若不指定類型,默認按
TEXT
處理
2. 刪除表
-- 刪除名為user的表(謹慎操作,數據不可恢復)
DROP TABLE user;
4.2 DML(數據操作語言)
1. 插入數據
-- 插入指定字段的數據(未指定字段值為NULL)
INSERT INTO user(id, age) VALUES(1, 10);-- 插入完整記錄(需與表字段順序一致)
INSERT INTO user VALUES(3, "wang", 11, datetime('now', '+8 hours'));-- 只插入部分字段(其余字段為NULL)
INSERT INTO user(age) VALUES(12);
datetime('now', '+8 hours')
:獲取當前東八區時間
2. 更新數據
-- 單條件更新:修改name為'li'的記錄的id為1
UPDATE user SET id = 1 WHERE name = 'li';-- 多條件更新(AND):同時滿足兩個條件
UPDATE user SET id = 1 WHERE name = "li" AND passwd = "123";-- 多條件更新(OR):滿足任一條件
UPDATE user SET id = 2 WHERE name = "li" OR name = "zhao";
3. 刪除數據
-- 刪除表中所有數據(謹慎操作,無條件刪除)
DELETE FROM user;-- 單條件刪除:刪除id為1的記錄
DELETE FROM user WHERE id = 1;-- 多條件刪除(AND/OR)
DELETE FROM user WHERE id = 1 AND name = "zhang";
DELETE FROM user WHERE id = 1 OR id = 2;
4.3 DQL(數據查詢語言)
1. 基本查詢
-- 查詢表中所有字段和數據
SELECT * FROM user;-- 查詢指定字段
SELECT id FROM user;
SELECT id, name FROM user;
2. 條件查詢
-- 邏輯條件查詢(NOT):查詢age不小于30的記錄
SELECT * FROM user WHERE NOT age < 30;-- 模糊查詢(LIKE):%匹配0-任意字符,_匹配1個字符
SELECT * FROM user WHERE name LIKE '張%'; -- 匹配姓張的所有記錄
SELECT * FROM user WHERE name LIKE '張_'; -- 匹配姓張且名字為2個字的記錄-- 排序查詢(ORDER BY):ASC升序(默認),DESC降序
SELECT * FROM user ORDER BY id; -- 按id升序
SELECT * FROM user ORDER BY id DESC; -- 按id降序-- 限制結果數量(LIMIT):只返回前2條記錄
SELECT * FROM user LIMIT 2;-- 組合查詢:條件+排序+限制
SELECT * FROM user
WHERE age > 20 OR age < 50
ORDER BY age DESC
LIMIT 2;
4.4 高級特性:自動增長列
SQLite 通過INTEGER PRIMARY KEY
實現自動增長,無需AUTOINCREMENT
:
-- 創建含自動增長列的表
CREATE TABLE user3(id INTEGER PRIMARY KEY ASC, -- ASC表示升序增長(默認)name TEXT,age INT,dt DATETIME
);-- 插入數據:id傳入NULL觸發自增(首條記錄id=1,后續自動+1)
INSERT INTO user3 VALUES(NULL, '李四', 23, datetime('now'));
五、SQLite C 語言接口
5.1 開發環境準備
- 頭文件:
#include <sqlite3.h>
- 編譯命令:
gcc test.c -lsqlite3 -lpthread -o test
5.2 核心 API 函數
1. 打開數據庫:sqlite3_open
int sqlite3_open(const char *path, // 數據庫文件路徑(如"./test.db")sqlite3 **db // 數據庫連接句柄的指針(輸出參數)
);
- 功能:打開指定路徑的數據庫文件,不存在則創建
- 返回值:成功返回
SQLITE_OK
(0),失敗返回非 0 錯誤碼 - 錯誤處理:通過
sqlite3_errmsg(db)
獲取錯誤信息
2. 關閉數據庫:sqlite3_close
int sqlite3_close(sqlite3 *db); // db:數據庫連接句柄
- 功能:關閉數據庫連接
- 返回值:成功返回
SQLITE_OK
,失敗返回錯誤碼 - 注意:關閉前需確保所有 SQL 操作已完成
3. 執行 SQL 語句:sqlite3_exec
int sqlite3_exec(sqlite3 *db, // 數據庫連接句柄const char *sql, // 要執行的SQL語句int (*callback)(void*,int,char**,char**), // 回調函數(處理查詢結果)void *arg, // 傳遞給回調函數的參數char **errmsg // 錯誤信息指針(輸出參數)
);
- 功能:執行 SQL 語句(INSERT/UPDATE/DELETE/SELECT 等)
- 回調函數:僅 SELECT 查詢時需要,用于逐行處理結果;非查詢語句可設為
NULL
- 錯誤處理:錯誤信息需通過
sqlite3_free(errmsg)
釋放內存
5.3 回調函數定義
回調函數用于處理sqlite3_exec
執行 SELECT 后的查詢結果:
// 回調函數:逐行處理查詢結果
static int callback(void *NotUsed, // 用戶自定義參數(由sqlite3_exec的arg傳入)int argc, // 結果列數char **argv, // 結果數據數組(argv[i]為第i列的值,NULL表示空值)char **azColName // 列名數組(azColName[i]為第i列的列名)
) {int i;// 遍歷列數據,打印列名和對應值for (i = 0; i < argc; i++) {printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");}printf("\n"); // 每行數據后換行return 0; // 返回0表示繼續處理下一行,非0則中斷
}
5.4 完整示例代碼
示例 1:控制臺輸出查詢結果
#include <stdio.h>
#include <sqlite3.h>// 回調函數:處理并打印查詢結果
int show(void* arg, int col, char** result, char** title) {static int flag = 0; // 標記是否首次調用(僅打印一次列名)int i = 0;// 首次調用:打印列名if (0 == flag) {flag = 1;for (i = 0; i < col; i++) {printf("%s\t", title[i]);}}// 打印當前行數據printf("\n");for (i = 0; i < col; i++) {printf("%s\t", result[i] ? result[i] : "NULL");}return 0;
}int main(int argc, char** argv) {sqlite3* db = NULL; // 數據庫連接句柄char* errmsg = NULL; // 錯誤信息指針int ret;// 1. 打開數據庫ret = sqlite3_open("./test.db", &db);if (SQLITE_OK != ret) {fprintf(stderr, "打開數據庫失敗:%s\n", sqlite3_errstr(ret));sqlite3_close(db);return 1;}// 2. 執行查詢SQLchar sql_cmd[] = "SELECT * FROM user;";ret = sqlite3_exec(db, sql_cmd, show, NULL, &errmsg);if (SQLITE_OK != ret) {fprintf(stderr, "執行SQL失敗:%s(SQL:%s)\n", errmsg, sql_cmd);sqlite3_free(errmsg); // 釋放錯誤信息內存sqlite3_close(db);return 1;}// 3. 關閉數據庫sqlite3_close(db);return 0;
}
示例 2:查詢結果寫入文件
#include <stdio.h>
#include <sqlite3.h>// 回調函數:將查詢結果寫入文件
int show(void* arg, int col, char** result, char** title) {FILE* fp = (FILE*)arg; // 傳入的文件指針static int flag = 0; // 標記是否首次調用int i = 0;// 首次調用:寫入列名if (0 == flag) {flag = 1;for (i = 0; i < col; i++) {fprintf(fp, "%s\t", title[i]);}}// 寫入當前行數據fprintf(fp, "\n");for (i = 0; i < col; i++) {fprintf(fp, "%s\t", result[i] ? result[i] : "NULL");}return 0;
}int main(int argc, char** argv) {sqlite3* db = NULL;char* errmsg = NULL;int ret;// 1. 打開數據庫ret = sqlite3_open("./test.db", &db);if (SQLITE_OK != ret) {fprintf(stderr, "打開數據庫失敗:%s\n", sqlite3_errstr(ret));sqlite3_close(db);return 1;}// 2. 打開文件(用于寫入結果)FILE* fp = fopen("result.txt", "w");if (NULL == fp) {perror("打開文件失敗");sqlite3_close(db);return 1;}// 3. 執行查詢SQL,將文件指針傳入回調函數char sql_cmd[] = "SELECT * FROM user;";ret = sqlite3_exec(db, sql_cmd, show, fp, &errmsg);if (SQLITE_OK != ret) {fprintf(stderr, "執行SQL失敗:%s(SQL:%s)\n", errmsg, sql_cmd);sqlite3_free(errmsg);sqlite3_close(db);fclose(fp);return 1;}// 4. 關閉資源fclose(fp);sqlite3_close(db);return 0;
}
5.5 運行示例
# 1. 編譯代碼
gcc query_to_file.c -lsqlite3 -lpthread -o query_to_file# 2. 執行程序(前提:test.db已存在且含user表)
./query_to_file# 3. 查看結果文件
cat result.txt
理想輸出(result.txt):
id name age dt
1 張三 23 2024-05-20 15:30:45
2 李四 25 2024-05-20 15:31:20