MySQL/MariaDB unter Linux (Debian)

Zuletzt aktualisiert am 2. Mai 2026 von Lars

MySQL/MariaDB. Wichtiges zum Einstieg findest du in diesem Artikel.

Beachte bitte, dass dieser Artikel eher eine Notiz meiner Erfahrungen ist als ein Tutorial.

Installation MySQL/MariaDB

System auf den neuesten Stand bringen

$ sudo apt update && sudo apt upgrade -y

Eigentliche Installation MySQL/MariaDB

$ sudo apt install -y mysql-server

Falls der Fehler "Fehler: Für Paket »mysql-server« existiert kein Installationskandidat." erscheint (häufig auf Debian-basierenden Distributionen), bietet es sich an, MariaDB zu verwenden.

$ sudo apt install -y mariadb-server

Unterschied MySQL und MariaDB

Ursprung und Entwicklung

  • MySQL: Eines der bekanntesten Open-Source-Datenbanksysteme, 1995 entwickelt. Wurde 2010 von Oracle übernommen.
  • MariaDB: 2009 als "Abspaltung" (Fork) von MySQL gegründet, um eine unabhängige, community-gesteuerte Alternative zu bieten. Entwickelt von den ursprünglichen MySQL-Machern.

Kompatibilität

  • MariaDB ist weitgehend kompatibel zu MySQL. Das bedeutet: Die meisten Befehle, Skripte und Anwendungen, die für MySQL geschrieben wurden, funktionieren auch mit MariaDB. Bei komplexen Projekten oder speziellen Funktionen kann es kleine Unterschiede geben.

Performance und Funktionen

  • MariaDB gilt oft als schneller und effizienter, besonders bei grossen Datenmengen. Es bietet zusätzliche Speicher-Engines (z. B. Aria) und Optimierungen.
  • MySQL ist stabil und bewährt, aber einige Funktionen (z. B. bestimmte Replikationsmethoden) sind in MariaDB weiterentwickelt.

Lizenz und Support

Beide sind Open Source, aber:

  • MySQL wird von Oracle verwaltet. Es gibt eine kostenlose Community-Version und eine kostenpflichtige Enterprise-Version mit Support.
  • MariaDB bleibt komplett kostenlos und wird von der Community und der MariaDB Foundation unterstützt. Es gibt auch kommerzielle Support-Angebote von Drittanbietern.

Grundkonfiguration vornehmen

$ sudo mysql_secure_installation

Es kann sein, dass du die folgende Meldung erhältst:

sudo: mysql_secure_installation: Befehl nicht gefunden

Bei neueren MariaDB-Versionen kann mysql_secure_installation Probleme machen, weil der root-Login über den unix_socket-Plugin läuft. In dem Fall funktioniert das direkt über mariadb.

Das bedeutet: Bei MariaDB auf neueren Systemen meldet man sich als Administrator normalerweise nicht mit einem Passwort an, sondern das System prüft automatisch, ob man als "root"-Benutzer des Betriebssystems angemeldet ist – ähnlich wie ein Hausschlüssel statt einer PIN. Das Einrichtungsskript mysql_secure_installation kommt damit manchmal nicht zurecht und schlägt fehl. Deshalb öffnet man die Datenbank in diesem Fall einfach direkt mit dem Befehl sudo mariadb und nimmt die Einstellungen manuell vor.

$ sudo mariadb

Jetzt kopierst du das Folgende in MariaDB. Pass vorher das Passwort der DB noch an.

-- Root-Passwort setzen (nativen Plugin erzwingen)
ALTER USER 'root'@'localhost' IDENTIFIED VIA mysql_native_password USING PASSWORD('DeinneuesDatenbankPasswort');

-- Anonyme Benutzer entfernen
DELETE FROM mysql.user WHERE User=''

-- Remote root-Login deaktivieren
DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1')

-- Test-Datenbank entfernen
DROP DATABASE IF EXISTS test;
DELETE FROM mysql.db WHERE Db='test' OR Db='test\_%'

-- Berechtigungen neu laden
FLUSH PRIVILEGES;

EXIT;

MySQL/MariaDB Befehle

Kommandos schliesst man mit einem Semikolon  ab.

MySQL/MariaDB starten

$ mysql

bzw.

$ mysql -u root -p

Vorhandene Datenbanken anzeigen

mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| test |
+--------------------+

Eine neue Datenbank erstellen

mysql> create database adressen;

Eine bestimmte Datenbank zur weiteren Bearbeitung verwenden

mysql> use adressen;

Eine Tabelle in der aktuell gewählten Datenbank erstellen

mysql> create table Adressen (name varchar(40), vorname varchar(40));

Tabellen in der aktuell gewählten Datenbank anzeigen

mysql> show tables;
+--------------------+
| Tables_in_adressen |
+--------------------+
| adressen           |
| vorname            |
+--------------------+

Eine Tabelle in der aktuell gewählten Datenbank löschen

mysql> drop table test;

Daten in eine Tabelle einfügen

mysql> INSERT INTO Adressen(Name, Vorname) VALUES("Lars", "Schlageter");

Inhalt einer Tabelle anzeigen

mysql> select * from adressen;
+-------+------------+
| name  | vorname    |
+-------+------------+
| Lars  | Schlageter |
| James | Kirk       |
| Helen | Mustermann |
+-------+------------+

Struktur einer Tabelle anzeigen

mysql> show columns from temperature;
+-------+-----------+------+-----+---------------------+----------------+
| Field | Type      | Null | Key | Default             | Extra          |
+-------+-----------+------+-----+---------------------+----------------+
| id    | int(11)   | NO   | PRI | NULL                | auto_increment |
| ts    | timestamp | YES  |     | current_timestamp() |                |
| value | float     | NO   |     | NULL                |                |
+-------+-----------+------+-----+---------------------+----------------+

MySQL Datentypen

char(m)Zeichenkette mit fester Länge mit max. 255 Zeichen
varchar(m)Zeichenkette variabler Länge mit max. 255 Zeichen
textText variabler Länge, max. 65535 Zeichen
longtextText variabler Länge, max. 4.2 GB
intGanze Zahl
float(m,d)Fliesskommazahl, m = Anzahl Stellen, d = Anz. Dezimalstellen
double(m,d)Fliesskommzahl mit doppelter Genauigkeit, m = Anzahl Stellen, d = Anz. Dezimalstellen
dezimal(m,d)Fliesskommazahl als Zeichenkette
yearJahr
dateDatum in Form 2016-10-20
timeZeit in Form 23:12:30
timestampDatum und Uhrzeit kombiniert in Form 2026-02-27 17:10:09, Wertebereich 1970-01-01 bis 2038-01-19

Hinweis: Es gibt auch den Typ datetime mit demselben Format, aber einem grösseren Wertebereich (1000-01-01 bis 9999-12-31) und ohne automatische Zeitzonenkonvertierung.

Autoinkrement

Häufig wird das Attribut "Autoinkrement" benötigt. Ein Wertfeld mit diesem Attribut versieht jede neue Spalte mit einem fortlaufenden neuen Wert.

CREATE TABLE kunden (
id INT AUTO_INCREMENT NOT NULL PRIMARY KEY, name VARCHAR(50)
);

Primary Key

Das Attribut "Primary Key" gibt an, dass das damit versehene Feld ein eindeutiger Schlüssel ist, also nur einmalig vorkommt.

Not Null

Das Attribut "Not Null" gibt an, dass das damit versehene Feld nicht den Wert Null annahmen darf.

Constraints

CONSTRAINTS in MySQL (und anderen Datenbanken) sind Regeln, die festlegen, welche Werte in einer Tabellenspalte erlaubt sind. Sie helfen dabei, die Datenintegrität sicherzustellen, und sorgen beispielsweise dafür, dass keine ungültigen oder widersprüchlichen Daten gespeichert werden.

Ein häufiges Einsatzgebiet ist die Definition von Beziehungen zwischen mehreren Tabellen, etwa über sogenannte FOREIGN-KEY-Constraints. Diese stellen sicher, dass eine Spalte nur Werte enthalten darf, die auch in einer anderen Tabelle vorhanden sind.

Jeder Constraint kann einen eigenen Namen erhalten. Wenn man keinen angibt, vergibt MySQL automatisch einen. Besonders bei FOREIGN-KEY-Constraints ist ein benannter Constraint hilfreich, wenn man ihn später ändern oder löschen möchte.

Wird ein FOREIGN KEY gesetzt, dann muss die referenzierte Spalte in der Zieltabelle entweder ein PRIMARY KEY oder über einen UNIQUE-Index eindeutig sein.

Man gibt sie entweder direkt beim Erstellen der Tabelle an oder wendet sie nachträglich mit dem ALTER TABLE Statement an.

Wichtige Constraints sind:

  • NOT NULL - Darf nicht leer sein
  • UNIQUE - Muss eindeutig sein
  • PRIMARY KEY - Muss eindeutig sein und existiert nur einmal pro Tabelle
  • FOREIGN KEY - "Fremd"-Key in der eigenen Tabelle, der auf einen Primary Key einer anderen Tabelle verweist
  • CHECK  - Gibt Wertebereich für eine Spalte an Beispiel aus http://www.w3schools.com/sql/sql_check.asp
CREATE TABLE Persons
(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255),
CHECK (P_Id>0)
)
CREATE TABLE Persons
(
P_Id int NOT NULL,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255) DEFAULT 'Sandnes'
)

Constraints sind auch im Zusammenhang mit Verknüpfungen sinnvoll.

Alter table person add constraint foreign key (plz) references ort (plz) on delete cascade;
delete from ort where plz = 8000;

Mehr unter Fremdschlüssel-Beziehungen

Natürlich gibt es zu diesem Thema bereits viele Artikel im Netz. Beim Ausprobieren fehlten mir jedoch oft entscheidende Hinweise. In vielen Beispielen wird das CONSTRAINT direkt innerhalb der CREATE TABLE-Anweisung erstellt. Wenn die Tabelle aber bereits existiert oder ein Fehler auftritt, wird das CONSTRAINT nicht angelegt. Ich empfehle dir daher, CONSTRAINTS bevorzugt über eine ALTER TABLE-Anweisung zu definieren..

Beispiel - Beziehungen definieren

Ich selbst arbeite selten direkt mit SQL-Syntax, sondern nutze in der Regel phpMyAdmin, um meine Datenbank über die Oberfläche zusammenzuklicken. Das Ergebnis lässt sich anschliessend als SQL-Syntax exportieren. Hier eine vereinfachte, aber funktionierende Variante:

Schritt 1: Tabelle "name" erstellen

CREATE TABLE IF NOT EXISTS `name` (
`adrnr` int(11) PRIMARY KEY AUTO_INCREMENT NOT NULL,
`vorname` varchar(50) DEFAULT NULL,
`nachname` varchar(50) DEFAULT NULL,
`plz` varchar(4) DEFAULT NULL
);

Dies ist eine einfache Adresstabelle. Die Spalte adrnr dient als automatisch fortlaufender Primärschlüssel.

Schritt 2: Tabelle "plz" erstellen

CREATE TABLE IF NOT EXISTS `plz` (
`plz` varchar(4) PRIMARY KEY NOT NULL,
`ort` varchar(50) DEFAULT NULL
);

Die Tabelle enthält Orte mit zugehöriger Postleitzahl. Da plz hier als PRIMARY KEY definiert ist, ist jeder Eintrag automatisch eindeutig.

Schritt 3: Fremdschlüsselbeziehung setzen

ALTER TABLE `name`
ADD CONSTRAINT `plz_ibfk_1` FOREIGN KEY (`plz`) REFERENCES `plz` (`plz`);

Damit wird sichergestellt, dass nur Postleitzahlen in die Tabelle name eingetragen werden dürfen, die auch in der Tabelle plz vorhanden sind. Das erhält die Datenkonsistenz.

Ergebnis/Nutzen

Nachdem die Tabellen so miteinander verknüpft wurden, kannst du beliebige Orte in der Tabelle plz eintragen. Sobald du dann in der name-Tabelle einen Datensatz anlegst, darfst du nur noch PLZs auswählen, die in der plz-Tabelle vorkommen. Das verhindert fehlerhafte oder unvollständige Daten.

Constraints in MySQL

phpMyAdmin Besonderheiten

Ich nutze phpMyAdmin vor allem zum Sichern und Wiederherstellen von CMS-Datenbanken. Beim Testen für diesen Artikel sind mir zwei nützliche Funktionen besonders aufgefallen:

Indizes löschen

Wähle eine Tabelle aus, klicke unterhalb auf den Link "Indizes", und dir wird eine Liste mit allen vorhandenen Indizes angezeigt. Über die Schaltfläche "Löschen" kannst du einzelne Indizes entfernen.

Grafischer Beziehungseditor

phpMyAdmin bietet einen grafischen Designer, mit dem sich Tabellenbeziehungen visuell bearbeiten lassen. Du findest ihn, wenn du die Datenbank öffnest, "Abfrage" auswählst und dann auf "Designer" klickst.

Beispiel Bash Script

Mit diesem Skript schreibe ich die gemessenen Temperaturdaten eines Raspberry Pi in eine Datenbank.

DB_HOST=192.168.0.200
DB_NAME=tempout
DB_USER=grafana
DB_PASS=meindbpasswort
TMP_VAL="/pfad/zu/temp1.txt"
TMP_DAT="/pfad/zu/temp1-dat.txt"

mysql \
-h"$DB_HOST" \
-u"$DB_USER" \
-p"$DB_PASS" \
--skip-ssl \
"$DB_NAME" \
-e "INSERT INTO temperature (ts, value) VALUES ('$CURRENT', $temp);"

Timestamp-Werte müssen in Anführungszeichen stehen.

Sicherheit

skip-grant-tables ist keine gute Idee

Bisher habe ich alles nur in meinem Homelab laufen lassen und mich um das Thema Sicherheit nicht grossartig gekümmert.

Damit der Zugriff klappte, hat mir eine KI geraten

/etc/mysql/mariadb.conf.d/50-server.cnf

skip-grant-tables

aktivieren in der Rubrik

[mysqld]

und anschliessend den mySQL Server neu starten.

sudo systemctl restart mariadb

Doch was macht diese Option überhaupt?

Die Option skip-grant-tables schaltet das gesamte Berechtigungssystem von MariaDB/MySQL komplett ab. Das bedeutet:

  • Jeder kann sich verbinden – ohne Passwort
  • Jeder hat vollen Zugriff – auf alle Datenbanken und Tabellen
  • Keine Authentifizierung – keine Überprüfung, wer du bist
  • Keine Autorisierung – keine Prüfung, was du tun darfst

Stell dir das wie einen Safe vor, bei dem du die Tür offen lässt und das Schloss entfernt hast. Jeder kann rein, alles ansehen und alles verändern.

Warum wird das verwendet?

In der Praxis dient diese Option hauptsächlich einem Zweck: Passwort-Reset. Wenn du als Administrator dein eigenes Root-Passwort verloren hast, kannst du damit kurzzeitig Zugriff wiederherstellen, ein neues Passwort setzen und die Option danach sofort wieder deaktivieren.

Warnung: Nur im Homelab!

Diese Konfiguration ist extrem gefährlich in jedem produktiven Umfeld:

RisikoBeschreibung
DatenverlustJeder kann Tabellen löschen oder überschreiben
DatendiebstahlAlle sensiblen Informationen sind zugänglich
ManipulationDaten können unbemerkt verändert werden
FernzugriffBei öffentlicher IP ist jeder im Internet betroffen

So gehst du sicher vor

Nachdem du dein Passwort zurückgesetzt hast, solltest du:

  1. Die Zeile skip-grant-tables wieder aus der Konfigurationsdatei entfernen
  2. Den Server neu starten: sudo systemctl restart mariadb
  3. Ein starkes Root-Passwort setzen
  4. Prüfen, ob noch anonyme Benutzer existieren (SELECT User, Host FROM mysql.user;)
  5. Unnötige Benutzer entfernen

Zugriff von mehreren Geräten im Netzwerk

Im Homelab möchte man oft, dass mehrere kleine Geräte (z. B. Raspberry Pis, Sensoren, andere Server) auf dieselbe Datenbank zugreifen. Wenn du für jedes Gerät einen eigenen Hostnamen konfigurieren müsstest, würde das schnell unübersichtlich.

Die Lösung ist die Verwendung eines Wildcard-Hosts (%), der Verbindungen von jedem beliebigen Host zulässt.

Wichtige Vorbedingung: Firewall

Bevor du diesen Schritt machst, stelle sicher, dass deine Datenbank nicht öffentlich im Internet erreichbar ist.

Der MySQL/MariaDB-Port (standardmässig 3306) sollte in deiner Firewall (Router, ufw, iptables) nur für dein lokales Netzwerk (192.168.0.0/24) geöffnet sein. Von aussen sollte der Port gesperrt sein.

Wenn das sichergestellt ist, ist die Nutzung von % im lokalen Netz eine praktische und sichere Methode.

Schritt 1: Benutzer für alle Hosts erstellen

Verbinde dich als Root mit der Datenbank:

sudo mysql -u root -p

Erstelle nun den Benutzer grafana (oder deinen gewünschten Namen) mit dem Host-Wildcard %:

CREATE USER 'grafana'@'%' IDENTIFIED BY 'DeinSicheresPasswort!';

Das % bedeutet hier: "Erlaube Verbindungen von jedem Host, der sich authentifizieren kann".
Schritt 2: Rechte zuweisen

Weise dem Benutzer die notwendigen Rechte auf der Ziel-Datenbank zu. In diesem Beispiel für die Datenbank tempout:

GRANT SELECT, INSERT, UPDATE, DELETE ON tempout.* TO 'grafana'@'%';
FLUSH PRIVILEGES;

Hinweis: FLUSH PRIVILEGES sorgt dafür, dass die Änderungen sofort wirksam werden.

Schritt 3: Alte Einträge bereinigen (falls vorhanden)

Falls du zuvor Benutzer für spezifische Hostnamen (z. B. 'grafana'@'localhost' oder 'grafana'@'raspz-temp1.fritz.box') erstellt hast, solltest du diese löschen, um Verwirrung zu vermeiden. MariaDB prüft Hostnamen in einer bestimmten Reihenfolge, und doppelte Einträge können zu unerwartetem Verhalten führen.

DROP USER 'grafana'@'localhost';
DROP USER 'grafana'@'raspz-temp1.fritz.box';

Wiederhole dies für alle alten spezifischen Einträge.

Schritt 4: Verbindung testen

Verlasse die SQL-Shell und teste die Verbindung von einem anderen Gerät im Netzwerk aus:

mysql -h 192.168.0.211 -u grafana -p -e "USE tempout; SHOW TABLES;"

Wenn du dich erfolgreich einloggst und die Tabellen siehst, ist alles korrekt konfiguriert.


Zeit gespart? Dann unterstütze doch it-zeugs.de

Wenn dieser Tipp dir geholfen hat, Zeit zu sparen, überlege bitte, eine kleine Spende zu hinterlassen. Dein Beitrag hilft mir, weiterhin wertvolle Inhalte zu erstellen. Du kannst unter diesem Linke spenden: Spende it-zeugs.de

Falld du nicht spenden willst oder kannst, dann wäre es toll, wenn du deinen nächsten Amazon Einkauf mit diesem Link beginnen würdest: Amazon Link. Für dich wird es nicht teurer, ich bekomme aber einen kleinen Beitrag.

Vielen herzlichen Dank ❤️

Schreibe einen Kommentar