Empfohlen

Herzlich Willkommen auf meiner Website

Hier blogge ich regelmäßig über verschiedene IT-Themen, die mir bei meiner täglichen Arbeit begegnen und die mich beschäftigen. In der Regel werden Sie hier also Artikel zu C++ mit Qt, JavaScript, HTML und/oder CSS und ähnlichen Themen finden.

Ich freue mich dabei natürlich über Kommentare, Fragen und rege Beteiligung.

Daneben finden Sie hier Informationen zu meiner selbstständigen Arbeit in den Bereichen Softwareentwicklung und Netzwerkbetreuung.

Tabellenvererbung in PostgreSQL: Ein mächtiges Werkzeug für die Datenmodellierung

Wenn Du in PostgreSQL arbeitest und mit der Herausforderung konfrontiert wirst, gemeinsame Attribute in mehreren Tabellen zu speichern, kann die Tabellenvererbung eine elegante Lösung bieten. Dieser Artikel erklärt Dir, was Tabellenvererbung ist, welche Vorteile und Einschränkungen sie hat und wie Du sie in Deiner eigenen Datenbank nutzen kannst.

Was ist Tabellenvererbung?

Tabellenvererbung in PostgreSQL ist ein Konzept, bei dem eine Tabelle (Elterntabelle) ihre Struktur und Constraints an andere Tabellen (Kindtabellen) weitergibt. So kannst Du eine Basistabelle mit gemeinsamen Spalten erstellen und verschiedene spezialisierte Tabellen davon erben lassen. Das macht Dein Datenmodell flexibler und wiederverwendbarer.

Ein einfaches Beispiel

Stell Dir vor, Du möchtest eine Tabelle für verschiedene Arten von Entitäten erstellen, z. B. Personen. Jede Person hat einen Namen, aber es gibt unterschiedliche Arten von Personen – etwa Mitarbeiter und Kunden, die jeweils zusätzliche Informationen benötigen. Mit Tabellenvererbung kannst Du eine gemeinsame Person-Tabelle erstellen und dann spezialisierte Tabellen für Mitarbeiter und Kunden, die von dieser Basisstruktur erben.

CREATE TABLE person (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL
);

CREATE TABLE mitarbeiter (
    gehalt NUMERIC NOT NULL
) INHERITS (person);

CREATE TABLE kunde (
    rabatt INT NOT NULL
) INHERITS (person);

In diesem Beispiel erben die Tabellen mitarbeiter und kunde die Spalten id und name von der Tabelle person. Zusätzlich haben sie ihre eigenen spezifischen Spalten – gehalt für mitarbeiter und rabatt für kunde.

Vorteile der Tabellenvererbung

Die Vererbung in PostgreSQL bietet einige klare Vorteile:

1. Wiederverwendbarkeit und DRY-Prinzip

Das Prinzip „Don’t Repeat Yourself“ (DRY) gilt auch bei Datenbanken. Indem Du die gemeinsamen Felder in einer Basistabelle definierst, vermeidest Du redundante Datenstrukturen und erleichterst die Pflege Deines Datenmodells. Änderungen in der Elterntabelle werden automatisch auf die Kindtabellen angewendet.

2. Einfachere Abfragen

Eine große Stärke der Tabellenvererbung ist, dass Abfragen an die Elterntabelle automatisch auch Daten aus den Kindtabellen einbeziehen. Das ermöglicht es Dir, alle Daten aus den verschiedenen vererbenden Tabellen mit nur einer Abfrage abzurufen.

SELECT * FROM person;

Mit dieser Abfrage erhältst Du alle Einträge aus person, mitarbeiter und kunde, da die Daten aus den Kindtabellen automatisch miteinbezogen werden.

3. Flexible Datenmodelle

Wenn Du Dein Datenmodell erweitern möchtest, kannst Du einfach neue Kindtabellen hinzufügen, die von der Elterntabelle erben. So kannst Du Dein Schema dynamisch an neue Anforderungen anpassen, ohne bestehende Tabellen zu ändern.

Einschränkungen der Tabellenvererbung

Trotz der vielen Vorteile gibt es auch einige Einschränkungen, die Du bei der Nutzung der Tabellenvererbung beachten solltest:

1. Keine automatische Fremdschlüssel-Vererbung

Fremdschlüssel-Beziehungen, die auf die Elterntabelle zeigen, werden nicht automatisch auf die Kindtabellen übertragen. Wenn Du zum Beispiel einen Fremdschlüssel auf person definierst, wird er nicht automatisch für mitarbeiter und kunde gelten. Du musst Fremdschlüssel für jede Kindtabelle separat definieren.

2. Probleme mit UNIQUE und PRIMARY KEY Constraints

Wenn Du in der Elterntabelle einen UNIQUE oder PRIMARY KEY-Constraint definierst, gilt dieser nicht automatisch für die Kindtabellen. Das bedeutet, dass Du in jeder Kindtabelle dieselbe id haben könntest, was zu Dateninkonsistenzen führen kann. Dieses Verhalten kann in bestimmten Szenarien problematisch sein, insbesondere wenn Eindeutigkeit in den Kindtabellen notwendig ist.

3. Keine automatischen Joins

PostgreSQL führt keine automatischen Joins zwischen Elterntabellen und Kindtabellen durch. Das bedeutet, dass Du in komplexeren Abfragen explizit darauf achten musst, wie Du Daten aus verschiedenen Tabellen kombinierst.

Ein praktisches Beispiel

Angenommen, Du hast eine Datenbank, in der Du verschiedene Arten von Nutzern speichern möchtest – Mitarbeiter und Kunden. Jeder Nutzer hat einen name, aber die beiden Typen haben zusätzliche, unterschiedliche Informationen (z. B. gehalt für Mitarbeiter und rabatt für Kunden).

CREATE TABLE person (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL
);

CREATE TABLE mitarbeiter (
    gehalt NUMERIC NOT NULL
) INHERITS (person);

CREATE TABLE kunde (
    rabatt INT NOT NULL
) INHERITS (person);

Nun kannst Du Daten sowohl in die Tabelle person als auch in die vererbenden Tabellen mitarbeiter und kunde einfügen:

INSERT INTO mitarbeiter (name, gehalt) VALUES ('Max Mustermann', 50000);
INSERT INTO kunde (name, rabatt) VALUES ('Erika Mustermann', 10);

Wenn Du nun eine Abfrage auf die Tabelle person ausführst:

SELECT * FROM person;

Wirst Du sowohl die Daten von Mitarbeiter als auch von Kunden sehen. Wenn Du jedoch nur die Daten von Mitarbeitern abfragen möchtest, kannst Du direkt auf die mitarbeiter-Tabelle zugreifen:

SELECT * FROM mitarbeiter;

Fazit

Tabellenvererbung in PostgreSQL ist ein mächtiges Werkzeug, das Dir hilft, Dein Datenmodell sauber, flexibel und wiederverwendbar zu halten. Durch die Möglichkeit, gemeinsame Spalten und Constraints in einer Basistabelle zu definieren, kannst Du Redundanzen vermeiden und Dein Schema leichter pflegen. Es gibt jedoch einige Einschränkungen, insbesondere in Bezug auf Fremdschlüssel und Constraints, die Du bei der Entscheidung berücksichtigen solltest.

Wenn Du Deine Datenbankstruktur modular und flexibel gestalten möchtest, ist die Tabellenvererbung eine Überlegung wert. Es lohnt sich, dieses Werkzeug in Dein Arsenal der Datenmodellierungstechniken aufzunehmen.

Dein neuer 3D-Druckservice – maßgeschneiderte Einzelstücke und Kleinserien für Dein Projekt

Ich freue mich, Dir meinen neuen 3D-Druckservice vorstellen zu dürfen! Ab sofort kannst Du individuelle 3D-Modelle als Einzelstücke oder in Kleinserien bei mir drucken lassen – schnell, präzise und ganz nach Deinen Wünschen.

Was ich Dir anbiete:

  • Flexible Materialauswahl: Ich drucke Deine Modelle vorwiegend mit PLA, ABS und PETG – drei der gängigsten Materialien im 3D-Druck. Falls Du spezielle Anforderungen hast, drucke ich auf Wunsch auch mit anderen Filamenten, z. B. mit Bio-PLA, einem nachhaltigen und umweltfreundlichen Material.
  • Hohe Präzision und Flexibilität: Mit einer maximalen Druckgröße von 250 x 220 x 220 mm und einer Schichtauflösung von 0,2 mm lassen sich unterschiedlichste Projekte realisieren – von Prototypen bis hin zu funktionalen Bauteilen oder dekorativen Objekten.
  • FDM-Drucktechnologie: Derzeit biete ich ausschließlich den FDM-Druck (Fused Deposition Modeling) an. Diese bewährte Technologie eignet sich hervorragend für stabile und langlebige Objekte.
  • Keine eigene 3D-Modellierung notwendig: Du hast bereits ein fertiges 3D-Modell? Großartig! Ich übernehme das Slicing, die Druckvorbereitung, Qualitätskontrolle und Nachbearbeitung für Dich. Dabei bevorzuge ich STL-Dateien, kann aber auch mit anderen Formaten arbeiten, falls das für Dich besser passt.
  • Individuelle Preisgestaltung: Da jedes Projekt unterschiedlich ist, stimme ich die Preise individuell mit Dir ab. Sie basieren auf den Materialkosten und der benötigten Arbeitszeit – so hast Du volle Transparenz und faire Konditionen.

Deine Vorteile auf einen Blick:

  • Kleinserien und Einzelstücke: Egal, ob Du ein einzelnes Modell oder eine kleine Serie drucken lassen möchtest – ich biete Dir maßgeschneiderte Lösungen.
  • Nachhaltige Materialien: Auf Wunsch drucke ich Deine Modelle mit umweltfreundlichen und biologisch abbaubaren Materialien wie Bio-PLA.
  • Höchste Qualitätsstandards: Von der Druckvorbereitung bis zur Nachbearbeitung arbeite ich mit größter Sorgfalt, um Dir das bestmögliche Ergebnis zu liefern.

So funktioniert es:

  1. Datei senden: Schick mir Deine fertige 3D-Vorlage (bevorzugt im STL-Format, aber auch andere Formate sind möglich).
  2. Individuelles Angebot: Du erhältst von mir ein unverbindliches Angebot, das genau auf Deine Anforderungen zugeschnitten ist.
  3. Fertigung & Versand: Nach Deiner Freigabe beginne ich mit dem Druck und sende Dir das fertige Produkt zu.

Jetzt Dein Projekt starten!

Hast Du Fragen oder möchtest direkt ein Angebot erhalten? Melde Dich gerne direkt hier über meine Website. Ich freue mich darauf, Deine Ideen in die Realität umzusetzen!

Shell-Skripte und Verzeichniswechsel: Warum Dein Skript nicht das Verzeichnis wechselt – und wie Du das Problem löst

Vielleicht kennst Du das Problem: Du hast unter Ubuntu oder Linux Mint ein einfaches Shell-Skript geschrieben, das nur das Verzeichnis wechseln soll. Doch beim Aufruf des Skripts merkst Du, dass das Verzeichnis in Deiner aktuellen Shell nicht gewechselt wird, obwohl der cd-Befehl im Skript steht.

In diesem Artikel erkläre ich Dir, warum das passiert und wie Du es richtig machst.

Das Problem: Skripte laufen in einer Subshell

Wenn Du ein Shell-Skript normal ausführst, passiert das in einer Subshell. Das bedeutet, dass eine neue Shell-Instanz geöffnet wird, die das Skript abarbeitet. Sobald das Skript fertig ist, wird die Subshell geschlossen und Du landest wieder in Deiner ursprünglichen Shell – ohne dass Änderungen wie der Verzeichniswechsel übernommen werden.

Das ist der Grund, warum Dein cd-Befehl zwar innerhalb des Skripts funktioniert, aber nach dem Ende des Skripts Dein Verzeichnis unverändert bleibt.

Die Lösung: Das Skript im aktuellen Shell-Kontext ausführen

Damit das Verzeichnis in Deiner aktuellen Shell geändert wird, musst Du das Skript im aktuellen Shell-Kontext ausführen. Dazu gibt es zwei einfache Möglichkeiten: den Befehl source oder den Punkt ..

Beispiel:

Nehmen wir an, Du hast ein Skript namens wechselverzeichnis.sh, das so aussieht:

#!/bin/bash
cd /pfad/zu/deinem/verzeichnis

Anstatt es wie gewohnt so aufzurufen:

./wechselverzeichnis.sh

musst Du es so aufrufen:

source wechselverzeichnis.sh

oder:

. wechselverzeichnis.sh

Was passiert beim „Sourcen“?

Durch den Aufruf mit source (oder dem Punkt .) wird das Skript nicht in einer Subshell ausgeführt, sondern direkt im Kontext Deiner aktuellen Shell. Alle Änderungen, die das Skript an der Umgebung vornimmt, wie z.B. der Verzeichniswechsel, gelten dann auch für Deine Shell-Sitzung.

Was ist, wenn ich das Skript normal ausführen will?

Wenn Du das Skript weiter wie gewohnt ausführst, also mit ./wechselverzeichnis.sh, dann bleibt es dabei, dass es in einer Subshell läuft. Das kann für andere Arten von Skripten völlig ausreichend sein, aber für Dinge wie cd, die Änderungen an der aktuellen Umgebung vornehmen sollen, ist es nicht die richtige Methode.

Fazit

Wenn Du ein Shell-Skript geschrieben hast, das in Deinem aktuellen Shell-Kontext Änderungen vornehmen soll, wie z.B. den Wechsel des Verzeichnisses mit cd, dann musst Du das Skript „sourcen“ – also mit source oder . aufrufen. Dadurch führst Du das Skript im gleichen Kontext aus, und die Änderungen gelten direkt für Deine aktuelle Shell-Sitzung.

So passt Du Deine Swap-Datei unter Linux an

Dein System wird langsamer, und Du hast bemerkt, dass der Arbeitsspeicher (RAM) oft ausgelastet ist? Dann könnte es Zeit sein, die Swap-Datei zu vergrößern! In diesem Artikel erkläre ich Dir Schritt für Schritt, wie Du Deine Swap-Datei anpassen kannst, um die Leistung Deines Linux-Systems zu optimieren.

Was ist Swap?

Bevor wir loslegen, ein kurzer Überblick: Die Swap-Datei fungiert als eine Art Erweiterung des Arbeitsspeichers (RAM). Wenn Dein physischer RAM voll ist, speichert Linux weniger genutzte Daten auf der Festplatte, um den RAM für aktivere Prozesse freizuhalten. Dies verhindert, dass das System einfriert oder verlangsamt, wenn es zu wenig RAM gibt.

Warum die Swap-Datei vergrößern?

Obwohl die Nutzung der Swap-Datei das System verlangsamen kann, ist es immer noch besser, als wenn das System komplett überlastet wird. Falls Du speicherintensive Anwendungen wie Entwicklungsumgebungen, Videobearbeitung oder Virtualisierung nutzt, könnte es ratsam sein, die Größe der Swap-Datei anzupassen.

Schritt-für-Schritt Anleitung zum Vergrößern der Swap-Datei

1. Swap-Datei deaktivieren

Zuerst müssen wir die aktuelle Swap-Datei deaktivieren, bevor wir sie vergrößern. Keine Sorge, Dein System wird weiterhin laufen, solange Du genügend freien RAM hast. Öffne ein Terminal und gib folgenden Befehl ein:

sudo swapoff /swapfile

2. Alte Swap-Datei entfernen (optional)

Falls Du möchtest, kannst Du die alte Swap-Datei löschen, um Platz zu schaffen. Nutze dafür folgenden Befehl:

sudo rm /swapfile

3. Neue Swap-Datei erstellen

Jetzt erstellen wir eine neue Swap-Datei mit der gewünschten Größe. Nehmen wir an, Du möchtest eine 4 GB große Swap-Datei:

sudo fallocate -l 4G /swapfile

Falls fallocate auf Deinem System nicht funktioniert, kannst Du auch diesen alternativen Befehl verwenden:

sudo dd if=/dev/zero of=/swapfile bs=1M count=4096

4. Berechtigungen festlegen

Damit die Swap-Datei sicher ist, setzen wir die Berechtigungen:

sudo chmod 600 /swapfile

5. Swap-Datei initialisieren

Nun formatieren wir die neue Swap-Datei, damit sie als Swap-Speicher verwendet werden kann:

sudo mkswap /swapfile

6. Swap-Datei aktivieren

Jetzt aktivieren wir die neue Swap-Datei:

sudo swapon /swapfile

7. Überprüfen, ob die Swap-Datei aktiv ist

Mit folgendem Befehl kannst Du überprüfen, ob die Swap-Datei korrekt aktiviert wurde:

swapon --show

Du solltest jetzt sehen, dass die neue Größe der Swap-Datei angezeigt wird.

8. Swap-Datei dauerhaft aktivieren

Damit die neue Swap-Datei nach jedem Neustart automatisch aktiviert wird, müssen wir sie in der /etc/fstab-Datei eintragen. Öffne die Datei mit einem Texteditor:

sudo nano /etc/fstab

Füge folgenden Eintrag hinzu, falls er nicht bereits vorhanden ist:

/swapfile none swap sw 0 0

Speichere die Datei und schließe den Editor.

Welche Swap-Größe ist sinnvoll?

Für ein System mit 8 GB RAM gibt es einige Richtlinien:

  • 8 GB Swap: Für normale Nutzung, ohne Ruhezustand, reicht das oft aus.
  • 12–16 GB Swap: Wenn Du speicherintensive Anwendungen nutzt oder den Ruhezustand verwenden möchtest, solltest Du eine größere Swap-Datei wählen.

Falls Dein System dennoch an die Grenzen stößt, kannst Du die Swap-Datei jederzeit vergrößern.

Fazit

Mit diesen einfachen Schritten kannst Du die Swap-Datei Deines Linux-Systems anpassen und vergrößern. Eine gut konfigurierbare Swap-Datei kann Dir helfen, die Leistung zu verbessern und Dein System stabil zu halten, auch wenn Dein Arbeitsspeicher ausgelastet ist.

Optimierung der Fehlermeldungen in PostgreSQL: Verwendung von log_error_verbosity und client_min_messages

Einleitung

In der Welt der Datenbanken ist PostgreSQL für seine Zuverlässigkeit und Leistungsfähigkeit bekannt. Dennoch kann es vorkommen, dass Entwickler und Administratoren auf kryptische Fehlermeldungen stoßen, die nur begrenzt Aufschluss über die eigentliche Ursache eines Problems geben. In solchen Fällen ist es hilfreich, die Detailtiefe der Fehlermeldungen zu erhöhen. Hier kommen die Parameter log_error_verbosity und client_min_messages ins Spiel. In diesem Artikel erläutere ich, wie Du diese Parameter verwenden kannst, um umfassendere und hilfreichere Fehlermeldungen zu erhalten.

Der Parameter log_error_verbosity

Der Parameter log_error_verbosity bestimmt, wie detailliert die Fehlerprotokolle von PostgreSQL sind. Es gibt drei mögliche Einstellungen:

  • TERSE: Liefert die minimal notwendige Information.
  • DEFAULT: Standardmäßige Detailtiefe, die ausreichend Informationen für die meisten Anwendungen bietet.
  • VERBOSE: Bietet die höchste Detailtiefe und ist besonders nützlich für das Debuggen komplexer Probleme.

Anwendung von log_error_verbosity

Um die Detailtiefe der Fehlermeldungen zu erhöhen, kannst Du log_error_verbosity auf VERBOSE setzen. Dies kann entweder in der PostgreSQL-Konfigurationsdatei (postgresql.conf) oder direkt in einer SQL-Sitzung erfolgen.

In der postgresql.conf Datei
  1. Öffne die postgresql.conf Datei in einem Texteditor:
   sudo nano /etc/postgresql/<version>/main/postgresql.conf
  1. Suche nach dem Parameter log_error_verbosity und setze ihn auf verbose:
   log_error_verbosity = verbose
  1. Speichere die Datei und schließe den Editor.
  2. Starte den PostgreSQL-Server neu, damit die Änderungen wirksam werden:
   sudo systemctl restart postgresql
In einer SQL-Sitzung

Du kannst die Einstellung auch vorübergehend in einer SQL-Sitzung ändern:

SET log_error_verbosity = 'verbose';

Der Parameter client_min_messages

Der Parameter client_min_messages steuert, welche Meldungen an den Client gesendet werden. Die verfügbaren Stufen sind:

  • DEBUG5 bis DEBUG1: Sehr detaillierte Debug-Informationen.
  • INFO: Informative Nachrichten.
  • NOTICE: Wichtige Hinweise.
  • WARNING: Warnungen vor möglichen Problemen.
  • ERROR: Fehler, die eine Aktion verhindern.
  • LOG: Nachrichten, die im Serverlog erscheinen.
  • FATAL: Kritische Fehler, die die Sitzung beenden.
  • PANIC: Schwerwiegende Fehler, die den Server stoppen.

Anwendung von client_min_messages

Um sicherzustellen, dass alle relevanten Meldungen angezeigt werden, kannst Du client_min_messages auf die detaillierteste Stufe DEBUG5 setzen.

In der postgresql.conf Datei
  1. Öffne die postgresql.conf Datei in einem Texteditor:
   sudo nano /etc/postgresql/<version>/main/postgresql.conf
  1. Suche nach dem Parameter client_min_messages und setze ihn auf debug5:
   client_min_messages = debug5
  1. Speichere die Datei und schließe den Editor.
  2. Starte den PostgreSQL-Server neu:
   sudo systemctl restart postgresql
In einer SQL-Sitzung

Du kannst die Einstellung auch vorübergehend in einer SQL-Sitzung ändern:

SET client_min_messages = debug5;

Zusammenfassung

Die Anpassung der Parameter log_error_verbosity und client_min_messages kann Dir helfen, detailliertere und nützlichere Fehlermeldungen in PostgreSQL zu erhalten. Dies erleichtert das Debuggen und die Fehlerbehebung erheblich. Denke daran, dass Änderungen an diesen Parametern die Menge der geloggten Informationen erheblich erhöhen können, was sich auf die Performance und die Größe der Logdateien auswirken kann. Verwende diese Einstellungen daher mit Bedacht und nur für die Zeit, die zur Problemlösung erforderlich ist.

Alles, was Sie über Natural Joins in SQL wissen müssen

SQL (Structured Query Language) ist eine mächtige Sprache für die Verwaltung und Manipulation von Datenbanken. Eine häufige Aufgabe bei der Arbeit mit Datenbanken ist das Verbinden von Tabellen, um umfassendere Datensätze zu erstellen. In SQL gibt es verschiedene Möglichkeiten, Tabellen zu verbinden, darunter INNER JOIN, LEFT JOIN, RIGHT JOIN und FULL JOIN. Ein spezieller Typ des Joins, der weniger bekannt, aber dennoch nützlich ist, ist der NATURAL JOIN.

Was ist ein Natural Join?

Ein NATURAL JOIN ist eine Art von Join, der automatisch die Spalten mit denselben Namen in beiden Tabellen verknüpft. Das bedeutet, dass Sie die Spalten, die zum Verbinden der Tabellen verwendet werden, nicht explizit angeben müssen. Stattdessen übernimmt die Datenbank-Engine diese Aufgabe für Sie. Dies kann den Code kürzer und einfacher machen, insbesondere wenn viele Spalten übereinstimmen.

Syntax eines Natural Join

Die Syntax eines NATURAL JOIN ist einfach und übersichtlich. Hier ein Beispiel:

SELECT * 
FROM table1
NATURAL JOIN table2;

In diesem Beispiel sucht die Datenbank-Engine automatisch nach Spalten in table1 und table2 mit denselben Namen und verknüpft diese.

Vorteile von Natural Joins

  1. Einfachheit: Der offensichtlichste Vorteil eines NATURAL JOIN ist die Einfachheit. Sie müssen nicht explizit die Spaltennamen angeben, was den SQL-Code kürzer und leichter lesbar macht.
  2. Automatisches Mapping: NATURAL JOIN übernimmt automatisch das Mapping der Spalten, was besonders nützlich ist, wenn mehrere Spalten übereinstimmen.
  3. Weniger Fehleranfällig: Da die Spaltennamen nicht manuell eingegeben werden müssen, besteht eine geringere Wahrscheinlichkeit für Tippfehler oder falsche Zuordnungen.

Nachteile von Natural Joins

  1. Unvorhersehbarkeit: Der größte Nachteil eines NATURAL JOIN ist die Unvorhersehbarkeit. Wenn neue Spalten zu einer der Tabellen hinzugefügt werden, die denselben Namen wie bestehende Spalten haben, kann dies zu unerwarteten Ergebnissen führen.
  2. Eingeschränkte Kontrolle: Da die Spalten automatisch verknüpft werden, haben Sie weniger Kontrolle über den Join-Prozess. Dies kann problematisch sein, wenn nur bestimmte Spalten verknüpft werden sollen.
  3. Lesbarkeit für andere Entwickler: Obwohl NATURAL JOIN den Code kürzer macht, kann es für andere Entwickler, die den Code lesen und warten, weniger klar sein, welche Spalten verknüpft werden. Explizite Joins sind oft klarer und verständlicher.

Wann sollten Sie Natural Joins verwenden?

NATURAL JOINs eignen sich am besten für Situationen, in denen Sie sicher sind, dass die Tabellen nur eine oder wenige Spalten mit denselben Namen haben und diese Spalten die einzigen sind, die verknüpft werden sollen. Wenn Sie jedoch komplexere Joins benötigen oder mehr Kontrolle über den Join-Prozess wünschen, sind explizite Joins wie INNER JOIN die bessere Wahl.

Fazit

NATURAL JOINs sind ein nützliches Werkzeug in SQL, das den Join-Prozess vereinfachen kann, indem es automatisch Spalten mit denselben Namen verknüpft. Während sie in bestimmten Situationen sehr praktisch sein können, ist es wichtig, ihre Einschränkungen und potenziellen Fallstricke zu kennen. Verwenden Sie NATURAL JOINs mit Bedacht und stellen Sie sicher, dass sie für Ihre spezifischen Anwendungsfälle geeignet sind. Wie bei vielen Aspekten der Softwareentwicklung gibt es keine Einheitslösung, und die Wahl des richtigen Werkzeugs hängt von den spezifischen Anforderungen und Umständen Ihres Projekts ab.

Die Bedeutung stabiler Enum-Werte in C++ Klassen

In der C++ Programmierung ist es wichtig, Enum-Werte so zu definieren, dass sie über die Zeit stabile Integer-Werte behalten, besonders wenn sie in Datenbanken gespeichert werden.

Warum ist die Stabilität von Enum-Werten wichtig?

Enums bieten eine bequeme Möglichkeit, benannte Konstanten zu definieren, aber ihre zugewiesenen Integer-Werte können sich ändern, wenn neue Werte hinzugefügt werden oder die Reihenfolge geändert wird. Dies kann zu Inkonsistenzen führen, wenn Enum-Werte in Datenbanken gespeichert und später interpretiert werden.

Beispiel: Eine Klasse mit Enum-Werten

Angenommen, wir haben eine Klasse Event, die verschiedene Ereignistypen speichert:

enum class EventType {
    UNKNOWN = 0,
    STARTED = 1,
    STOPPED = 2,
    PAUSED = 3
};

class Event
{
public:
    Event(EventType type = EventType::UNKNOWN) 
        : eventType(type)
    {
        // Weitere Initialisierungen können hier erfolgen
    }

    EventType getType() const {
        return eventType;
    }

    void setType(EventType type) {
        eventType = type;
    }

    int getTypeAsInt() const {
        return static_cast<int>(eventType);
    }

private:
    EventType eventType;
};

Sicherstellen stabiler Enum-Werte für die Datenbank

Um sicherzustellen, dass Enum-Werte über die Zeit stabil bleiben und in Datenbanken konsistent gespeichert werden können, ist es wichtig, ihnen explizite Integer-Werte zuzuweisen. Im obigen Beispiel wurden den Enum-Werten feste Integer-Werte zugewiesen (UNKNOWN = 0, STARTED = 1, usw.). Dies stellt sicher, dass sich die zugewiesenen Integer-Werte nicht ändern, wenn neue Enum-Werte hinzugefügt werden.

Fazit

Die Stabilität von Enum-Werten in C++ ist entscheidend, insbesondere wenn sie persistent in Datenbanken gespeichert werden sollen. Durch das explizite Zuweisen von festen Integer-Werten zu Enum-Konstanten stellt man sicher, dass die Interpretation dieser Werte über die Zeit konsistent bleibt.

Integration von Meld mit Git

Wenn Sie Git zur Versionskontrolle verwenden und auf der Suche nach einem benutzerfreundlichen Diff- und Merge-Tool sind, ist Meld eine ausgezeichnete Wahl. In diesem Artikel erfahren Sie, wie Sie Meld installieren und nahtlos in Ihre Git-Workflows integrieren können.

Schritt 1: Installation von Meld

Stellen Sie zunächst sicher, dass Sie Meld installiert haben. Sie können Meld von der offiziellen Website herunterladen und installieren: Meld.

Schritt 2: Konfiguration von Meld als Diff-Tool

Um Meld als Diff-Tool in Git zu konfigurieren, öffnen Sie eine Eingabeaufforderung (CMD, PowerShell, Terminal) und führen Sie die folgenden Befehle aus:

git config --global diff.tool meld
git config --global difftool.meld.path [Pfad-zu-Meld]

Ersetzen Sie [Pfad-zu-Meld] durch den tatsächlichen Pfad zur Meld-Programmdatei. Beispielsweise könnte der Pfad unter Windows so aussehen:

git config --global difftool.meld.path "C:/Program Files (x86)/Meld/Meld.exe"

Unter Linux oder macOS könnte es einfach meld sein, wenn Meld im Systempfad liegt:

git config --global difftool.meld.path meld

Schritt 3: Konfiguration von Meld als Merge-Tool

Um Meld als Merge-Tool zu konfigurieren, führen Sie diese Befehle aus:

git config --global merge.tool meld
git config --global mergetool.meld.path [Pfad-zu-Meld]
git config --global mergetool.meld.trustExitCode true

Auch hier sollten Sie [Pfad-zu-Meld] durch den tatsächlichen Pfad zur Meld-Programmdatei ersetzen.

Schritt 4: Zusätzliche Einstellungen für Benutzerfreundlichkeit

Um sicherzustellen, dass Git Sie nicht jedes Mal nach einer Bestätigung fragt, wenn Sie Meld verwenden, können Sie die folgenden Befehle ausführen:

git config --global difftool.prompt false
git config --global mergetool.prompt false

Verwendung von Meld mit Git

Nachdem Sie die Konfiguration abgeschlossen haben, können Sie Meld sowohl für Diffs als auch für Merges verwenden.

Diff-Tool verwenden: Um Meld als Diff-Tool zu nutzen, verwenden Sie git difftool anstelle von git diff:

git difftool [commit1] [commit2] -- [dateiname]

Wenn Sie beispielsweise die Änderungen des letzten Commits vergleichen möchten, führen Sie Folgendes aus:

git difftool HEAD~1 HEAD -- [dateiname]

Merge-Tool verwenden: Bei Merge-Konflikten können Sie Meld verwenden, um diese zu lösen:

git mergetool

Fazit

Durch die Integration von Meld in Ihre Git-Workflows profitieren Sie von einer benutzerfreundlichen und leistungsfähigen Umgebung zum Vergleichen und Zusammenführen von Dateien. Die oben beschriebenen Schritte sollten Ihnen helfen, Meld schnell und effektiv zu konfigurieren. Probieren Sie es aus und erleben Sie, wie Meld Ihre Arbeit mit Git noch produktiver macht.

qCompress und qUncompress auf der Kommandozeile

Die in Qt eingebaute Methode zur Komprimierung von Datenströmen mit qCompress und qUncompress generiert leider keine standardkonformen Dateien, die mit externen Tools geöffnet werden können.

Ich habe daher ein kleines Tool geschrieben, das den Umgang mit diesen Dateien auf der Kommandozeile erleichtert. Die einzige Abhängigkeit besteht dabei zu Qt Core (Qt5Core.dll unter Windows). Der Quelltext steht unter GPL 3 zur freien Verfügung und kann hier runtergeladen werden:

https://github.com/thomasbutzbach/qtArchiver

Datensicherung für Ubuntu-Server verschlüsselt auf Strato HiDrive

Eine automatische, nächtliche Datensicherung für einen Ubuntu-Server ist schnell eingerichtet. Dabei werden die Daten lokal verschlüsselt und dann per SFTP verschlüsselt auf einen Strato HiDrive-Account übertragen. Dazu verwende ich das Linux-Tool Duplicity.

Zunächst richtet man ein kleines Shell-Skript ein und legt es im eigenen Home-Verzeichnis an. Mein Beispiel-Skript führt monatlich eine vollständige Datensicherung durch. Alle weiteren nächtlichen Sicherungen erfolgen dann inkrementell. Außerdem lasse ich durch Duplicity automatisch alle Sicherungen entfernen, die älter als 3 Monate sind. So muss ich mir keine Gedanken darüber machen, dass der Strato HiDrive-Speicher auf Dauer vollläuft.

#!/bin/bash
export PASSPHRASE="MeineStrengGeheimePassphrase"
export FTP_PASSWORD=<SFTP-Passwort von Strato>

# monatliche Vollsicherung (1M)
duplicity --full-if-older-than 1M /home/user sftp://share-xxxx@sftp.hidrive.strato.com/users/share-xxxx/Serversicherungen

# Backups wegräumen, die älter als 3 Monate sind
duplicity remove-older-than 3M --force sftp://share-xxxx@sftp.hidrive.strato.com/users/share-xxxx/Serversicherungen

unset PASSPHRASE
unset FTP_PASSWORD

Hier sind nur noch die markierten Stellen individuell anzupassen bzw. mit den Strato-Zugangsdaten zu füllen.

Beim ersten Aufruf muss man zunächst den SSH-Fingerabdruck des Strato-Server bestätigen. Dieser wird dabei in der .ssh/known_hosts abgelegt. Daher sollte man das Sicherungsskript einmal manuell durchlaufen lassen, bevor man die Datensicherung als Cronjob anlegt. Ist der SSH-Fingerabdruck hinterlegt, läuft das Sicherungsskript ohne weitere Nachfrage automatisch durch.

Dieses Sicherungsskript kann man nun z.B. über einen Cronjob jede Nacht  um 23:00 Uhr aufrufen. Um einen solchen Cronjob anzulegen, wechselt man mit crontab -e in den Cronjob-Editor und legt folgende neue Zeile an:

0 23 * * * /home/user/backup.sh >> /home/user/logs/backup.log 2> /home/user/logs/backup.error.log

Dabei ist darauf zu achten, dass das logs-Verzeichnis bereits angelegt und schreibbar ist, da die Datensicherung sonst fehlschlägt.

Für die Wiederherstellung der so gesicherten Daten habe ich ein kleines Restore-Skript zusammengestellt, das ich im Notfall nur noch schnell anpassen muss, ohne erst zu recherchieren, wie genau eine Datenwiederherstellung mit Duplicity funktioniert.

export PASSPHRASE="MeineStrengGeheimePassphrase"
export FTP_PASSWORD=<SFTP-Passwort von Strato>

duplicity restore sftp://share-xxxx@sftp.hidrive.strato.com/users/share-xxxx/Serversicherungen /home/user/backup

unset PASSPHRASE
unset FTP_PASSWORD

Die beiden Skriptdateien sollte man dann noch mit einem chmod 700 backup.sh bzw. chmod 700 restore.sh vor den neugierigen Blicken anderer User auf dem System schützen.