现在AI飞速发展,两天就可以开发一个项目,选择数据库需要选对。
SQLite vs MySQL 超全对比|小项目选谁?一篇讲透!

一句话速选结论
| 场景 | 推荐选择 |
|---|---|
| 桌面软件、单机应用、小程序、嵌入式设备 | SQLite |
| 网站后台、高并发、多人协作、大数据量 | MySQL |
本文不深究底层原理,聚焦实际开发中的选型逻辑、使用方法与避坑指南,帮你快速匹配项目与数据库的适配关系。
一、架构本质差异:一个”无服务”,一个”有服务”
MySQL:经典客户端-服务器架构
MySQL 是典型的 C/S(客户端-服务器)架构:后台存在独立的 mysqld 服务进程,应用程序通过 JDBC 或网络协议连接到服务器,由服务器统一完成数据的读写、调度与管理。
核心特点:
- 支持多客户端同时连接,天然适配网站多人访问场景
- 具备完善的权限管理、事务机制与备份方案
- 需要独立安装、配置服务进程,需专人运维
SQLite:无服务器嵌入式架构
SQLite 采用 Serverless 嵌入式架构:没有独立的服务器进程,整个数据库就是一个 .db 格式的磁盘文件,应用程序直接通过内置库文件读写数据。
核心特点:
- 零配置、零安装,单个文件即可完成全部数据库功能
- 启动速度达毫秒级,资源占用极低
- 可随应用程序一起打包分发,无需额外部署
- 单线程写入,多进程同时写入会触发数据库锁
可以简单理解:MySQL 是”线下饭店”——有后厨、有服务员,支持多人同时就餐;SQLite 是”自热火锅”——打开就能用,适合单人/少量场景,便携性拉满。
二、核心指标全方位对比
| 对比维度 | SQLite | MySQL |
|---|---|---|
| 体积 | 约 1MB(单个库文件) | 安装包 400MB+,运行占用 500MB+ 内存 |
| 安装部署 | 无需安装,复制 .db 文件即可使用 | 需要安装、配置服务、设置权限,迁移需导出导入 SQL |
| 并发能力 | 单写多读,写入操作会锁库 | 多线程读写,支持高并发场景 |
| 网络访问 | 不支持远程连接,仅本地文件访问 | 支持远程网络连接,可部署在独立服务器 |
| 数据规模 | 适合 GB 级别数据量 | 支持 TB 级别大数据量 |
| 用户权限 | 无内置权限系统,依赖操作系统文件权限 | 支持精细的 GRANT 权限控制,可分配多用户角色 |
| 事务支持 | 完整支持 ACID 特性 | 支持 ACID,同时提供多种事务隔离级别 |
| 存储引擎 | 仅内置一种存储引擎 | 支持 InnoDB、MyISAM 等多种存储引擎,可按需选择 |
| 典型适用场景 | 桌面App、嵌入式设备、单元测试、本地缓存 | 企业网站、业务系统、大数据平台、高并发接口 |
三、Java 开发连接方式对比
SQLite:极简连接方案
Maven 依赖
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.41.2.1</version>
</dependency>
核心连接代码 无需用户名密码,无需启动服务,直接指定本地文件路径,文件不存在会自动创建:
Connection conn = DriverManager.getConnection("jdbc:sqlite:mydata.db");
完整工具类示例
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class SQLiteUtils {
private static final String URL = "jdbc:sqlite:student.db";
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(URL);
}
// 查询操作
public static ResultSet query(String sql) {
try (Connection conn = getConnection();
Statement stmt = conn.createStatement()) {
return stmt.executeQuery(sql);
} catch (SQLException e) {
e.printStackTrace();
return null;
}
}
// 增删改操作
public static int update(String sql) {
try (Connection conn = getConnection();
Statement stmt = conn.createStatement()) {
return stmt.executeUpdate(sql);
} catch (SQLException e) {
e.printStackTrace();
return 0;
}
}
}
MySQL:标准服务端连接
Maven 依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
核心连接代码 需要配置地址、端口、用户名、密码,且必须确保 MySQL 服务处于启动状态:
String url = "jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai";
String user = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url, user, password);
若服务未启动,会直接抛出 Communications link failure 异常。
四、SQL 语法差异与注意事项
两者基础 SQL 语法高度兼容,但在字段类型、特性关键字上存在差异,开发中容易踩坑。
1. 创建表语法差异
| 功能点 | SQLite | MySQL |
|---|---|---|
| 自增主键 | INTEGER PRIMARY KEY AUTOINCREMENT | INT PRIMARY KEY AUTO_INCREMENT |
| 字符串类型 | TEXT | VARCHAR(长度) |
| 日期类型 | 用 TEXT 或 INTEGER 存储 | 原生支持 DATE / DATETIME 类型 |
SQLite 建表示例
CREATE TABLE student (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
age INTEGER,
score REAL
);
MySQL 建表示例
CREATE TABLE student (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
age INT,
score DECIMAL(5,2)
);
注意:SQLite 的自增关键字必须搭配
INTEGER类型使用,写INT会导致自增失效。
2. 增删查改语法
插入、查询、更新、删除的基础语法两者完全一致:
-- 插入
INSERT INTO student (name, age, score) VALUES ('张三', 20, 89.5);
-- 查询
SELECT * FROM student WHERE age > 18 ORDER BY score DESC;
3. 查看建表语句
- SQLite 特有方式:
SELECT sql FROM sqlite_master
WHERE type = 'table' AND name = 'student';
- MySQL 方式:
SHOW CREATE TABLE student;
五、在 IDEA 中使用 SQLite
- 添加依赖后,打开 Database 面板:
View → Tool Windows → Database - 新建数据源:点击
+ → Data Source → SQLite - 选择数据库文件:点击 File 旁的浏览按钮,选中本地
.db文件 - 点击
Test Connection,出现绿色对勾即连接成功
提示:SQLite 没有用户系统,无需填写用户名和密码,权限由操作系统的文件权限控制。
六、SQLite 常见踩坑指南
坑1:database is locked(数据库被锁)
报错信息:SQLITE_BUSY: database is locked 根本原因:SQLite 是单线程写入模型。如果代码中同时打开多个 Connection 写入,或者上一个连接未关闭就开启新连接,就会触发锁库。 解决方案:使用 try-with-resources 语法,让连接自动关闭:
// 正确写法:用完自动关闭连接
try (Connection conn = getConnection();
Statement stmt = conn.createStatement()) {
stmt.executeUpdate("INSERT ...");
}
坑2:AUTOINCREMENT 自增不生效
必须同时满足两个条件:
- 字段类型必须是
INTEGER,不能是INT - 字段必须声明为
PRIMARY KEY
坑3:没有原生 Boolean 类型
SQLite 没有专门的布尔类型,用 INTEGER 替代:
0代表 false1代表 true
坑4:不支持 ALTER TABLE 删除列
SQLite 无法直接删除表字段,需要通过”新建表-复制数据-删旧表-重命名”的方式间接实现:
-- 1. 创建不含目标列的新表
CREATE TABLE student_new (id INTEGER PRIMARY KEY, name TEXT);
-- 2. 复制原有数据
INSERT INTO student_new SELECT id, name FROM student;
-- 3. 删除旧表
DROP TABLE student;
-- 4. 重命名新表
ALTER TABLE student_new RENAME TO student;
七、选型决策指南
快速决策树
你的项目是什么类型?
│
┌─────┴─────┐
▼ ▼
单机/桌面应用 网站/服务器
│ │
▼ ▼
SQLite MySQL
✅ 推荐 ✅ 推荐
细分场景选型表
| 场景 | 推荐数据库 | 核心理由 |
|---|---|---|
| 个人桌面记账、工具类软件 | SQLite | 终端用户无需安装数据库,软件开箱即用 |
| 单机版毕业设计项目 | SQLite | 项目文件直接拷贝即可运行,答辩演示方便 |
| 单元测试模拟数据库 | SQLite | 支持内存模式,测试完成数据自动销毁,无污染 |
| 浏览器本地大容量存储 | SQLite | 可通过 WASM 在浏览器运行,补充 IndexedDB 的能力 |
| 企业官网+后台管理系统 | MySQL | 支持多人同时访问,可精细化分配权限 |
| 秒杀、高并发接口服务 | MySQL + Redis | SQLite 无法支撑高并发写入 |
| 单表数据量超过 1GB | MySQL | SQLite 大文件下性能会明显下降 |
八、SQLite 进阶:内存数据库(测试神器)
SQLite 支持纯内存运行模式,数据全部存储在内存中,程序退出自动清空,速度极快:
Connection conn = DriverManager.getConnection("jdbc:sqlite::memory:");
适用场景:
- 单元测试:每个测试用例独立内存库,数据互不干扰
- 临时数据处理:比 HashMap 更灵活,支持完整 SQL 语法
- 高频缓存:重启程序自动清空,无需额外清理逻辑
九、总结
| 核心诉求 | 选 SQLite | 选 MySQL |
|---|---|---|
| 简单省事、开箱即用 | ✅ | ❌ |
| 零配置、随软件打包分发 | ✅ | ❌ |
| 高并发多用户访问 | ❌ | ✅ |
| 支撑大数据量、复杂业务 | ❌ | ✅ |
| 需要远程网络访问 | ❌ | ✅ |
| 精细化用户权限控制 | ❌ | ✅ |
简单来说:
- SQLite 是”瑞士军刀”——小巧轻便、随时能用,是个人项目、桌面应用、嵌入式场景的最优解。
- MySQL 是”重型卡车”——稳定强大、承载力强,是企业系统、网站后台、高并发场景的标准选择。
两者并非竞争关系,而是互补关系。很多成熟项目会同时使用:用 MySQL 存储核心业务数据,用 SQLite 做客户端本地缓存或离线功能。
附录:SQLite 字段类型速查
| 类型 | 说明 | 对应 Java 类型 |
|---|---|---|
NULL | 空值 | null |
INTEGER | 整型 | Long / Integer |
REAL | 浮点型 | Double / Float |
TEXT | 文本字符串 | String |
BLOB | 二进制数据 | byte[] |
