SQLite 轻量数据库:嵌入式与移动端首选
SQLite 轻量数据库:嵌入式与移动端首选
SQLite 是一个自包含、无服务器、零配置、事务性的 SQL 数据库引擎。它占用资源极小,且无需独立的服务器进程,数据库就是一个磁盘文件。因此,SQLite 成为嵌入式系统、移动应用、桌面软件以及网站原型开发的理想选择。
本教程面向零基础初学者,带你从认识 SQLite 到熟练使用其核心功能。
为什么选择 SQLite?
在正式学习之前,先了解 SQLite 的核心优势,有助于你理解它的应用场景。
- 零配置:无需安装、管理数据库服务器,没有配置文件。
- 轻量化:整个库的大小通常小于 600KB,运行时内存消耗仅需数百 KB。
- 单一文件:整个数据库存储在一个跨平台的普通磁盘文件中,备份和迁移极其简单。
- 跨平台:支持 Windows、Linux、macOS、Android、iOS 等主流系统。
- ACID 兼容:支持事务,遵循原子性、一致性、隔离性和持久性。
- 公共领域:SQLite 的代码属于公有领域,可自由用于商业或私人项目。
适用场景
- 移动应用:Android、iOS 原生数据库的首选方案。
- 嵌入式设备:IoT、机顶盒、车载系统等资源受限的环境。
- 桌面软件:应用程序内部的数据存储,如浏览器书签、电子邮件客户端。
- 测试与原型:快速搭建后端数据层,无需配置专用数据库服务器。
- 网站中小规模数据:日请求量低于 10 万次的网站可直接使用 SQLite。
安装 SQLite
Windows
- 访问 SQLite 官方下载页面:sqlite.org/download.html
- 下载预编译的二进制文件压缩包(如
sqlite-tools-win-x64-*.zip)。 - 解压得到
sqlite3.exe,将其所在目录添加到系统环境变量PATH中。 - 打开命令提示符,输入
sqlite3验证安装。
macOS
macOS 通常已预装 SQLite。在终端输入:
sqlite3 --version
若未安装,可通过 Homebrew 安装:
brew install sqlite
Linux (Ubuntu/Debian)
sudo apt update
sudo apt install sqlite3
快速启动:创建第一个数据库
SQLite 数据库就是一个文件,你可以用命令行或代码创建。
- 打开终端,执行:
sqlite3 my_database.db
- 此时会进入 SQLite 交互式终端,并自动创建
my_database.db文件。 - 查看帮助命令:在 sqlite> 提示符下输入
.help。 - 退出命令行:输入
.quit。
核心数据类型
与许多数据库不同,SQLite 使用动态类型系统,但它为其值定义了存储类(Storage Class)。
| 存储类 | 描述 |
|---|---|
| NULL | 空值 |
| INTEGER | 有符号整数,可存储 0、1、2、3、4、6、8 字节 |
| REAL | 浮点值,存储为 8 字节 IEEE 浮点数 |
| TEXT | 文本字符串,使用数据库编码(UTF-8、UTF-16BE 或 UTF-16LE) |
| BLOB | 二进制数据,完全按照输入存储 |
SQLite 也支持类型亲和性(Type Affinity),可简化与其它数据库的兼容。
基本命令行操作
进入 sqlite3 交互环境后,以下是一些常用 点命令(开头带有句点):
.databases– 列出当前连接中附加的数据库。.tables– 显示所有表名。.schema [table_name]– 查看建表语句。.headers on– 查询结果显示列标题。.mode column– 以列模式格式化输出。.import <文件> <表名>– 从 CSV 文件导入数据到表。.output <文件名>– 将输出重定向到文件。.exit或.quit– 退出。
SQL 语句速查
SQLite 支持大多数 SQL-92 标准,以下是常用语句示例。
创建表
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE NOT NULL,
age INTEGER,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
插入数据
INSERT INTO users (name, email, age) VALUES ('Alice', 'alice@example.com', 25);
INSERT INTO users (name, email, age) VALUES ('Bob', 'bob@example.com', 30);
查询数据
SELECT * FROM users;
SELECT name, email FROM users WHERE age > 20 ORDER BY name;
更新数据
UPDATE users SET age = 26 WHERE id = 1;
删除数据
DELETE FROM users WHERE id = 2;
模糊查询
SELECT * FROM users WHERE name LIKE 'A%';
聚合查询
SELECT COUNT(*), AVG(age) FROM users;
分组与排序
SELECT age, COUNT(*) FROM users GROUP BY age HAVING COUNT(*) > 1;
连接查询(JOIN)
假设有订单表 orders:
SELECT users.name, orders.product
FROM users
INNER JOIN orders ON users.id = orders.user_id;
事务支持
SQLite 完全支持事务,确保数据完整性。
BEGIN TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;
发生错误时可执行 ROLLBACK 回滚。
索引优化查询
为常用查询列创建索引可以显著提高性能。
CREATE INDEX idx_users_email ON users(email);
CREATE UNIQUE INDEX idx_unique_email ON users(email);
查看索引列表:
SELECT * FROM sqlite_master WHERE type = 'index';
视图
视图是基于查询结果的虚拟表,可简化复杂查询。
CREATE VIEW user_orders AS
SELECT u.name, o.product
FROM users u
JOIN orders o ON u.id = o.user_id;
像查询普通表一样使用视图:
SELECT * FROM user_orders;
在编程语言中使用 SQLite
SQLite 广泛支持各种语言,以下是 Python 示例(其他语言类似)。
Python (sqlite3 模块)
import sqlite3
# 创建连接
conn = sqlite3.connect('example.db')
cursor = conn.cursor()
# 建表
cursor.execute('''
CREATE TABLE IF NOT EXISTS books (
id INTEGER PRIMARY KEY,
title TEXT,
author TEXT
)
''')
# 插入数据
cursor.execute("INSERT INTO books (title, author) VALUES (?, ?)", ('1984', 'George Orwell'))
# 查询数据
rows = cursor.execute("SELECT * FROM books").fetchall()
for row in rows:
print(row)
# 提交并关闭
conn.commit()
conn.close()
Android (Java/Kotlin)
Android SDK 内置 SQLiteOpenHelper 类,Room 持久性库更是官方推荐的最佳实践,在 SQLite 基础上提供抽象层。
Node.js
使用 better-sqlite3 或 sqlite3 包。
const Database = require('better-sqlite3');
const db = new Database('app.db');
db.exec("CREATE TABLE IF NOT EXISTS notes (id INTEGER PRIMARY KEY, content TEXT)");
db.prepare("INSERT INTO notes (content) VALUES (?)").run('Hello SQLite');
const rows = db.prepare("SELECT * FROM notes").all();
console.log(rows);
备份与恢复
由于 SQLite 数据库是单一文件,最简单的备份就是复制该文件。
- 文件复制备份:
cp mydb.db mydb_backup.db - 使用
.backup命令(在 sqlite3 交互终端):
sqlite3 mydb.db ".backup backup.db"
恢复时直接使用备份文件替换即可。
此外,还可用 .dump 命令将数据库导出为 SQL 脚本:
sqlite3 mydb.db .dump > dump.sql
重建数据库:
sqlite3 newdb.db < dump.sql
常见工具推荐
- DB Browser for SQLite:开源图形化管理工具,适合初学者。
- SQLiteStudio:跨平台,功能齐全的 GUI 管理工具。
- DBeaver:通用数据库工具,内置 SQLite 支持。
- 命令行:最轻量、最直接的方式。
最佳实践
- 使用参数化查询:避免 SQL 注入,如使用
?占位符。 - 合理设计表结构:使用
INTEGER PRIMARY KEY自增主键,文本数据使用TEXT。 - 善用事务:批量写入时包装在事务中可极大提升性能。
- 定期维护:执行
VACUUM命令整理数据库碎片。 - 文件路径注意:确保应用有读取该文件的权限,尤其在移动端。
- 并发写限制:SQLite 支持多读但只支持单写,高并发写入场景需考虑其他方案。
性能优化提示
- 使用内存数据库:测试时可将数据库置于内存中,如
:memory:。 - 启用 WAL 模式:
PRAGMA journal_mode=WAL;可提高并发读写性能。 - 批量插入:使用
BEGIN...COMMIT包裹多条 INSERT 语句。 - 合理索引:仅为查询频繁的列创建索引,避免过多索引对写入造成压力。
常见问题
Q:SQLite 能处理多大数据库? A:单个数据库文件大小可达 281 TB,通常实际受限于文件系统。千万条记录以内性能表现良好。
Q:SQLite 可以网络访问吗? A:SQLite 本身不支持客户端-服务器模式,但可在 NAS 上通过文件共享访问(仅限低并发场景)。需要网络数据库时建议使用 PostgreSQL 或 MySQL。
Q:多个进程可以同时写吗? A:SQLite 使用文件锁,同一时间只允许一个写者,但多个读者可以同时读。高并发写入场景会产生锁竞争。
结语
SQLite 以其极致轻量和零配置的便利性,在嵌入式与移动开发领域占据统治地位。掌握本教程内容,你将能熟练地在各种项目中运用 SQLite 构建可靠的数据存储。从简单的命令行操作,到集成在 Python、Android 等环境中的高级用法,SQLite 都表现出令人惊叹的可靠与高效。立即动手,开始你的第一个 SQLite 项目吧!