Zum Inhalt springen

ATTACH- und DETACH-Anweisungen

DuckDB erlaubt das Anhängen an und das Lösen von Datenbankdateien.

Beispiele

Die Datenbank file.db mit dem aus dem Namen abgeleiteten Alias (file) anhängen:

ATTACH 'file.db';

Die Datenbank file.db mit einem expliziten Alias (file_db) anhängen:

ATTACH 'file.db' AS file_db;

Die Datenbank file.db im Nur-Lese-Modus anhängen:

ATTACH 'file.db' (READ_ONLY);

Die Datenbank file.db mit einer Blockgröße von 16 kB anhängen:

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

Die Datenbank file.db mit einer Row-Group-Größe von 2048 Zeilen anhängen:

ATTACH 'file.db' (ROW_GROUP_SIZE 2048);

Die Datenbank file.db mit deaktivierten WAL-Schreibvorgängen für bessere Performance anhängen:

ATTACH 'file.db' (RECOVERY_MODE no_wal_writes);

Eine SQLite-Datenbank zum Lesen und Schreiben anhängen (weitere Informationen in der sqlite-Extension):

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

Die Datenbank file.db anhängen, falls der abgeleitete Datenbankalias file noch nicht existiert:

ATTACH IF NOT EXISTS 'file.db';

Die Datenbank file.db anhängen, falls der explizite Datenbankalias file_db noch nicht existiert:

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

Die Datenbank file2.db als Alias file_db anhängen und den vorhandenen Alias lösen und ersetzen, falls er existiert:

ATTACH OR REPLACE 'file2.db' AS file_db;

Eine Tabelle in der angehängten Datenbank mit dem Alias file anlegen:

CREATE TABLE file.new_table (i INTEGER);

Die Datenbank mit dem Alias file lösen:

DETACH file;

Eine Liste aller angehängten Datenbanken anzeigen:

SHOW DATABASES;

Die Standarddatenbank auf die Datenbank file ändern:

USE file;

ATTACH

Die ATTACH-Anweisung fügt eine neue Datenbankdatei zum Katalog hinzu, aus der gelesen und in die geschrieben werden kann. Beachten Sie, dass Anhangsdefinitionen nicht zwischen Sitzungen persistiert werden: Wenn eine neue Sitzung gestartet wird, müssen Sie sich erneut an alle Datenbanken anhängen.

ATTACH-Syntax

ATTACH erlaubt DuckDB, mit mehreren Datenbankdateien zu arbeiten, und ermöglicht die Übertragung von Daten zwischen verschiedenen Datenbankdateien.

ATTACH unterstützt HTTP- und S3-Endpunkte. Für diese wird standardmäßig eine Nur-Lese-Verbindung hergestellt. Daher sind die folgenden beiden Befehle gleichwertig:

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

Ebenso sind die folgenden beiden Befehle zur Verbindung mit S3 gleichwertig:

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

Explizite Speicherversionen

DuckDB v1.2.0 hat die Option STORAGE_VERSION eingeführt, mit der die Speicherversion explizit angegeben werden kann. Damit können Sie sich für neuere, vorwärts-inkompatible Features entscheiden:

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

Diese Einstellung gibt die minimale DuckDB-Version an, die die Datenbankdatei lesen können sollte. Werden Datenbankdateien mit dieser Option geschrieben, können die resultierenden Dateien von älteren DuckDB-Versionen als der angegebenen nicht geöffnet werden. Sie können von der angegebenen Version und allen neueren DuckDB-Versionen gelesen werden.

Um eine Datenbank mit der neuesten Speicherversion zu initialisieren, verwenden Sie:

ATTACH 'file.db' (STORAGE_VERSION 'latest');

Weitere Details finden Sie auf der Seite „Speicher“.

Datenbankverschlüsselung

DuckDB unterstützt Datenbankverschlüsselung. Standardmäßig verwendet es AES-Verschlüsselung mit einer Schlüssellänge von 256 Bit im empfohlenen GCM-Modus. Die Verschlüsselung umfasst die Hauptdatenbankdatei, die Write-Ahead-Log-Datei (WAL) und sogar temporäre Dateien. Um sich an eine verschlüsselte Datenbank anzuhängen, verwenden Sie die ATTACH-Anweisung mit einem ENCRYPTION_KEY.

ATTACH 'encrypted.db' AS enc_db (ENCRYPTION_KEY 'quack_quack');

Zum Verschlüsseln von Daten kann DuckDB entweder die eingebaute Bibliothek mbedtls oder die OpenSSL-Bibliothek aus der httpfs-Extension verwenden. Beachten Sie, dass die OpenSSL-Varianten dank Hardwarebeschleunigung deutlich schneller sind; laden Sie daher httpfs für gute Verschlüsselungsperformance:

LOAD httpfs;
ATTACH 'encrypted.db' AS enc_db (ENCRYPTION_KEY 'quack_quack'); -- will be faster thanks to httpfs

Um den AES-Modus auf CBC oder CTR zu ändern, verwenden Sie die Option ENCRYPTION_CIPHER:

ATTACH 'encrypted.db' AS enc_db (ENCRYPTION_KEY 'quack_quack', ENCRYPTION_CIPHER 'CBC');
ATTACH 'encrypted.db' AS enc_db (ENCRYPTION_KEY 'quack_quack', ENCRYPTION_CIPHER 'CTR');

Datenbankverschlüsselung impliziert die Verwendung der Speicherversion 1.4.0 oder später.

Optionen

Null oder mehr Copy-Optionen können in Klammern nach der ATTACH-Anweisung angegeben werden. Parameterwerte können mit oder ohne einfache Anführungszeichen übergeben werden. Für Parameterwerte können beliebige Ausdrücke verwendet werden.

Name Beschreibung Typ Standardwert
READ_ONLY Die Datenbank im Nur-Lese-Modus anhängen. Verwenden Sie READ_WRITE (der Standard), um im Lese-/Schreibmodus anzuhängen. BOOLEAN false
COMPRESS Ob die Datenbank komprimiert ist. Nur für In-Memory-Datenbanken anwendbar. VARCHAR false
TYPE Der Dateityp (DUCKDB oder SQLITE) oder aus dem Eingabe-Stringliteral abgeleitet (MySQL, PostgreSQL). VARCHAR DUCKDB
DEFAULT_TABLE Die Tabelle, die abgefragt wird, wenn die angehängte Datenbank direkt über ihren Katalognamen referenziert wird (z. B. FROM ⟨db⟩). VARCHAR -
BLOCK_SIZE Die Blockgröße einer neuen Datenbankdatei. Muss eine Zweierpotenz sein und im Bereich [16384, 262144] liegen. Kann für vorhandene Dateien nicht gesetzt werden. UBIGINT 262144
ROW_GROUP_SIZE Die Row-Group-Größe einer neuen Datenbankdatei. UBIGINT 122880
STORAGE_VERSION Die verwendete Speicherversion. VARCHAR v1.0.0
ENCRYPTION_KEY Der Schlüssel zum Verschlüsseln der Datenbank. VARCHAR -
ENCRYPTION_CIPHER Die Chiffre zum Verschlüsseln der Datenbank (CBC, CTR oder GCM). VARCHAR -
RECOVERY_MODE Wiederherstellungsmodus der Datenbank. no_wal_writes deaktiviert WAL-Schreibvorgänge und verbessert die Performance zulasten der Crash-Wiederherstellung. VARCHAR -

DETACH

Die DETACH-Anweisung erlaubt es, zuvor angehängte Datenbankdateien zu schließen und zu lösen und dabei alle Sperren auf der Datenbankdatei freizugeben.

Beachten Sie, dass es nicht möglich ist, sich von der Standarddatenbank zu lösen: Wenn Sie das tun möchten, verwenden Sie die USE-Anweisung, um die Standarddatenbank auf eine andere zu ändern. Wenn Sie zum Beispiel mit einer persistenten Datenbank verbunden sind, können Sie zu einer In-Memory-Datenbank wechseln, indem Sie ausführen:

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

Warnung Das Schließen der Verbindung, z. B. der Aufruf der Funktion close() in Python, gibt die Sperren auf den Datenbankdateien nicht frei, weil die Dateihandles von der Hauptinstanz von DuckDB gehalten werden (im Fall von Python vom Modul duckdb).

DETACH-Syntax

Namensqualifizierung

Der vollständig qualifizierte Name von Katalogobjekten enthält den Katalog, das Schema und den Namen des Objekts. Zum Beispiel:

Die Datenbank new_db anhängen:

ATTACH 'new_db.db';

Das Schema my_schema in der Datenbank new_db anlegen:

CREATE SCHEMA new_db.my_schema;

Die Tabelle my_table im Schema my_schema anlegen:

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

Auf die Spalte col innerhalb der Tabelle my_table verweisen:

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

Beachten Sie, dass der vollständig qualifizierte Name oft nicht erforderlich ist. Ist ein Name nicht vollständig qualifiziert, sucht das System anhand des Katalog-Suchpfads, auf welche Einträge verwiesen werden soll. Der Standard-Katalog-Suchpfad umfasst den Systemkatalog, den temporären Katalog und die zunächst angehängte Datenbank zusammen mit dem Schema main.

Beachten Sie auch die Regeln zu Bezeichnern und insbesondere Datenbanknamen.

Standarddatenbank und -schema

Wird eine Tabelle ohne Qualifizierung angelegt, wird sie im Standardschema der Standarddatenbank angelegt. Die Standarddatenbank ist die Datenbank, die beim Erzeugen des Systems gestartet wird – und das Standardschema ist main.

Die Tabelle my_table in der Standarddatenbank anlegen:

CREATE TABLE my_table (col INTEGER);

Standarddatenbank und -schema ändern

Die Standarddatenbank und das Standardschema können mit dem Befehl USE geändert werden.

Das Standard-Datenbankschema auf new_db.main setzen:

USE new_db;

Das Standard-Datenbankschema auf new_db.my_schema setzen:

USE new_db.my_schema;

Konflikte auflösen

Bei nur einer Qualifizierung kann das System das entweder als Katalog oder als Schema interpretieren, solange es keine Konflikte gibt. Zum Beispiel:

ATTACH 'new_db.db';
CREATE SCHEMA my_schema;

Legt die Tabelle new_db.main.tbl an:

CREATE TABLE new_db.tbl (i INTEGER);

Legt die Tabelle default_db.my_schema.tbl an:

CREATE TABLE my_schema.tbl (i INTEGER);

Entsteht ein Konflikt (d. h. es gibt sowohl ein Schema als auch einen Katalog mit demselben Namen), verlangt das System, dass stattdessen ein vollständig qualifizierter Pfad verwendet wird:

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

Den Katalog-Suchpfad ändern

Der Katalog-Suchpfad kann über die Konfigurationsoption search_path angepasst werden, die eine kommagetrennte Liste von Werten verwendet, die auf dem Suchpfad liegen. Das folgende Beispiel zeigt die Suche in zwei Datenbanken:

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

Auf die Tabellen über ihren vollständig qualifizierten Namen verweisen:

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

Oder den Suchpfad setzen und auf die Tabellen über ihren Namen verweisen:

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

Transaktionssemantik

Beim Ausführen von Abfragen über mehrere Datenbanken öffnet das System separate Transaktionen pro Datenbank. Die Transaktionen werden standardmäßig lazy gestartet – wenn eine gegebene Datenbank zum ersten Mal in einer Abfrage referenziert wird, wird eine Transaktion für diese Datenbank gestartet. SET immediate_transaction_mode = true kann umgeschaltet werden, um dieses Verhalten zu ändern und Transaktionen in allen angehängten Datenbanken stattdessen eagerly zu starten.

Während mehrere Transaktionen gleichzeitig aktiv sein können, unterstützt das System das Schreiben in einer einzelnen Transaktion nur in eine einzige angehängte Datenbank. Versuchen Sie, in einer einzelnen Transaktion in mehrere angehängte Datenbanken zu schreiben, wird der folgende Fehler geworfen:

Terminal window
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.

Der Grund für diese Einschränkung ist, dass das System die Atomarität von Transaktionen über angehängte Datenbanken hinweg nicht aufrechterhält. Transaktionen sind nur innerhalb jeder Datenbankdatei atomar. Indem die globale Transaktion auf das Schreiben in nur eine Datenbankdatei beschränkt wird, bleiben die Atomaritätsgarantien erhalten.