在嵌入式数据存储方案里,SQLite与Derby(Java DB)经常被拿来比较。前者是诞生于2000年的C语言库,后者是纯Java实现、曾由Apache维护并随Oracle JDK分发的关系型数据库。两者都主打零配置、单文件或轻量存储,但底层设计与适用场景差异明显。本文从架构模型、SQL能力、并发机制与工程落地几个角度展开分析,帮助你在具体项目中做判断。

架构形态与运行环境的根本差异
SQLite并不是一个独立的数据库服务,它只是一组C函数编译进你的程序进程。应用程序通过调用sqlite3_open之类的接口直接读写磁盘上的单个文件,没有网络协议,也没有后台守护进程。这种进程内架构让它几乎能为任何语言所用:Python用内置sqlite3模块,Java通过JDBC驱动本质也是JNI或纯Java封装的本地库调用,C#有System.Data.SQLite。正因如此,SQLite广泛存在于手机APP、浏览器、命令行工具中,体积常常只有几百KB。
Derby则完全不同,它是100% Java编写的数据库引擎。以内嵌模式运行时,Derby的引擎类加载进当前JVM,和你的Java应用共享同一个进程与内存空间,数据存为一组目录文件而非单一文件。因为它依赖JRE,所以非Java项目硬要用的话,必须额外携带十几MB以上的运行环境。Derby还支持网络模式,通过启动NetworkServerControl变成独立数据库服务器,此时多个JVM经TCP/IP连接访问,这一点SQLite原生并不提供。
从部署形态看,如果你的系统本身就用Java开发,Derby内嵌几乎不增加新依赖;但若系统是Go或C++写的,为了Derby去捆绑JRE显然不合理。反过来,SQLite的跨语言特性让它成为通用型嵌入式存储首选。下面这段Java代码展示了Derby内嵌模式最基本的建库与连库方式:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class DerbyEmbed {
public static void main(String[] args) throws Exception {
// 内嵌模式,数据库以目录形式创建在demoDB文件夹
String url = "jdbc:derby:demoDB;create=true";
Connection conn = DriverManager.getConnection(url);
Statement st = conn.createStatement();
st.execute("CREATE TABLE t(id INT PRIMARY KEY, name VARCHAR(20))");
st.close();
conn.close();
}
}
SQL标准兼容与数据类型处理能力
Derby在SQL标准上走得比SQLite远得多。它支持存储过程、触发器、游标、复杂连接以及大部分SQL/SQL-99语法,类型系统涵盖DECIMAL精确数、CLOB/BLOB大对象、DATE/TIME/TIMESTAMP等。对于从Oracle或PostgreSQL迁下来的Java系统,Derby能较平滑承接原有表结构与查询写法。SQLite则刻意保持精简,早期甚至不支持右连接与完整的ALTER TABLE,类型系统采用动态类型亲和(type affinity),允许同一列混存整数与文本。
这种差异带来实际开发中的坑。例如SQLite执行SELECT '1' + 2会做隐式转换得到3,而Derby严格按类型检查会直接报错。再比如外键约束,SQLite需要编译时开启且建表用PRAGMA开启,Derby默认就支持引用完整性。若你的业务依赖严谨的模式约束与标准SQL,Derby更省心;若只是存配置、日志、缓存,SQLite的灵活反而降低样板代码。
下面的SQLite示例展示其动态类型特点,同一列可写入不同形态数据而引擎不报错:
-- SQLite中创建一张表并插入混合类型
CREATE TABLE sample(col);
INSERT INTO sample VALUES (10);
INSERT INTO sample VALUES ('hello');
INSERT INTO sample VALUES (3.14);
SELECT typeof(col) FROM sample;
从维护角度看,Derby因为贴近标准,团队招人交接成本低;SQLite则要求开发者理解其亲和规则,否则容易出现隐式转换导致的查询偏差。选型时应当把团队SQL习惯纳入考量。
并发控制、锁机制与性能特征
并发写入是嵌入式数据库的共同难点。SQLite采用文件级锁:写操作会对整个数据库文件加写锁,同一时刻仅一个写者,读者可被多事务并发但写时阻塞读。它通过WAL(Write-Ahead Logging)模式缓解读写冲突,让读不阻塞写、写不阻塞读,但依旧单写。Derby内嵌模式使用表级锁与行级锁结合,配合事务隔离级别,能支持多个连接在同一库内做更细粒度并发,不过所有连接必须位于同一JVM。
性能方面,SQLite读路径极短,单条查询延迟常低于Derby,因为它免去了JVM堆内对象映射与JDBC层开销。批量写入开启事务后二者差距缩小,但Derby的GC压力在大数据量时更明显。网络模式下Derby脱离进程限制,可横向服务多应用,却也失去嵌入式低延迟优势,此时它更像一个迷你版中心库而非边缘库。
下面SQLite开启WAL并做批量插入的示意,体现其事务包裹降低锁竞争的做法:
PRAGMA journal_mode=WAL; BEGIN TRANSACTION; INSERT INTO log VALUES (1, 'a'); INSERT INTO log VALUES (2, 'b'); COMMIT;
如果你的场景是单机工具、移动端或边缘设备,写冲突少、追求极小体积与启动快,SQLite胜出。若是Java服务端内部需要标准关系库且不愿引外部中间件,Derby内嵌提供完整SQL与较好并发,是合理折中。理解锁边界,才能预估系统峰值时的阻塞风险。
工程集成与生态工具现状
SQLite官方提供命令行shell、可视化工具如DB Browser,语言绑定覆盖几乎所有平台,甚至浏览器里的WebSQL也曾基于它。它的备份只需复制文件,但运行期复制需先停写或借备份API。Derby随JDK曾自带,现在独立下载,配套有ij命令行与Eclipse插件,备份常通过导出SQL或文件系统快照完成。因为纯Java,Derby易被打进Fat Jar随应用分发,适合云原生镜像里免去外部数据库依赖。
从长期维护看,SQLite由专门基金持续投入,版本迭代稳定;Derby自Apache毕业后活跃度下降,新项目引用前需评估社区支撑。若系统未来可能从嵌入式演变为客户端加中心库混合架构,Derby网络模式提供平滑升级路径,SQLite则需引入服务端如LiteStream或自行同步。综合来说,语言栈与部署边界是第一位,其次才是功能深浅与并发量。
SQLiteDerbyembedded_database修改时间:2026-08-16 13:08:36