⌘+k ctrl+k
1.3 (稳定版)
搜索快捷键 cmd + k | ctrl + k
ATTACH 和 DETACH 语句

DuckDB 允许附加到数据库文件和从数据库文件分离。

示例

附加数据库 file.db,别名从名称 (file) 推断

ATTACH 'file.db';

附加数据库 file.db,并显式指定别名 (file_db)

ATTACH 'file.db' AS file_db;

以只读模式附加数据库 file.db

ATTACH 'file.db' (READ_ONLY);

以 16 kB 的块大小附加数据库 file.db

ATTACH 'file.db' (BLOCK_SIZE 16_384);

附加 SQLite 数据库进行读写(更多信息请参阅 sqlite 扩展

ATTACH 'sqlite_file.db' AS sqlite_db (TYPE sqlite);

如果推断的数据库别名 file 尚不存在,则附加数据库 file.db

ATTACH IF NOT EXISTS 'file.db';

如果显式数据库别名 file_db 尚不存在,则附加数据库 file.db

ATTACH IF NOT EXISTS 'file.db' AS file_db;

将数据库 file2.db 附加为别名 file_db,如果现有别名存在则分离并替换它

ATTACH OR REPLACE 'file2.db' AS file_db;

在附加的数据库中创建表,别名为 file

CREATE TABLE file.new_table (i INTEGER);

分离别名为 file 的数据库

DETACH file;

显示所有已附加数据库的列表

SHOW DATABASES;

将默认数据库更改为数据库 file

USE file;

ATTACH

ATTACH 语句将新的数据库文件添加到目录中,可以从中读取和写入。请注意,附加定义不会在会话之间持久化:当启动新会话时,您必须重新附加到所有数据库。

Attach 语法

ATTACH 允许 DuckDB 对多个数据库文件进行操作,并允许在不同数据库文件之间传输数据。

ATTACH 支持 HTTP 和 S3 端点。对于这些端点,默认创建只读连接。因此,以下两个命令是等效的:

ATTACH 'https://blobs.duckdb.org/databases/stations.duckdb' AS stations_db;
ATTACH 'https://blobs.duckdb.org/databases/stations.duckdb' AS stations_db (READ_ONLY);

同样,以下连接到 S3 的两个命令是等效的:

ATTACH 's3://duckdb-blobs/databases/stations.duckdb' AS stations_db;
ATTACH 's3://duckdb-blobs/databases/stations.duckdb' AS stations_db (READ_ONLY);

在 DuckDB 1.1.0 版本之前,必须为 HTTP 和 S3 端点指定 READ_ONLY 标志。

显式存储版本

DuckDB v1.2.0 引入了 STORAGE_VERSION 选项,它允许显式指定存储版本。使用此选项,您可以选择启用新的向前不兼容的功能。

ATTACH 'file.db' (STORAGE_VERSION 'v1.2.0');

此设置指定了能够读取数据库文件的最低 DuckDB 版本。当使用此选项写入数据库文件时,生成的文件不能被低于指定版本的旧版 DuckDB 打开。它们可以被指定版本和所有更新版本的 DuckDB 读取。

更多详细信息,请参阅“存储”页面

DETACH

DETACH 语句允许关闭和分离之前附加的数据库文件,释放数据库文件上持有的任何锁。

请注意,无法从默认数据库分离:如果您想这样做,请发出 USE 语句将默认数据库更改为另一个。例如,如果您连接到持久数据库,可以通过发出以下命令更改为内存数据库:

ATTACH ':memory:' AS memory_db;
USE memory_db;

警告 关闭连接,例如调用 Python 中的 close() 函数,不会释放数据库文件上持有的锁,因为文件句柄由主 DuckDB 实例(在 Python 的情况下,是 duckdb 模块)持有。

Detach 语法

选项

名称 描述 类型 默认值
access_mode 数据库的访问模式(AUTOMATICREAD_ONLYREAD_WRITE)。 VARCHAR automatic
type 文件类型(DUCKDBSQLITE),或从输入字符串字面量推断(MySQL、PostgreSQL)。 VARCHAR DUCKDB
block_size 新数据库文件的块大小。必须是 2 的幂,且在 [16384, 262144] 范围内。不能为现有文件设置。 UBIGINT 262144

名称限定

目录对象的完全限定名称包含对象的目录模式名称。例如:

附加数据库 new_db

ATTACH 'new_db.db';

在数据库 new_db 中创建模式 my_schema

CREATE SCHEMA new_db.my_schema;

在模式 my_schema 中创建表 my_table

CREATE TABLE new_db.my_schema.my_table (col INTEGER);

引用表 my_table 中的列 col

SELECT new_db.my_schema.my_table.col FROM new_db.my_schema.my_table;

请注意,通常不需要完全限定名称。当名称未完全限定时,系统会使用目录搜索路径查找要引用的条目。默认目录搜索路径包括系统目录、临时目录和初始附加的数据库以及 main 模式。

另请注意标识符和特别是数据库名称的规则

默认数据库和模式

当创建表时没有任何限定符,表将在默认数据库的默认模式中创建。默认数据库是系统创建时启动的数据库——默认模式是 main

在默认数据库中创建表 my_table

CREATE TABLE my_table (col INTEGER);

更改默认数据库和模式

可以使用 USE 命令更改默认数据库和模式。

将默认数据库模式设置为 new_db.main

USE new_db;

将默认数据库模式设置为 new_db.my_schema

USE new_db.my_schema;

解决冲突

当只提供一个限定符时,只要没有冲突,系统可以将其解释为目录模式。例如:

ATTACH 'new_db.db';
CREATE SCHEMA my_schema;

创建表 new_db.main.tbl

CREATE TABLE new_db.tbl (i INTEGER);

创建表 default_db.my_schema.tbl

CREATE TABLE my_schema.tbl (i INTEGER);

如果我们制造冲突(即,我们同时有一个同名的模式和一个同名的目录),系统会要求改用完全限定路径:

CREATE SCHEMA new_db;
CREATE TABLE new_db.tbl (i INTEGER);
Binder Error:
Ambiguous reference to catalog or schema "new_db" - use a fully qualified path like "memory.new_db"

更改目录搜索路径

可以通过设置 search_path 配置选项来调整目录搜索路径,该选项使用逗号分隔的值列表作为搜索路径。以下示例演示在两个数据库中进行搜索:

ATTACH ':memory:' AS db1;
ATTACH ':memory:' AS db2;
CREATE table db1.tbl1 (i INTEGER);
CREATE table db2.tbl2 (j INTEGER);

使用其完全限定名称引用表

SELECT * FROM db1.tbl1;
SELECT * FROM db2.tbl2;

或者设置搜索路径并使用其名称引用表

SET search_path = 'db1,db2';
SELECT * FROM tbl1;
SELECT * FROM tbl2;

事务语义

在多个数据库上运行查询时,系统会为每个数据库打开独立的事务。默认情况下,事务是延迟启动的——当查询中首次引用给定数据库时,该数据库的事务将被启动。SET immediate_transaction_mode = true 可以切换此行为,改为在所有附加数据库中立即启动事务。

虽然可以同时激活多个事务,但系统在一个事务中只支持对单个附加数据库进行写入。如果您尝试在单个事务中写入多个附加数据库,将抛出以下错误:

Attempting to write to database "db2" in a transaction that has already modified database "db1" -
a single transaction can only write to a single attached database.

此限制的原因是系统不对跨附加数据库的事务保持原子性。事务仅在每个数据库文件内部是原子性的。通过将全局事务限制为仅写入单个数据库文件,可以保持原子性保证。