SQLite的优雅设计

SQLite的优雅设计: 展示了即使是极其复杂的项目,也可以保持简单易用

将「单文件头文件库」的概念发挥到极致------同一个被称作 amalgamated source 的单文件,包含了将近 30 万行代码,但使用起来就像用一个简单的小库一样。


SQLite

SQLite 是一个实现 SQL 数据库引擎的库,从手机应用到浏览器、从桌面软件到服务器,几乎所有设备都在使用它。按使用量计算,它是世界上使用最广泛的数据库


安装与使用(零依赖)

1. 获取源码

访问 SQLite 下载页面,下载 amalgamated sources(合并后的源码包)。

bash 复制代码
wget https://www.sqlite.org/xxxxx.zip
unzip sqlite-autoconf-xxxxxxx.zip

下载的压缩包包含 4 个文件:

文件 说明
sqlite3.c 核心库文件,约 30 万行代码
sqlite3.h 头文件,约 1.4 万行代码
sqlite3ext.h 扩展头文件,约 700 行代码(用于编写插件)
shell.c 命令行工具实现,约 4 万行代码

2. 示例

c 复制代码
#include <stdio.h>
#include "sqlite3.h"

int main(int argc, char **argv) {
    sqlite3 *db;
    char *err_msg = 0;
    
    // 打开数据库连接
    int rc = sqlite3_open("test.db", &db);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        return 1;
    }
    
    // 执行 SQL 语句
    rc = sqlite3_exec(db, "CREATE TABLE Users (id INTEGER PRIMARY KEY, name TEXT)", 0, 0, &err_msg);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "SQL error: %s\n", err_msg);
        sqlite3_free(err_msg);
        sqlite3_close(db);
        return 1;
    }
    
    sqlite3_close(db);
    return 0;
}

整个核心使用流程只有三步:

  1. sqlite3_open() --- 打开数据库连接
  2. sqlite3_exec() --- 执行 SQL 查询
  3. sqlite3_close() --- 关闭连接

编译方式

方式一:静态编译

将 SQLite 直接编译进可执行文件:

bash 复制代码
gcc -o main main.c sqlite3.c -lpthread -ldl

编译参数说明:

  • -lpthread --- 线程支持
  • -ldl --- 动态链接支持
  • 编译时间稍长(SQLite 较大),但最终产物是单个可执行文件,部署简单

方式二:动态编译

先单独编译动态库,再链接:

bash 复制代码
# 编译动态库
gcc -shared -fPIC -o libsqlite3.so sqlite3.c

# 链接动态库
gcc -o main main.c -L. -lsqlite3

# 运行(需要指定库路径)
LD_LIBRARY_PATH=. ./main

使用 -L. 指定在当前目录查找库,避免链接到系统安装的 SQLite。


API 设计

核心 API 精简

SQLite 的 API 表面看起来只有 10 个核心函数,掌握这些就能完成 90% 的日常工作:

API 函数 用途
sqlite3_open() 打开/创建数据库
sqlite3_close() 关闭连接
sqlite3_exec() 执行 SQL 语句
sqlite3_prepare() 预处理语句
sqlite3_step() 执行预处理语句
sqlite3_finalize() 销毁预处理语句
sqlite3_bind_*() 绑定参数
sqlite3_column_*() 读取结果列
sqlite3_errmsg() 获取错误信息
sqlite3_close_v2() 改进版关闭函数

虽然 SQLite 实际上有 225+ 个 API ,但文档只展示你 90% 时间会用到的核心部分,让新手不会「知识淹没」。

API 版本管理

c 复制代码
sqlite3_prepare()        // 旧版,已废弃
sqlite3_prepare_v2()     // 当前推荐版本
sqlite3_prepare_v3()     // 最新版本

向后兼容性原则:旧 API 仍然可用,不破坏用户现有代码 Never break user space


库设计原则

1. 默认安装方式应该是「下载即用」

  • 下载压缩包
  • 解压
  • 包含头文件
  • 用普通编译器编译

任何语言、任何项目都不应该强制要求使用特定的构建系统 即使语言有 npm、pip、cargo 等包管理器,也应该保留「拖拽添加」的能力。这会促使开发者设计更轻量的依赖。

2. 文档要「漏斗导向成功」

不要一开始就把所有 API 堆在用户面前:

  • 先展示核心功能(10 个函数)
  • 进阶功能放在需要时再查阅
  • 让用户从「一无所知」到「能用」的时间最短

3. 尊重向后兼容性

  • 需要新接口时,命名 V2/V3 而不是废弃旧接口
  • 旧代码在新版本下仍能运行

相关:

Neovim 打开 30 万行文件同样流畅,现代编辑器的性能足以处理大文件

OpenSSL 同样采用 amalgamated source 方式

SQLite 用一个 30 万行的单文件 证明了:

  • 复杂性可以被封装
  • 简单性可以被保持
  • 向后兼容性是可以做到的
相关推荐
Access开发易登软件20 小时前
Access 用 VBA 操作 SQLite,不用装任何驱动
jvm·数据库·sqlite·vba·access·access开发
谷谷地图下载器20 小时前
全球、台湾省的无水印·街景数据(离线数据),专为可视化项目定制,支持国产化
javascript·c++·3d·arcgis·sqlite
彭祥.1 天前
基于SQLite与face_recognition的人脸库管理
数据库·计算机视觉·sqlite
搜佛说1 天前
sfsDb 和 SQLite、InfluxDB “硬碰硬”的底层性能与技术架构对比
jvm·架构·sqlite
星越华夏1 天前
SQLite数据库优化实战技巧案例
数据库·sqlite
abcy0712132 天前
python在models定义了一个对象,接口调用时报错对象不存在models.xx.DoesNotExist
数据库·sqlite
ggabb2 天前
形制与意蕴的殊途:中英诗歌的优劣差异探析
sqlite
Dxy12393102162 天前
Django 三种 ENGINE 的区别
python·django·sqlite
abcy0712132 天前
django聚合函数
数据库·sqlite