SQLite 的 “分离数据库”(Detached Database)指的是使用 ATTACH DATABASE 语句将多个 SQLite 数据库文件附加到当前数据库连接中,使它们在同一个 SQL 语句中可以像一个逻辑数据库一样被访问。
一、什么是分离数据库(Attached / Detached Database)
- 主数据库:默认打开的数据库文件(
main)。 - 分离数据库:通过
ATTACH附加的其他数据库文件,使用别名(如db2,temp等)访问。
ATTACH DATABASE 'path/to/other.db' AS db2;
之后,你可以在 SQL 中这样跨数据库查询:
SELECT * FROM main.users JOIN db2.orders ON users.id = orders.user_id;
二、核心操作
1. 附加数据库(Attach)
ATTACH DATABASE '/path/to/database2.db' AS db2;
ATTACH DATABASE ':memory:' AS mem_db; -- 附加内存数据库
注意:路径支持相对路径、绝对路径、
:memory:(内存数据库)
2. 分离数据库(Detach)
DETACH DATABASE db2;
不能分离
main和temp数据库。
三、数据库别名(Schema Names)
| 别名 | 含义 |
|---|---|
main | 默认数据库文件 |
temp | 临时数据库(通常在内存中) |
| 自定义名 | 如 db2, backup, logs 等 |
使用方式:
-- 查询 db2 中的表
SELECT * FROM db2.products;
-- 插入数据到附加数据库
INSERT INTO db2.logs (timestamp, message) VALUES (datetime('now'), 'Error occurred');
四、实际应用场景
| 场景 | 说明 |
|---|---|
| 多模块应用 | 用户数据在 users.db,订单在 orders.db,附加后可 JOIN 查询 |
| 数据迁移 | 将旧数据库附加,逐表复制数据到新数据库 |
| 日志分离 | 业务数据与日志数据分开存储,提高性能 |
| 测试/备份 | 附加只读备份数据库进行验证 |
五、示例:跨数据库迁移数据
-- 1. 附加旧数据库
ATTACH DATABASE 'old_data.db' AS old;
-- 2. 创建新表(如果不存在)
CREATE TABLE IF NOT EXISTS main.customers (
id INTEGER PRIMARY KEY,
name TEXT,
email TEXT
);
-- 3. 迁移数据
INSERT INTO main.customers (id, name, email)
SELECT id, name, email FROM old.customers;
-- 4. 分离
DETACH DATABASE old;
六、限制与注意事项
| 项目 | 说明 |
|---|---|
| 事务跨数据库 | 不支持跨多个附加数据库的原子事务(除非使用 PRAGMA foreign_keys=ON 和 WAL 模式下的某些情况) |
| 最大附加数 | 默认最多 10 个(可通过 SQLITE_MAX_ATTACHED 编译时修改,最高 125) |
| 路径权限 | 必须对附加的数据库文件有读写权限 |
| WAL 模式 | 建议使用 WAL 模式提高并发性能 |
| 内存数据库 | :memory: 数据库每个连接独立 |
查看当前附加数据库:
PRAGMA database_list;
输出示例:
seq name file
--- ------- ----------------------
0 main /path/to/main.db
2 db2 /path/to/other.db
3 temp
七、编程语言中使用(以 Python 为例)
import sqlite3
conn = sqlite3.connect('main.db')
conn.execute("ATTACH DATABASE 'logs.db' AS logs")
# 跨库查询
cur = conn.execute("""
SELECT u.name, l.action
FROM main.users u
JOIN logs.actions l ON u.id = l.user_id
""")
for row in cur:
print(row)
conn.execute("DETACH DATABASE logs")
conn.close()
总结
| 功能 | 命令 |
|---|---|
| 附加数据库 | ATTACH DATABASE 'file.db' AS alias; |
| 分离数据库 | DETACH DATABASE alias; |
| 查看附加列表 | PRAGMA database_list; |
| 跨库操作 | 使用 schema.table 语法 |
分离数据库是 SQLite 实现“多数据库逻辑合一”的强大机制,适合模块化、迁移、日志分离等场景。
如需实现 自动备份 + 附加验证 或 加密数据库附加,也可以进一步扩展(例如结合 SQLCipher)。需要我提供完整脚本吗?