JavaDB 是一个 基于 Java 实现的简单数据库,原理参考自 MySQL。
- 事务:设计事务状态管理模块,支持事务状态的实时查询,遵循 ACID 原则。
- 数据:使用引用计数缓存管理数据,在回收时进行刷盘操作,确保系统的效率和稳定。
- 日志:引入数据库日志管理机制,通过日志保障数据一致性,实现故障恢复功能。
- 版本:基于两阶段锁和 MVCC 实现事务的读提交和可重复读隔离级别,支持死锁检测。
- 索引:采用 B+ 树作为索引结构,支持高效的索引查找。
- 表:构建表管理器,负责管理表结构和字段信息,实现 SQL 语句的执行功能。
- JDK 8
- IDEA 2024.1
JavaDB 分为前端和后端,通过 Socket 进行交互,支持多个客户端同时通过 Socket 连接到服务器,执行 SQL 查询并返回结果。
前端(即客户端)的主要功能是读取用户输入,将其发送给后端执行,并输出后端返回的结果,然后等待下一次输入。 客户端以 Shell 命令行的形式存在,在命令行中接收用户的输入,通过 Socket 发送给服务端,并接收服务端返回的响应。 由于 Socket 是阻塞式 I/O,因此客户端在等待服务端返回数据时会处于阻塞状态。
服务端启动后,通过 ServerSocket
监听指定端口。当有客户端发起 Socket 连接时,服务端会将该连接交由新创建的线程处理。
为了高效管理这些线程,使用了线程池技术。每个处理线程负责循环接收来自客户端的数据,进行处理后将结果返回给客户端。
在服务端处理请求的过程中,首先需要对客户端发送的 SQL 语句进行解析。 解析器的实现相对简单,由于支持的 SQL 语法较为有限,使用字符串分割和匹配的方式来完成解析。 如果解析的 SQL 语句合法,服务端将执行相应的逻辑并返回结果。
服务端的后端部分可以划分为五个主要模块,每个模块通过接口提供功能给其他依赖它的模块。这五个模块的具体功能如下:
- 事务管理模块(TM):负责管理事务的启动、提交、回滚等操作,确保数据一致性。
- 数据管理模块(DM):负责数据的存储、读取以及物理数据的管理。
- 版本管理模块(VM):负责管理数据的多版本控制,确保在并发操作下的数据一致性。
- 索引管理模块(IM):负责索引的创建、维护和查询优化,提升数据检索的效率。
- 表管理模块(TBM):负责表结构的管理,包括表的创建、修改以及元数据的管理。
各个模块之间通过接口进行协作,模块的依赖关系如下图所示。 通过这种模块化设计,系统可以确保每个功能的清晰分工,同时增强可扩展性和维护性。
在运行之前,请确保你在 pom.xml
文件中调整了项目的编译版本以匹配你的 JDK。
如果你将项目导入 IDE,请相应地更改项目的编译设置。
首先,使用以下命令编译源码:
mvn compile
编译完成后,使用以下命令创建数据库,假设数据库路径为 /tmp/javadb
:
mvn exec:java -Dexec.mainClass="cn.tangrl.javadb.backend.Launcher" -Dexec.args="-create /tmp/javadb"
创建数据库后,运行以下命令以默认参数启动数据库服务:
mvn exec:java -Dexec.mainClass="cn.tangrl.javadb.backend.Launcher" -Dexec.args="-open /tmp/javadb"
在另一个终端中,执行以下命令启动客户端并连接到数据库:
mvn exec:java -Dexec.mainClass="cn.tangrl.javadb.client.Launcher"
客户端启动后,将会提供一个交互式的命令行界面。 在该界面中,你可以输入类似 SQL 的语法,并通过回车将语句发送到服务器,随后会输出执行结果。
- 基于 NIO 实现非阻塞式 I/O,提高后端的高并发能力。
- 基于 ANTLR 语法分析器生成器 实现 SQL 语法解析。
- 支持更多的 SQL 语法