12k
All articles

5 MariaDB-Features, die man kennen sollte

Wichtige MariaDB-Funktionen: Vektorsuche, systemversionierte und Application-Time-Tabellen, Speicher-Engine pro Tabelle sowie utf8mb4 als Standard in 11.8 LTS.

OpenReplay Team
OpenReplay Team
5 MariaDB-Features, die man kennen sollte

Die fünf folgenreichsten MariaDB-Features für ein Team, das MySQL 8.0 betreibt, sind die integrierte Vektorsuche, system-versionierte Tabellen, Application-Time-Perioden, die Wahl der Storage Engine pro Tabelle sowie utf8mb4 als Server-Standard mit UCA-14.0.0-Kollationen – eingeführt mit MariaDB 11.6 und weitergeführt in der LTS-Linie 11.8.

Wenn Sie in einer MySQL-8.0-Landschaft über einen Versionswechsel nachdenken, gehört MariaDB zu den Optionen, die einen Platz auf der Liste verdienen.

Im Folgenden geht es um jedes dieser Features im Einzelnen: was es leistet und welches SQL Sie dafür schreiben würden. Die Versionsangaben beziehen sich auf MariaDB 11.8 LTS und MariaDB 12.3 LTS – jene Releases, die die meisten Teams bei einem Neustart heute installieren würden.

Die wichtigsten Erkenntnisse

  • MariaDB liefert die Vektorähnlichkeitssuche direkt im Community-Server mit: eine VECTOR(N)-Spalte und ein VECTOR INDEX auf Basis eines modifizierten HNSW-Algorithmus – ohne jede zusätzliche Extension.
  • MariaDB nutzt den Vektorindex nur dann, wenn ORDER BY aus einem reinen Distanzaufruf besteht, der zur Metrik des Index passt, gefolgt von einem LIMIT; eine abweichende Distanzfunktion führt zum Full Table Scan.
  • WITH SYSTEM VERSIONING in Verbindung mit SELECT ... FOR SYSTEM_TIME AS OF liefert Point-in-Time-Abfragen ohne Audit-Trigger und ohne separate History-Tabelle.
  • PERIOD FOR deklariert die fachliche Gültigkeit einer Tabelle; deklariert man sowohl System Versioning als auch eine Application-Time-Periode, wird die Tabelle bitemporal.
  • Der Standardzeichensatz ist seit MariaDB 11.6 utf8mb4, die Kollationen basieren auf UCA 14.0.0, und 11.8 ist das erste Long-Term-Support-Release, das dies mitbringt.

Wie funktioniert Vektorsuche in MariaDB ohne Extension?

MariaDB speichert und durchsucht Embeddings im Community-Server selbst: eine VECTOR(N)-Spalte, ein VECTOR INDEX auf Basis eines modifizierten HNSW-Algorithmus sowie Distanzfunktionen für Cosinus- und euklidische Ähnlichkeit. Die Projektseite zu MariaDB Vector nennt 11.8 LTS als General Availability, und die Referenz zum VECTOR-Typ begrenzt eine Spalte auf 16.383 Dimensionen. Es wird nichts zusätzlich installiert, und es steht kein zweiter Datastore neben Ihren Zeilen, der irgendwann aus dem Tritt gerät.

CREATE TABLE support_articles (
  id         BIGINT UNSIGNED PRIMARY KEY,
  tenant_id  INT NOT NULL,
  body       TEXT,
  embedding  VECTOR(768) NOT NULL,
  VECTOR INDEX (embedding) M=8 DISTANCE=cosine
) ENGINE=InnoDB;

768 entspricht der Ausgabebreite mehrerer verbreiteter Open-Weight-Modelle für Satz-Embeddings; setzen Sie den Wert auf das, was Ihr Modell ausgibt. Zwei Einschränkungen lassen sich direkt aus diesem DDL ablesen. Die indizierte Spalte muss NOT NULL sein, und M akzeptiert Werte von 3 bis 200, wobei höhere Werte Genauigkeit gegen Indexgröße und Schreibgeschwindigkeit eintauschen – siehe die Referenz zu create-table-with-vectors. Die Projektseite nennt außerdem eine Obergrenze von einem Vektorindex pro Tabelle.

Der Server hält und durchsucht Vektoren; er erzeugt sie nicht. Das Array kommt also aus Ihrem Embedding-Modell und wird als Text übergeben:

INSERT INTO support_articles (id, tenant_id, body, embedding)
VALUES (1, 17, 'Resetting a device token',
        VEC_FromText('[0.021, -0.113, 0.447, ...]'));

Da die Embeddings in einer gewöhnlichen InnoDB-Tabelle liegen, werden eine WHERE-Klausel und ein Ähnlichkeits-Ranking als ein einziges transaktionales Statement ausgeführt. Ein danebengesetzter Vektordienst kann das nicht bieten: Eine Nearest-Neighbour-Suche auf die Zeilen eines einzelnen Mandanten einzugrenzen, benötigt weder einen Join über zwei Systeme hinweg noch eine Nachfilterung von Ergebnissen, für deren Abruf Sie bereits bezahlt haben.

SELECT id, body
FROM support_articles
WHERE tenant_id = 17
ORDER BY VEC_DISTANCE_COSINE(embedding, VEC_FromText('[...]'))
LIMIT 10;

Warum wird der Vektorindex übergangen?

Der Index kommt nur zum Einsatz, wenn die Abfrage nach einem schlichten Distanzaufruf sortiert, dabei die Metrik verwendet, für die der Index gebaut wurde, und die Zeilen mit einem LIMIT begrenzt. Fragen Sie einen mit Cosinus gebauten Index mit der euklidischen Funktion ab, stellt die Referenzdokumentation unmissverständlich klar, dass der Index nicht genutzt werden kann und die Abfrage zu einem Full Table Scan degradiert:

-- index above was built with DISTANCE=cosine
SELECT id, body
FROM support_articles
WHERE tenant_id = 17
ORDER BY VEC_DISTANCE_EUCLIDEAN(embedding, VEC_FromText('[...]'))
LIMIT 10;

Das generische VEC_DISTANCE umgeht diese Falle, indem es sich je nach zugrunde liegendem Index zu euklidisch oder Cosinus auflöst, wie in der Vector-Übersicht beschrieben; diese beiden Metriken sind die einzigen unterstützten. Wenn der Recall bei kleinen LIMIT-Werten eine Rolle spielt, legt mhnsw_ef_search fest, wie viele Ergebniskandidaten die Indexsuche im Spiel hält: standardmäßig 20, einstellbar von 1 bis 10000. Die Suche sucht nie nach weniger als diesem Wert, selbst wenn LIMIT weniger anfordert – ein höherer Wert erkauft also Qualität mit Suchzeit.

Zum Vergleich: MySQL 8.0 kennt keinen VECTOR-Typ; ein Vektortyp kam mit der 9.x-Serie, und indexgestützte Vektorsuche ist als HeatWave-Funktion dokumentiert, wobei HeatWave GenAI die Indizes selbst erstellt – für Vektorspalten, die häufig abgefragt werden. In PostgreSQL übernimmt dieselbe Aufgabe pgvector, eine Extension, die Sie installieren und aktivieren müssen.

System-versionierte Tabellen: Wie fragt man den vergangenen Dienstag ab?

Eine system-versionierte Tabelle behält jede überschriebene Version einer Zeile in der Tabelle selbst, sodass ein Point-in-Time-Read eine Klausel in einem normalen SELECT ist statt eines Audit-Triggers, der in eine History-Tabelle schreibt, die Sie pflegen müssen. Weil die alten Versionen bei den aktuellen bleiben, können Sie die Tabelle so lesen, wie sie zu jedem beliebigen vergangenen Zeitpunkt aussah, Änderungen nachvollziehen und zwei Zeitpunkte nebeneinanderstellen.

CREATE TABLE subscription (
  account_id  BIGINT PRIMARY KEY,
  plan        VARCHAR(32),
  seats       INT
) WITH SYSTEM VERSIONING;

SELECT account_id, plan, seats
FROM subscription
FOR SYSTEM_TIME AS OF TIMESTAMP '2025-11-04 09:00:00'
WHERE account_id = 4021;

Das ist bereits das gesamte Feature. Historie wird zurückgegeben, sobald FOR SYSTEM_TIME angegeben ist, und die Referenz zu system-versionierten Tabellen dokumentiert AS OF, BETWEEN, FROM ... TO und ALL als Abfrageformen. Die explizite DDL-Form deklariert GENERATED ALWAYS AS ROW START- und ROW END-Spalten mit einer PERIOD FOR SYSTEM_TIME; die obige Kurzform speichert dieselbe Information hinter den Pseudospalten ROW_START und ROW_END. Unter InnoDB können Sie zusätzlich nach Transaktion versionieren – mit BIGINT UNSIGNED-Spalten für Row-Start und Row-End – und mit FOR SYSTEM_TIME AS OF TRANSACTION lesen. MariaDBs eigene Dokumentation der Unterschiede führt temporale Datentabellen unter den Fähigkeiten auf, für die MySQL kein Gegenstück hat.

Application-Time-Perioden für fachliche Gültigkeit

System Versioning hält fest, wann die Datenbank etwas erfahren hat; eine Application-Time-Periode hält fest, wann der Sachverhalt tatsächlich zutraf. Eine Application-Time-Periode ist eine Zeitspanne, die durch zwei temporale Spalten gleichen Typs und gleicher Breite abgesteckt wird, und sie versioniert Ihre Daten auf Anwendungs- statt auf Serverebene. Ein Preis mit Gültigkeitsfenster ist der klassische Anwendungsfall.

CREATE TABLE price_list (
  sku        VARCHAR(32),
  price      DECIMAL(10,2),
  valid_from DATE,
  valid_to   DATE,
  PERIOD FOR validity(valid_from, valid_to),
  UNIQUE (sku, validity WITHOUT OVERLAPS)
);

UPDATE price_list FOR PORTION OF validity
  FROM '2026-01-01' TO '2026-04-01'
  SET price = 18.00
WHERE sku = 'KB-114';

Die Deklaration einer Periode erzwingt für beide Spalten NOT NULL und ergänzt stillschweigend eine Prüfung, dass der erste Wert vor dem zweiten liegt. WITHOUT OVERLAPS in einem Primär- oder Unique-Key weist anschließend Zeilen zurück, deren Perioden kollidieren. Diese Klausel ist ab MariaDB 10.5.3 dokumentiert; die Perioden selbst, FOR PORTION eingeschlossen, kamen früher, nämlich mit MariaDB 10.4.3. Deklarieren Sie an einer Tabelle sowohl eine Periode als auch System Versioning, erhalten Sie eine bitemporale Tabelle, die beide Arten der Versionierung gleichzeitig auf denselben Zeilen betreibt. Genau das unterscheidet einen Preis, der am Dienstag falsch war, von einem, der lediglich verspätet erfasst wurde.

Lässt sich die Storage Engine pro Tabelle wählen?

MariaDB legt die Storage Engine pro Tabelle fest, sodass transaktionale Tabellen auf InnoDB bleiben, während andere Tabellen desselben Schemas etwas anderes verwenden. Über den Standardumfang hinaus nennt die Dokumentation der Unterschiede ColumnStore für verteilte analytische Verarbeitung, MyRocks, die S3-Engine für Cloud-Archivierung, Aria als MyISAM-Ersatz sowie CONNECT, SEQUENCE, Spider, SphinxSE, FederatedX und OQGRAPH.

CREATE TABLE event_archive (
  id   BIGINT PRIMARY KEY,
  body TEXT
) ENGINE=Aria;

Einige davon werden als separate Plugin-Pakete ausgeliefert und sind nicht in den Server einkompiliert. Prüfen Sie daher die Dokumentation der jeweiligen Engine für das Release, das Sie installieren, bevor Sie davon ausgehen, dass eine bloße ENGINE=-Klausel genügt.

utf8mb4 als Standard und neuere Kollationen

MariaDB hat den Standardzeichensatz des Servers in 11.6 von latin1 auf utf8mb4 umgestellt und die Kollationen dabei auf UCA 14.0.0 aktualisiert. Wenn Sie zwischen Long-Term-Support-Releases upgraden, landen beide Änderungen in 11.8, und die Ankündigung des 11.8-LTS-Release vom 8. Juni 2025 führt sie als Teil dieses Releases auf. Damit verabschiedet sich MariaDB von einem eigenen Standard, der älter ist als Emojis – es ist nicht der Punkt, an dem MariaDB MySQL beim Standard selbst überholt. Der Teil, der das Upgrade überdauert, ist die Kollationsseite: Sortierreihenfolge und Vergleiche folgen einem neueren Unicode-Kollationsalgorithmus als bei MySQL. Ein Gegencheck der Sortierergebnisse lohnt sich also, wenn Sie Ausgaben beider Systeme vergleichen.

MariaDB-Features und die Releases, in denen sie erschienen sind

FeatureWas Sie damit tun könnenVerfügbarkeit in MariaDB
VektorsucheEmbeddings in VECTOR(N) speichern, mit VECTOR INDEX indizieren, in einem Statement filtern und rankenVECTOR-Typ in 11.7.1 ergänzt, GA in 11.8 LTS, vorhanden in 12.3 LTS
System-versionierte TabellenEine Tabelle so lesen, wie sie zu einem vergangenen Zeitpunkt oder in einer vergangenen Transaktion aussahVerfügbar in den LTS-Releases 11.8 und 12.3
Application-Time-PeriodenFachliche Gültigkeitsfenster modellieren und einen Ausschnitt davon aktualisierenPerioden und FOR PORTION ab 10.4.3, WITHOUT OVERLAPS ab 10.5.3, in aktuellen LTS-Releases vorhanden
Bitemporale TabellenIn einer Tabelle sowohl nach Systemzeit als auch nach fachlicher Zeit versionierenIn aktuellen LTS-Releases vorhanden
utf8mb4-Standard, UCA 14.0.0Unicode ohne Änderung an der ServerkonfigurationStandard ab 11.6, erstes LTS damit ist 11.8

Ein Upgrade-Hinweis, den man mitnehmen sollte: Der 11.8-Release-Beitrag hält fest, dass die Erweiterung des TIMESTAMP-Bereichs keine Datenkonvertierung erforderte, sofern keine system-versionierten Tabellen im Einsatz sind – und nennt genau diese Tabellen als die eine bekannte Komplikation, weil sich die interne Timestamp-Darstellung geändert hat.

Greifen Sie sich von diesen fünf Features dasjenige heraus, das zu einem Problem passt, das Sie bereits haben. Geht es um Audit-Historie, erstellen Sie eine Wegwerf-Tabelle WITH SYSTEM VERSIONING, ändern Sie eine Zeile zweimal und lesen Sie sie mit FOR SYSTEM_TIME AS OF zurück; Sie wissen dann binnen Minuten, ob das den Trigger ersetzt, den Sie bisher gepflegt haben.

FAQs

Kann ich System Versioning für eine bereits bestehende Tabelle aktivieren?

Ja. ALTER TABLE t ADD SYSTEM VERSIONING aktiviert es an einer bestehenden Tabelle, und ALTER TABLE t DROP SYSTEM VERSIONING entfernt es, wodurch die gesamte Historie gelöscht wird. Beide Varianten bauen die Tabelle neu auf und können bei großen Tabellen entsprechend langsam sein. Spätere Schemaänderungen hängen von der Einstellung system_versioning_alter_history ab: Bei ERROR schlägt das Ändern einer versionierten Tabelle fehl; bei KEEP gelingt das ALTER, historische Abfragen zeigen dann jedoch die neue Tabellenstruktur.

Wie verhindere ich, dass eine system-versionierte Tabelle unbegrenzt wächst?

Es gibt drei dokumentierte Möglichkeiten: Bereinigen mit dem Statement DELETE HISTORY, das das Privileg DELETE HISTORY voraussetzt; Partitionierung nach SYSTEM_TIME und Löschen historischer Partitionen, wobei weder die aktuelle Partition noch die einzige historische Partition gelöscht werden kann; oder System Versioning entfernen und erneut hinzufügen, was die Historie um den Preis eines Tabellen-Rebuilds leert. TRUNCATE TABLE hilft ebenfalls nicht: Der Server verweigert es mit Fehler 4137, damit die Historie erhalten bleibt.

Kann ich in MariaDB eine Vektorspalte sowohl für Cosinus- als auch für euklidische Distanz indizieren?

Nein. Ein Vektorindex wird für genau eine Distanzfunktion gebaut, gültige Werte sind cosine und euclidean (Standard), und eine Suche mit einer anderen Distanzfunktion kann diesen Index nicht nutzen. MariaDB erlaubt zudem nur einen Vektorindex pro Tabelle. Eine zweite Metrik zu bedienen bedeutet also, den Index zu löschen und mit einem anderen DISTANCE-Wert neu aufzubauen, statt einen weiteren daneben anzulegen.

Wirkt sich der utf8mb4-Standard in MariaDB 11.8 auf die Replikation zu älteren Servern aus?

Ja. Der Standardzeichensatz wurde in MariaDB 11.6 von latin1 auf utf8mb4 und die Standardkollation auf utf8mb4_uca1400_ai_ci umgestellt; 11.8 ist das erste Long-Term-Support-Release mit dieser Änderung. Ältere Releases kennen diese Kollation nicht, sodass ein MariaDB-11.8-Primary nicht zu einem MariaDB-10.6-Replica replizieren kann, sofern Sie den Server nicht auf die alten Standardwerte zurücksetzen.

Understand every bug

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — self-hosted, with full data ownership.

Star on GitHub

We use cookies to improve your experience. By using our site, you accept cookies.