MySQL-Erweiterung
Die mysql-Erweiterung ermöglicht DuckDB, Daten direkt aus einer laufenden MySQL-Instanz zu lesen und in sie zu schreiben. Die Daten können direkt aus der zugrunde liegenden MySQL-Datenbank abgefragt werden. Daten können aus MySQL-Tabellen in DuckDB-Tabellen geladen werden oder umgekehrt.
Installation und Laden
Um die mysql-Erweiterung zu installieren, führen Sie aus:
INSTALL mysql;Die Erweiterung wird beim ersten Gebrauch automatisch geladen. Wenn Sie sie lieber manuell laden möchten, führen Sie aus:
LOAD mysql;Daten aus MySQL lesen
Um eine MySQL-Datenbank für DuckDB zugänglich zu machen, verwenden Sie den Befehl ATTACH mit dem Typ mysql oder mysql_scanner:
ATTACH 'host=localhost user=root port=0 database=mysql' AS mysqldb (TYPE mysql);USE mysqldb;Konfiguration
Die Verbindungszeichenkette bestimmt die Parameter für die Verbindung zu MySQL als Menge von key=value-Paaren. Nicht angegebene Optionen werden durch ihre Standardwerte gemäß der folgenden Tabelle ersetzt. Verbindungsinformationen können auch über Umgebungsvariablen angegeben werden. Wird eine Option nicht explizit gesetzt, versucht die MySQL-Erweiterung, sie aus einer Umgebungsvariable zu lesen.
| Setting | Standard | Umgebungsvariable |
|---|---|---|
| database | NULL | MYSQL_DATABASE |
| host | localhost | MYSQL_HOST |
| password | MYSQL_PWD | |
| port | 0 | MYSQL_TCP_PORT |
| socket | NULL | MYSQL_UNIX_PORT |
| user | aktueller Benutzer | MYSQL_USER |
| ssl_mode | preferred | |
| ssl_ca | ||
| ssl_capath | ||
| ssl_cert | ||
| ssl_cipher | ||
| ssl_crl | ||
| ssl_crlpath | ||
| ssl_key |
Konfiguration über Secrets
MySQL-Verbindungsinformationen können auch über Secrets angegeben werden. Die folgende Syntax kann verwendet werden, um ein Secret zu erstellen.
CREATE SECRET ( TYPE mysql, HOST '127.0.0.1', PORT 0, DATABASE mysql, USER 'mysql', PASSWORD '');Die Informationen aus dem Secret werden verwendet, wenn ATTACH aufgerufen wird. Wir können die Verbindungszeichenkette leer lassen, um alle im Secret gespeicherten Informationen zu verwenden.
ATTACH '' AS mysql_db (TYPE mysql);Wir können die Verbindungszeichenkette verwenden, um einzelne Optionen zu überschreiben. Um beispielsweise eine andere Datenbank zu verbinden und dabei dieselben Anmeldedaten zu verwenden, können wir nur den Datenbanknamen wie folgt überschreiben.
ATTACH 'database=my_other_db' AS mysql_db (TYPE mysql);Standardmäßig sind erstellte Secrets temporär. Secrets können mit dem Befehl CREATE PERSISTENT SECRET dauerhaft gespeichert werden. Persistente Secrets können sitzungsübergreifend verwendet werden.
Mehrere Secrets verwalten
Benannte Secrets können verwendet werden, um Verbindungen zu mehreren MySQL-Datenbankinstanzen zu verwalten. Secrets können bei der Erstellung einen Namen erhalten.
CREATE SECRET mysql_secret_one ( TYPE mysql, HOST '127.0.0.1', PORT 0, DATABASE mysql, USER 'mysql', PASSWORD '');Das Secret kann dann mit dem Parameter SECRET in ATTACH explizit referenziert werden.
ATTACH '' AS mysql_db_one (TYPE mysql, SECRET mysql_secret_one);SSL-Verbindungen
Die ssl-Verbindungsparameter können für SSL-Verbindungen verwendet werden. Nachfolgend eine Beschreibung der unterstützten Parameter.
| Setting | Beschreibung |
|---|---|
| ssl_mode | Der Sicherheitszustand für die Verbindung zum Server: disabled, required, verify_ca, verify_identity oder preferred (Standard: preferred) |
| ssl_ca | Der Pfadname der Certificate-Authority-(CA-)Zertifikatsdatei |
| ssl_capath | Der Pfadname des Verzeichnisses, das vertrauenswürdige SSL-CA-Zertifikatsdateien enthält |
| ssl_cert | Der Pfadname der öffentlichen Client-Schlüsselzertifikatsdatei |
| ssl_cipher | Die Liste zulässiger Chiffren für die SSL-Verschlüsselung |
| ssl_crl | Der Pfadname der Datei mit Zertifikatssperrlisten |
| ssl_crlpath | Der Pfadname des Verzeichnisses, das Dateien mit Zertifikatssperrlisten enthält |
| ssl_key | Der Pfadname der privaten Client-Schlüsseldatei |
MySQL-Tabellen lesen
Die Tabellen in der MySQL-Datenbank können gelesen werden, als wären sie normale DuckDB-Tabellen, die zugrunde liegenden Daten werden jedoch zur Abfragezeit direkt aus MySQL gelesen.
SHOW ALL TABLES;| name |
|---|
| signed_integers |
SELECT * FROM signed_integers;| t | s | m | i | b |
|---|---|---|---|---|
| -128 | -32768 | -8388608 | -2147483648 | -9223372036854775808 |
| 127 | 32767 | 8388607 | 2147483647 | 9223372036854775807 |
| NULL | NULL | NULL | NULL | NULL |
Es kann wünschenswert sein, eine Kopie der MySQL-Datenbanken in DuckDB anzulegen, damit das System die Tabellen nicht fortlaufend aus MySQL neu liest, insbesondere bei großen Tabellen.
Daten können mit Standard-SQL von MySQL nach DuckDB kopiert werden, zum Beispiel:
CREATE TABLE duckdb_table AS FROM mysqlscanner.mysql_table;Daten nach MySQL schreiben
Zusätzlich zum Lesen von Daten aus MySQL können Sie Tabellen erstellen, Daten in MySQL laden und weitere Änderungen an einer MySQL-Datenbank mit Standard-SQL-Abfragen vornehmen.
So können Sie DuckDB beispielsweise verwenden, um in einer MySQL-Datenbank gespeicherte Daten nach Parquet zu exportieren oder Daten aus einer Parquet-Datei nach MySQL zu lesen.
Nachfolgend ein kurzes Beispiel, wie Sie eine neue Tabelle in MySQL erstellen und Daten darin laden.
ATTACH 'host=localhost user=root port=0 database=mysqlscanner' AS mysql_db (TYPE mysql);CREATE TABLE mysql_db.tbl (id INTEGER, name VARCHAR);INSERT INTO mysql_db.tbl VALUES (42, 'DuckDB');Viele Operationen auf MySQL-Tabellen werden unterstützt. All diese Operationen ändern die MySQL-Datenbank direkt, und das Ergebnis nachfolgender Operationen kann dann mit MySQL gelesen werden.
Falls keine Änderungen gewünscht sind, kann ATTACH mit der Eigenschaft READ_ONLY ausgeführt werden, die Änderungen an der zugrunde liegenden Datenbank verhindert. Zum Beispiel:
ATTACH 'host=localhost user=root port=0 database=mysqlscanner' AS mysql_db (TYPE mysql, READ_ONLY);Unterstützte Operationen
Nachfolgend eine Liste der unterstützten Operationen.
CREATE TABLE
CREATE TABLE mysql_db.tbl (id INTEGER, name VARCHAR);INSERT INTO
INSERT INTO mysql_db.tbl VALUES (42, 'DuckDB');SELECT
SELECT * FROM mysql_db.tbl;| id | name |
|---|---|
| 42 | DuckDB |
COPY
COPY mysql_db.tbl TO 'data.parquet';COPY mysql_db.tbl FROM 'data.parquet';Sie können auch eine vollständige Kopie der Datenbank mit der Anweisung COPY FROM DATABASE erstellen:
COPY FROM DATABASE mysql_db TO my_duckdb_db;UPDATE
UPDATE mysql_db.tblSET name = 'Woohoo'WHERE id = 42;DELETE
DELETE FROM mysql_db.tblWHERE id = 42;ALTER TABLE
ALTER TABLE mysql_db.tblADD COLUMN k INTEGER;DROP TABLE
DROP TABLE mysql_db.tbl;CREATE VIEW
CREATE VIEW mysql_db.v1 AS SELECT 42;CREATE SCHEMA und DROP SCHEMA
CREATE SCHEMA mysql_db.s1;CREATE TABLE mysql_db.s1.integers (i INTEGER);INSERT INTO mysql_db.s1.integers VALUES (42);SELECT * FROM mysql_db.s1.integers;| i |
|---|
| 42 |
DROP SCHEMA mysql_db.s1;Transaktionen
CREATE TABLE mysql_db.tmp (i INTEGER);BEGIN;INSERT INTO mysql_db.tmp VALUES (42);SELECT * FROM mysql_db.tmp;Das liefert:
| i |
|---|
| 42 |
ROLLBACK;SELECT * FROM mysql_db.tmp;Das liefert eine leere Tabelle.
Die DDL-Anweisungen sind in MySQL nicht transaktional.
SQL-Abfragen in MySQL ausführen
Die Tabellenfunktion mysql_query
Die Tabellenfunktion mysql_query ermöglicht es, beliebige Leseabfragen in einer angehängten Datenbank auszuführen. mysql_query nimmt den Namen der angehängten MySQL-Datenbank, in der die Abfrage ausgeführt werden soll, sowie die auszuführende SQL-Abfrage entgegen. Das Ergebnis der Abfrage wird zurückgegeben. Einfache Anführungszeichen in Zeichenketten werden durch Verdopplung des einfachen Anführungszeichens escaped.
mysql_query(attached_database::VARCHAR, query::VARCHAR)Zum Beispiel:
ATTACH 'host=localhost database=mysql' AS mysqldb (TYPE mysql);SELECT * FROM mysql_query('mysqldb', 'SELECT * FROM cars LIMIT 3');Die Funktion mysql_execute
Die Funktion mysql_execute ermöglicht das Ausführen beliebiger Abfragen in MySQL, einschließlich Anweisungen, die das Schema und den Inhalt der Datenbank aktualisieren.
ATTACH 'host=localhost database=mysql' AS mysqldb (TYPE mysql);CALL mysql_execute('mysqldb', 'CREATE TABLE my_table (i INTEGER)');Einstellungen
| Name | Beschreibung | Standard |
|---|---|---|
mysql_bit1_as_boolean |
Ob BIT(1)-Spalten in BOOLEAN umgewandelt werden sollen |
true |
mysql_debug_show_queries |
DEBUG-EINSTELLUNG: alle an MySQL gesendeten Abfragen auf stdout ausgeben | false |
mysql_enable_filter_pushdown |
Ob Filter-Pushdown verwendet werden soll (ohne Prädikatanalyse) | true |
mysql_enable_transactions |
Ob START TRANSACTION / COMMIT / ROLLBACK auf MySQL-Verbindungen ausgeführt werden soll |
true |
mysql_incomplete_dates_as_nulls |
Ob DATEs mit Monat oder Tag null als NULLs zurückgegeben werden sollen |
false |
mysql_pool_acquire_mode |
Wie Verbindungen aus dem Pool bezogen werden: force (immer verbinden, Pool-Limit ignorieren), wait (blockieren, bis eine verfügbar ist) oder try (sofort fehlschlagen, wenn keine verfügbar ist) |
force |
mysql_pool_connection_idle_timeout_millis |
Maximale Zeit in Millisekunden, die eine Verbindung idle im Cache bleiben kann, bevor sie geschlossen wird | 60000 |
mysql_pool_connection_max_lifetime_millis |
Maximales Alter in Millisekunden einer gepoolten Verbindung seit dem ersten Öffnen; bei Überschreitung wird die Verbindung geschlossen, statt in den Cache zurückgegeben zu werden (0 deaktiviert dies) |
0 |
mysql_pool_enable_reaper_thread |
Ob ein eigener Thread laufen soll, der den Pool periodisch prüft und abgelaufene Verbindungen entfernt | true |
mysql_pool_enable_thread_local_cache |
Thread-lokales Verbindungs-Caching für schnellere Wiederverwendung derselben Verbindung im selben Thread aktivieren | false |
mysql_pool_size |
Maximale Anzahl von Verbindungen pro MySQL-Katalog | automatisch (basierend auf der CPU-Anzahl) |
mysql_pool_wait_timeout_millis |
Timeout in Millisekunden beim Warten auf eine Verbindung aus dem Pool | 30000 |
mysql_session_time_zone |
Sitzungszeitzone, die für neu geöffnete Verbindungen zum MySQL-Server gesetzt wird | '' |
mysql_time_as_time |
Ob MySQL-TIME-Spalten in DuckDB-TIME umgewandelt werden sollen |
false |
mysql_tinyint1_as_boolean |
Ob TINYINT(1)-Spalten in BOOLEAN umgewandelt werden sollen |
true |
Schema-Cache
Um Schema-Daten nicht fortlaufend aus MySQL holen zu müssen, hält DuckDB Schema-Informationen – etwa Tabellennamen, ihre Spalten usw. – im Cache. Werden Schema-Änderungen über eine andere Verbindung zur MySQL-Instanz vorgenommen, etwa indem einer Tabelle neue Spalten hinzugefügt werden, können die gecachten Schema-Informationen veraltet sein. In diesem Fall kann die Funktion mysql_clear_cache ausgeführt werden, um die internen Caches zu leeren.
CALL mysql_clear_cache();