SQLite数据库操作 #
一、数据库概述 #
1.1 SQLite数据库特点 #
sql
-- SQLite 数据库特点:
-- 1. 单文件存储 - 整个数据库存储在一个文件中
-- 2. 无服务器 - 不需要单独的服务器进程
-- 3. 零配置 - 无需安装和配置
-- 4. 动态类型 - 列类型灵活
-- 数据库文件扩展名:
-- .db - 最常用
-- .sqlite - 常用
-- .sqlite3- 常用
-- .db3 - 较少使用
1.2 数据库文件结构 #
text
数据库文件结构:
┌────────────────────────────────┐
│ 文件头 (100字节) │
├────────────────────────────────┤
│ 页面 1 (B-Tree页) │
├────────────────────────────────┤
│ 页面 2 (B-Tree页) │
├────────────────────────────────┤
│ 页面 3 (溢出页) │
├────────────────────────────────┤
│ ... │
└────────────────────────────────┘
-- 页面大小:512 到 65536 字节(默认 4096)
二、创建数据库 #
2.1 命令行创建 #
bash
# 方式1:直接创建
sqlite3 myapp.db
# 方式2:创建并执行SQL
sqlite3 myapp.db "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT);"
# 方式3:创建内存数据库
sqlite3 :memory:
# 方式4:创建临时文件数据库
sqlite3 ''
2.2 在SQLite命令行中创建 #
sql
-- 打开或创建数据库
.open myapp.db
-- 检查当前数据库
.databases
-- 输出示例:
-- main: /path/to/myapp.db
2.3 编程语言创建 #
python
# Python
import sqlite3
# 创建/打开数据库文件
conn = sqlite3.connect('myapp.db')
# 创建内存数据库
conn = sqlite3.connect(':memory:')
# 创建临时文件数据库
conn = sqlite3.connect('')
javascript
// Node.js (better-sqlite3)
const Database = require('better-sqlite3');
// 创建/打开数据库文件
const db = new Database('myapp.db');
// 创建内存数据库
const db = new Database(':memory:');
java
// Java
import java.sql.Connection;
import java.sql.DriverManager;
// 创建/打开数据库文件
Connection conn = DriverManager.getConnection("jdbc:sqlite:myapp.db");
// 创建内存数据库
Connection conn = DriverManager.getConnection("jdbc:sqlite::memory:");
三、内存数据库 #
3.1 创建内存数据库 #
sql
-- 内存数据库:数据存储在内存中,关闭后数据丢失
-- 命令行方式
sqlite3 :memory:
-- 或在SQLite命令行中
.open :memory:
-- 创建表并插入数据
CREATE TABLE temp_data (id INTEGER PRIMARY KEY, value TEXT);
INSERT INTO temp_data (value) VALUES ('temporary');
-- 查询数据
SELECT * FROM temp_data;
3.2 内存数据库特点 #
sql
-- 优点:
-- 1. 速度极快 - 无磁盘I/O
-- 2. 安全 - 关闭后数据消失
-- 3. 无需清理 - 无临时文件
-- 缺点:
-- 1. 数据不持久
-- 2. 受内存大小限制
-- 3. 进程结束数据丢失
-- 适用场景:
-- 1. 临时数据处理
-- 2. 测试环境
-- 3. 缓存数据
-- 4. 数据分析中间结果
3.3 内存数据库持久化 #
sql
-- 将内存数据库保存到文件
-- 方法1:使用 .backup 命令
.backup 'backup.db'
-- 方法2:使用 ATTACH 复制
ATTACH DATABASE 'backup.db' AS backup;
CREATE TABLE backup.users AS SELECT * FROM main.users;
DETACH DATABASE backup;
四、附加数据库 #
4.1 ATTACH命令 #
sql
-- SQLite 支持同时操作多个数据库
-- 使用 ATTACH 附加其他数据库
-- 基本语法
ATTACH DATABASE 'filename' AS database_name;
-- 示例
ATTACH DATABASE 'users.db' AS users_db;
ATTACH DATABASE 'orders.db' AS orders_db;
ATTACH DATABASE 'logs.db' AS logs_db;
-- 查看附加的数据库
.databases
-- 输出示例:
-- main: /path/to/main.db
-- users_db: /path/to/users.db
-- orders_db: /path/to/orders.db
-- logs_db: /path/to/logs.db
4.2 访问附加数据库 #
sql
-- 使用 database_name.table_name 访问表
-- 主数据库(main)
SELECT * FROM main.users;
-- 附加的数据库
SELECT * FROM users_db.users;
SELECT * FROM orders_db.orders;
-- 跨数据库查询
SELECT
u.name,
o.order_date,
o.total
FROM main.users u
JOIN orders_db.orders o ON u.id = o.user_id;
-- 跨数据库插入
INSERT INTO logs_db.logs (message)
SELECT 'Order created: ' || id FROM orders_db.orders;
4.3 跨数据库操作 #
sql
-- 创建跨数据库视图
CREATE VIEW order_summary AS
SELECT
u.name,
o.id AS order_id,
o.total
FROM main.users u
JOIN orders_db.orders o ON u.id = o.user_id;
-- 跨数据库复制表
CREATE TABLE users_db.users_backup AS
SELECT * FROM main.users;
-- 跨数据库事务
BEGIN TRANSACTION;
INSERT INTO main.users (name) VALUES ('Alice');
INSERT INTO orders_db.orders (user_id, total) VALUES (last_insert_rowid(), 100);
COMMIT;
4.4 分离数据库 #
sql
-- 使用 DETACH 分离数据库
DETACH DATABASE database_name;
-- 示例
DETACH DATABASE users_db;
DETACH DATABASE orders_db;
-- 注意:main 数据库不能分离
DETACH DATABASE main; -- 错误!
五、数据库信息 #
5.1 查看数据库列表 #
sql
-- 命令行方式
.databases
-- SQL方式
SELECT
name,
file
FROM pragma_database_list;
-- 输出示例:
-- name | file
-- --------|------------------
-- main | /path/to/main.db
-- temp |
-- users_db| /path/to/users.db
5.2 查看数据库属性 #
sql
-- 数据库页面大小
PRAGMA page_size;
-- 数据库页数
PRAGMA page_count;
-- 数据库大小(字节)
SELECT page_size * page_count AS size_bytes FROM pragma_page_count;
-- 数据库版本
PRAGMA schema_version;
-- 用户版本(可用于版本控制)
PRAGMA user_version;
-- 设置用户版本
PRAGMA user_version = 1;
5.3 数据库统计信息 #
sql
-- 表统计
SELECT
name AS table_name,
(SELECT COUNT(*) FROM pragma_table_info(m.name)) AS column_count
FROM sqlite_master
WHERE type = 'table';
-- 索引统计
SELECT COUNT(*) AS index_count
FROM sqlite_master
WHERE type = 'index' AND sql IS NOT NULL;
-- 触发器统计
SELECT COUNT(*) AS trigger_count
FROM sqlite_master
WHERE type = 'trigger';
六、数据库维护 #
6.1 VACUUM命令 #
sql
-- VACUUM:重建数据库文件,回收空间
-- 基本用法
VACUUM;
-- 指定数据库
VACUUM main;
-- VACUUM 的作用:
-- 1. 回收已删除数据占用的空间
-- 2. 重建数据库文件
-- 3. 整理碎片
-- 4. 优化性能
-- 注意:
-- 1. 执行期间会锁定数据库
-- 2. 需要足够的磁盘空间(临时需要2倍大小)
-- 3. 大数据库执行时间较长
-- 自动 VACUUM 模式
PRAGMA auto_vacuum = NONE; -- 默认,不自动回收
PRAGMA auto_vacuum = FULL; -- 完全自动回收
PRAGMA auto_vacuum = INCREMENTAL; -- 增量回收
-- 增量 VACUUM
PRAGMA incremental_vacuum(100); -- 回收100页
6.2 INTEGRITY_CHECK #
sql
-- 检查数据库完整性
PRAGMA integrity_check;
-- 完整检查(较慢)
PRAGMA integrity_check(1000000);
-- 快速检查
PRAGMA quick_check;
-- 检查特定表
PRAGMA integrity_check('users');
6.3 数据库优化 #
sql
-- 分析统计信息
ANALYZE;
-- 分析特定表
ANALYZE users;
-- 分析特定索引
ANALYZE idx_users_email;
-- 更新统计信息后,查询优化器可以更好地选择索引
七、数据库配置 #
7.1 PRAGMA设置 #
sql
-- 常用 PRAGMA 设置
-- 页面大小(创建数据库时设置)
PRAGMA page_size = 4096;
-- 缓存大小(页数)
PRAGMA cache_size = -2000; -- 负数表示KB
-- 日志模式
PRAGMA journal_mode = DELETE; -- 默认
PRAGMA journal_mode = WAL; -- Write-Ahead Logging(推荐)
PRAGMA journal_mode = MEMORY; -- 内存日志
PRAGMA journal_mode = OFF; -- 无日志
-- 同步模式
PRAGMA synchronous = OFF; -- 不同步(最快,不安全)
PRAGMA synchronous = NORMAL; -- 正常同步
PRAGMA synchronous = FULL; -- 完全同步(最安全)
-- 外键约束
PRAGMA foreign_keys = ON; -- 启用外键
PRAGMA foreign_keys = OFF; -- 禁用外键
-- 临时文件存储
PRAGMA temp_store = MEMORY; -- 内存
PRAGMA temp_store = FILE; -- 文件
-- 锁定模式
PRAGMA locking_mode = NORMAL; -- 正常
PRAGMA locking_mode = EXCLUSIVE; -- 独占
7.2 查看当前设置 #
sql
-- 查看各种设置
PRAGMA page_size;
PRAGMA cache_size;
PRAGMA journal_mode;
PRAGMA synchronous;
PRAGMA foreign_keys;
PRAGMA temp_store;
PRAGMA locking_mode;
-- 查看所有编译选项
PRAGMA compile_options;
八、数据库备份与恢复 #
8.1 使用.backup命令 #
sql
-- 备份数据库
.backup 'backup.db'
-- 备份到指定数据库
.backup main 'backup.db'
-- 备份附加的数据库
.backup users_db 'users_backup.db'
8.2 使用.dump命令 #
sql
-- 导出SQL脚本
.dump
-- 导出到文件
.output backup.sql
.dump
.output stdout
-- 导出特定表
.dump users
-- 导出多个表
.dump users orders products
8.3 恢复数据库 #
bash
# 从SQL脚本恢复
sqlite3 new.db < backup.sql
# 或在SQLite命令行中
sqlite3 new.db
.read backup.sql
8.4 在线备份API #
python
# Python 在线备份
import sqlite3
def backup_database(source_db, dest_db):
source = sqlite3.connect(source_db)
dest = sqlite3.connect(dest_db)
# 执行备份
source.backup(dest)
dest.close()
source.close()
backup_database('main.db', 'backup.db')
九、数据库安全 #
9.1 文件权限 #
bash
# 设置数据库文件权限
chmod 600 myapp.db # 只有所有者可读写
# 设置目录权限
chmod 700 /path/to/database/directory
9.2 数据库加密 #
sql
-- SQLite 本身不支持加密
-- 需要使用扩展:
-- 1. SQLCipher - 商业加密扩展
-- 2. SEE - SQLite Encryption Extension
-- 3. wxSQLite3 - 开源加密扩展
-- SQLCipher 示例
PRAGMA key = 'your-encryption-key';
-- 或
PRAGMA key = "x'your-hex-key'";
-- 重新加密
PRAGMA rekey = 'new-encryption-key';
9.3 只读模式 #
sql
-- 以只读模式打开数据库
-- 命令行
sqlite3 file:myapp.db?mode=ro
-- URI 格式
.open file:myapp.db?mode=ro
-- Python
conn = sqlite3.connect('file:myapp.db?mode=ro', uri=True)
十、常见问题 #
10.1 数据库被锁定 #
sql
-- 错误:database is locked
-- 解决方案:
-- 1. 使用 WAL 模式
PRAGMA journal_mode = WAL;
-- 2. 增加超时时间
PRAGMA busy_timeout = 5000; -- 5秒
-- 3. 减少事务时间
BEGIN IMMEDIATE;
-- 快速操作
COMMIT;
10.2 数据库损坏 #
sql
-- 检查损坏
PRAGMA integrity_check;
-- 如果损坏,尝试恢复
-- 1. 导出数据
.dump
-- 2. 创建新数据库
-- 3. 导入数据
.read backup.sql
10.3 磁盘空间不足 #
sql
-- 检查数据库大小
SELECT page_size * page_count / 1024 / 1024 AS size_mb
FROM pragma_page_count;
-- 回收空间
VACUUM;
-- 删除不需要的数据后执行VACUUM
DELETE FROM logs WHERE created_at < date('now', '-30 days');
VACUUM;
十一、总结 #
数据库操作要点 #
| 操作 | 命令/方法 |
|---|---|
| 创建数据库 | sqlite3 filename.db |
| 打开数据库 | .open filename.db |
| 附加数据库 | ATTACH DATABASE ‘file’ AS name |
| 分离数据库 | DETACH DATABASE name |
| 备份数据库 | .backup ‘file’ |
| 导出SQL | .dump |
| 检查完整性 | PRAGMA integrity_check |
| 回收空间 | VACUUM |
最佳实践 #
- 使用 WAL 模式提高并发性能
- 定期备份数据库
- 定期执行 VACUUM 回收空间
- 使用 PRAGMA 优化配置
- 注意数据库文件权限
下一步,让我们学习表操作!
最后更新:2026-03-27