Skip to content
IRC-Coding IRC-Coding
Datenbanken Normalisierung 1NF 2NF 3NF BCNF Funktionsabhängigkeiten Anomalien Datenmodellierung

Datenbank Normalisierung: 1NF, 2NF, 3NF, BCNF & Anomalien

Datenbank Normalisierung mit 1NF, 2NF, 3NF, BCNF. Funktionsabhängigkeiten, Anomalien und Normalformen mit SQL Beispielen.

S

schutzgeist

2 min read

Datenbank Normalisierung: 1NF, 2NF, 3NF, BCNF & Anomalien

Datenbank-Normalisierung ist ein systematischer Prozess zur Organisation von Daten in relationalen Datenbanken. Ziel ist die Reduzierung von Redundanz und die Vermeidung von Anomalien bei Datenmanipulationen.

Was ist Normalisierung?

Normalisierung zerlegt komplexe Datenstrukturen in kleinere, logisch zusammenhängende Tabellen. Durch die Einhaltung von Normalformen werden Datenintegrität und Konsistenz sichergestellt.

Ziele der Normalisierung

  • Redundanz vermeiden: Daten nur einmal speichern
  • Anomalien eliminieren: Update-, Insert-, Delete-Anomalien vermeiden
  • Datenintegrität: Konsistente Daten gewährleisten
  • Wartbarkeit: Einfache Änderungen und Erweiterungen

Funktionsabhängigkeiten

Grundkonzepte

Funktionsabhängigkeit beschreibt die Beziehung zwischen Attributen in einer Relation.

-- Beispiel: Studentenrelation
CREATE TABLE Studenten (
    MatrikelNr INT PRIMARY KEY,
    Name VARCHAR(50),
    Semester INT,
    Fachbereich VARCHAR(50)
);

-- Funktionsabhängigkeiten:
-- MatrikelNr → Name (jede Matrikelnummer hat genau einen Namen)
-- MatrikelNr → Semester (jede Matrikelnummer hat genau ein Semester)
-- MatrikelNr → Fachbereich (jede Matrikelnummer hat genau einen Fachbereich)

Arten von Funktionsabhängigkeiten

-- Vollständige Funktionsabhängigkeit
CREATE TABLE Noten (
    MatrikelNr INT,
    VorlesungNr INT,
    Note DECIMAL(3,1),
    PRIMARY KEY (MatrikelNr, VorlesungNr)
);

-- (MatrikelNr, VorlesungNr) → Note (vollständig abhängig)
-- MatrikelNr ↛ Note (nicht abhängig)
-- VorlesungNr ↛ Note (nicht abhängig)

-- Transitive Funktionsabhängigkeit
CREATE TABLE Dozenten (
    DozentenNr INT PRIMARY KEY,
    Name VARCHAR(50),
    Fachbereich VARCHAR(50),
    FachbereichLeiter VARCHAR(50)
);

-- DozentenNr → Fachbereich
-- Fachbereich → FachbereichLeiter
-- DozentenNr → FachbereichLeiter (transitiv)

Anomalien in nicht-normalisierten Daten

Beispiel für Anomalien

-- Nicht-normalisierte Tabelle mit Problemen
CREATE TABLE Probleme_Tabelle (
    MatrikelNr INT,
    StudentName VARCHAR(50),
    VorlesungNr INT,
    VorlesungName VARCHAR(50),
    DozentNr INT,
    DozentName VARCHAR(50),
    Note DECIMAL(3,1),
    Semester INT
);

-- Daten:
-- 101, 'Max Mustermann', 301, 'Datenbanken', 501, 'Prof. Schmidt', 1.3, 5
-- 101, 'Max Mustermann', 302, 'Algorithmen', 502, 'Prof. Mueller', 2.0, 5
-- 102, 'Erika Mustermann', 301, 'Datenbanken', 501, 'Prof. Schmidt', 1.7, 3

Arten von Anomalien

1. Update-Anomalie

-- Problem: Dozentenname ändern
UPDATE Probleme_Tabelle 
SET DozentName = 'Prof. Dr. Schmidt' 
WHERE DozentNr = 501;
-- Muss für alle Vorkommen gemacht werden!

2. Insert-Anomalie

-- Problem: Neue Vorlesung ohne Studenten einfügen
INSERT INTO Probleme_Tabelle (MatrikelNr, VorlesungNr, VorlesungName, DozentNr, DozentName)
VALUES (NULL, 303, 'Software Engineering', 503, 'Prof. Weber');
-- Problem: MatrikelNr darf nicht NULL sein (Primary Key)

3. Delete-Anomalie

-- Problem: Letzten Studenten aus Vorlesung löschen
DELETE FROM Probleme_Tabelle 
WHERE MatrikelNr = 101 AND VorlesungNr = 302;
-- Verliert Information über Vorlesung 302 und Dozent 502

Erste Normalform (1NF)

Definition und Regeln

Eine Relation ist in 1NF, wenn:

  1. Alle Attribute atomar sind (keine wiederholten Gruppen)
  2. Jede Zeile eindeutig identifizierbar ist (Primary Key)
  3. Alle Attributwerte aus demselben Domäne stammen

Umsetzung in 1NF

-- Vorher: Nicht in 1NF (wiederholte Gruppen)
CREATE TABLE Studenten_Vorher (
    MatrikelNr INT PRIMARY KEY,
    Name VARCHAR(50),
    Vorlesungen VARCHAR(200), -- "301,302,303"
    Noten VARCHAR(100)        -- "1.3,2.0,1.7"
);

-- Nachher: In 1NF (atomare Attribute)
CREATE TABLE Studenten_1NF (
    MatrikelNr INT PRIMARY KEY,
    Name VARCHAR(50),
    Semester INT
);

CREATE TABLE Belegungen_1NF (
    MatrikelNr INT,
    VorlesungNr INT,
    Note DECIMAL(3,1),
    PRIMARY KEY (MatrikelNr, VorlesungNr),
    FOREIGN KEY (MatrikelNr) REFERENCES Studenten_1NF(MatrikelNr)
);

-- Beispiel für atomare Werte
INSERT INTO Studenten_1NF VALUES (101, 'Max Mustermann', 5);
INSERT INTO Belegungen_1NF VALUES (101, 301, 1.3);
INSERT INTO Belegungen_1NF VALUES (101, 302, 2.0);

1NF mit JSON/XML (moderne Ansätze)

-- PostgreSQL Beispiel mit JSON
CREATE TABLE Studenten_Modern (
    MatrikelNr INT PRIMARY KEY,
    Name VARCHAR(50),
    Belegungen JSONB
);

INSERT INTO Studenten_Modern VALUES (
    101, 
    'Max Mustermann',
    '[
        {"vorlesungNr": 301, "note": 1.3},
        {"vorlesungNr": 302, "note": 2.0}
    ]'
);

-- Abfrage mit JSON-Funktionen
SELECT 
    MatrikelNr, 
    Name,
    vorlesung->>'vorlesungNr' AS Vorlesung,
    vorlesung->>'note' AS Note
FROM Studenten_Modern, 
     jsonb_array_elements(Belegungen) AS vorlesung
WHERE MatrikelNr = 101;

Zweite Normalform (2NF)

Definition und Regeln

Eine Relation ist in 2NF, wenn:

  1. Sie in 1NF ist
  2. Alle Nicht-Schlüsselattribute vollständig vom Primärschlüssel abhängen

Problem: Partielle Abhängigkeiten

-- Problem: Nicht in 2NF (partielle Abhängigkeiten)
CREATE TABLE Belegungen_Problem (
    MatrikelNr INT,
    VorlesungNr INT,
    StudentName VARCHAR(50),      -- Hängt nur von MatrikelNr ab
    VorlesungName VARCHAR(50),    -- Hängt nur von VorlesungNr ab
    DozentNr INT,                 -- Hängt nur von VorlesungNr ab
    Note DECIMAL(3,1),            -- Hängt von (MatrikelNr, VorlesungNr) ab
    PRIMARY KEY (MatrikelNr, VorlesungNr)
);

-- Partielle Abhängigkeiten:
-- MatrikelNr → StudentName (partiell)
-- VorlesungNr → VorlesungName, DozentNr (partiell)
-- (MatrikelNr, VorlesungNr) → Note (vollständig)

Umsetzung in 2NF

-- Aufteilung in 2NF
CREATE TABLE Studenten_2NF (
    MatrikelNr INT PRIMARY KEY,
    Name VARCHAR(50),
    Semester INT
);

CREATE TABLE Vorlesungen_2NF (
    VorlesungNr INT PRIMARY KEY,
    Name VARCHAR(50),
    DozentNr INT
);

CREATE TABLE Belegungen_2NF (
    MatrikelNr INT,
    VorlesungNr INT,
    Note DECIMAL(3,1),
    PRIMARY KEY (MatrikelNr, VorlesungNr),
    FOREIGN KEY (MatrikelNr) REFERENCES Studenten_2NF(MatrikelNr),
    FOREIGN KEY (VorlesungNr) REFERENCES Vorlesungen_2NF(VorlesungNr)
);

-- Beispieldaten
INSERT INTO Studenten_2NF VALUES (101, 'Max Mustermann', 5);
INSERT INTO Vorlesungen_2NF VALUES (301, 'Datenbanken', 501);
INSERT INTO Belegungen_2NF VALUES (101, 301, 1.3);

Überprüfung auf 2NF

-- Test auf partielle Abhängigkeiten
-- Für jedes Nicht-Schlüsselattribut prüfen:
-- Ist es vom gesamten Schlüssel abhängig?

-- Beispiel: StudentName
-- Abhängig von MatrikelNr? Ja
-- Abhängig von VorlesungNr? Nein
-- → Partielle Abhängigkeit → Nicht in 2NF

-- Beispiel: Note
-- Abhängig von MatrikelNr? Nein
-- Abhängig von VorlesungNr? Nein
-- Abhängig von (MatrikelNr, VorlesungNr)? Ja
-- → Volle Abhängigkeit → In 2NF

Dritte Normalform (3NF)

Definition und Regeln

Eine Relation ist in 3NF, wenn:

  1. Sie in 2NF ist
  2. Keine transitiven Abhängigkeiten von Nicht-Schlüsselattributen existieren

Problem: Transitive Abhängigkeiten

-- Problem: Nicht in 3NF (transitive Abhängigkeiten)
CREATE TABLE Dozenten_Problem (
    DozentenNr INT PRIMARY KEY,
    Name VARCHAR(50),
    Fachbereich VARCHAR(50),
    FachbereichLeiter VARCHAR(50)
);

-- Transitive Abhängigkeiten:
-- DozentenNr → Fachbereich
-- Fachbereich → FachbereichLeiter
-- DozentenNr → FachbereichLeiter (transitiv)

Umsetzung in 3NF

-- Aufteilung in 3NF
CREATE TABLE Dozenten_3NF (
    DozentenNr INT PRIMARY KEY,
    Name VARCHAR(50),
    Fachbereich VARCHAR(50)
);

CREATE TABLE Fachbereiche_3NF (
    Fachbereich VARCHAR(50) PRIMARY KEY,
    Leiter VARCHAR(50)
);

-- Beispieldaten
INSERT INTO Dozenten_3NF VALUES (501, 'Prof. Schmidt', 'Informatik');
INSERT INTO Fachbereiche_3NF VALUES ('Informatik', 'Prof. Dr. Meier');

Komplexes 3NF-Beispiel

-- Komplettes 3NF-Schema für Universität
CREATE TABLE Studenten (
    MatrikelNr INT PRIMARY KEY,
    Name VARCHAR(50) NOT NULL,
    Geburtsdatum DATE,
    Fachbereich VARCHAR(50)
);

CREATE TABLE Fachbereiche (
    Fachbereich VARCHAR(50) PRIMARY KEY,
    Dekan VARCHAR(50),
    Gebaeude VARCHAR(20)
);

CREATE TABLE Dozenten (
    DozentenNr INT PRIMARY KEY,
    Name VARCHAR(50) NOT NULL,
    Fachbereich VARCHAR(50),
    FOREIGN KEY (Fachbereich) REFERENCES Fachbereiche(Fachbereich)
);

CREATE TABLE Vorlesungen (
    VorlesungNr INT PRIMARY KEY,
    Titel VARCHAR(100) NOT NULL,
    DozentenNr INT,
    Fachbereich VARCHAR(50),
    FOREIGN KEY (DozentenNr) REFERENCES Dozenten(DozentenNr),
    FOREIGN KEY (Fachbereich) REFERENCES Fachbereiche(Fachbereich)
);

CREATE TABLE Belegungen (
    MatrikelNr INT,
    VorlesungNr INT,
    Semester INT,
    Note DECIMAL(3,1),
    PRIMARY KEY (MatrikelNr, VorlesungNr, Semester),
    FOREIGN KEY (MatrikelNr) REFERENCES Studenten(MatrikelNr),
    FOREIGN KEY (VorlesungNr) REFERENCES Vorlesungen(VorlesungNr)
);

Boyce-Codd Normalform (BCNF)

Definition und Regeln

Eine Relation ist in BCNF, wenn:

  1. Sie in 3NF ist
  2. Für jede Funktionsabhängigkeit X → Y gilt: X ist ein Superschlüssel

Problem: BCNF-Verletzung

-- Problem: Nicht in BCNF
CREATE TABLE Lehrveranstaltungen (
    DozentenNr INT,
    Fachbereich VARCHAR(50),
    VorlesungNr INT,
    PRIMARY KEY (DozentenNr, Fachbereich)
);

-- Daten:
-- 501, 'Informatik', 301
-- 501, 'Mathematik', 401
-- 502, 'Informatik', 302

-- Funktionsabhängigkeiten:
-- (DozentenNr, Fachbereich) → VorlesungNr (Primärschlüssel)
-- DozentenNr → Fachbereich (jeder Dozent gehört zu genau einem Fachbereich)

-- Problem: DozentenNr → Fachbereich
-- DozentenNr ist kein Superschlüssel → BCNF-Verletzung!

Umsetzung in BCNF

-- Aufteilung in BCNF
CREATE TABLE Dozenten_Fachbereich (
    DozentenNr INT PRIMARY KEY,
    Fachbereich VARCHAR(50)
);

CREATE TABLE Fachbereich_Vorlesungen (
    Fachbereich VARCHAR(50),
    DozentenNr INT,
    VorlesungNr INT,
    PRIMARY KEY (Fachbereich, DozentenNr)
);

-- Alternative BCNF-Lösung
CREATE TABLE Dozenten (
    DozentenNr INT PRIMARY KEY,
    Fachbereich VARCHAR(50)
);

CREATE TABLE Vorlesungen_Dozenten (
    VorlesungNr INT,
    DozentenNr INT,
    PRIMARY KEY (VorlesungNr, DozentenNr),
    FOREIGN KEY (DozentenNr) REFERENCES Dozenten(DozentenNr)
);

BCNF vs 3NF

-- Beispiel wo 3NF ≠ BCNF
CREATE TABLE Projektmitarbeiter (
    ProjektNr INT,
    MitarbeiterNr INT,
    Rolle VARCHAR(50),
    PRIMARY KEY (ProjektNr, MitarbeiterNr)
);

-- Annahme: Jeder Mitarbeiter hat in jedem Projekt genau eine Rolle
-- Aber: Ein Mitarbeiter kann die gleiche Rolle in verschiedenen Projekten haben

-- Funktionsabhängigkeiten:
-- (ProjektNr, MitarbeiterNr) → Rolle (Primärschlüssel)
-- MitarbeiterNr → Rolle (jeder Mitarbeiter hat eine feste Rolle)

-- BCNF-Verletzung: MitarbeiterNr → Rolle, aber MitarbeiterNr ist kein Superschlüssel

-- BCNF-Lösung:
CREATE TABLE Mitarbeiter_Rolle (
    MitarbeiterNr INT PRIMARY KEY,
    Rolle VARCHAR(50)
);

CREATE TABLE Projekt_Mitarbeiter (
    ProjektNr INT,
    MitarbeiterNr INT,
    PRIMARY KEY (ProjektNr, MitarbeiterNr),
    FOREIGN KEY (MitarbeiterNr) REFERENCES Mitarbeiter_Rolle(MitarbeiterNr)
);

Normalisierungsprozess

Schritt-für-Schritt-Anleitung

-- Schritt 0: Ausgangstabelle (nicht normalisiert)
CREATE TABLE Uni_Daten (
    MatrikelNr INT,
    StudentName VARCHAR(50),
    VorlesungNr INT,
    VorlesungName VARCHAR(50),
    DozentNr INT,
    DozentName VARCHAR(50),
    Fachbereich VARCHAR(50),
    Note DECIMAL(3,1),
    Semester INT
);

-- Schritt 1: 1NF - Atomare Werte
-- (bereits atomar in diesem Beispiel)

-- Schritt 2: 2NF - Partielle Abhängigkeiten eliminieren
CREATE TABLE Studenten_2NF (
    MatrikelNr INT PRIMARY KEY,
    Name VARCHAR(50),
    Semester INT
);

CREATE TABLE Vorlesungen_2NF (
    VorlesungNr INT PRIMARY KEY,
    Name VARCHAR(50),
    DozentNr INT,
    Fachbereich VARCHAR(50)
);

CREATE TABLE Noten_2NF (
    MatrikelNr INT,
    VorlesungNr INT,
    Note DECIMAL(3,1),
    PRIMARY KEY (MatrikelNr, VorlesungNr)
);

-- Schritt 3: 3NF - Transitive Abhängigkeiten eliminieren
CREATE TABLE Dozenten_3NF (
    DozentenNr INT PRIMARY KEY,
    Name VARCHAR(50),
    Fachbereich VARCHAR(50)
);

CREATE TABLE Fachbereiche_3NF (
    Fachbereich VARCHAR(50) PRIMARY KEY,
    -- Zusätzliche Fachbereichsinformationen
);

-- Finale 3NF-Struktur
CREATE TABLE Studenten (
    MatrikelNr INT PRIMARY KEY,
    Name VARCHAR(50),
    Semester INT
);

CREATE TABLE Fachbereiche (
    Fachbereich VARCHAR(50) PRIMARY KEY
);

CREATE TABLE Dozenten (
    DozentenNr INT PRIMARY KEY,
    Name VARCHAR(50),
    Fachbereich VARCHAR(50),
    FOREIGN KEY (Fachbereich) REFERENCES Fachbereiche(Fachbereich)
);

CREATE TABLE Vorlesungen (
    VorlesungNr INT PRIMARY KEY,
    Name VARCHAR(50),
    DozentenNr INT,
    Fachbereich VARCHAR(50),
    FOREIGN KEY (DozentenNr) REFERENCES Dozenten(DozentenNr),
    FOREIGN KEY (Fachbereich) REFERENCES Fachbereiche(Fachbereich)
);

CREATE TABLE Belegungen (
    MatrikelNr INT,
    VorlesungNr INT,
    Note DECIMAL(3,1),
    PRIMARY KEY (MatrikelNr, VorlesungNr),
    FOREIGN KEY (MatrikelNr) REFERENCES Studenten(MatrikelNr),
    FOREIGN KEY (VorlesungNr) REFERENCES Vorlesungen(VorlesungNr)
);

Normalisierungs-Algorithmen

Synthese-Algorithmus

-- Funktionsabhängigkeiten analysieren
-- F = {MatrikelNr → Name, VorlesungNr → Titel, DozentNr → Name, 
--       (MatrikelNr, VorlesungNr) → Note}

-- Schritt 1: Minimale Überdeckung finden
-- F_min = {MatrikelNr → Name, VorlesungNr → Titel, 
--          DozentNr → Name, (MatrikelNr, VorlesungNr) → Note}

-- Schritt 2: Gruppieren nach linker Seite
-- Gruppe 1: MatrikelNr → Name → Relation Studenten(MatrikelNr, Name)
-- Gruppe 2: VorlesungNr → Titel → Relation Vorlesungen(VorlesungNr, Titel)
-- Gruppe 3: DozentNr → Name → Relation Dozenten(DozentenNr, Name)
-- Gruppe 4: (MatrikelNr, VorlesungNr) → Note → Relation Noten(MatrikelNr, VorlesungNr, Note)

-- Schritt 3: Kandidatenschlüssel bestimmen und ergänzen
-- Kandidatenschlüssel: (MatrikelNr, VorlesungNr) für Noten
-- Andere Relationen haben ihre eigenen Primärschlüssel

Dekompositions-Algorithmus

-- Ausgangstabelle mit Anomalien
CREATE TABLE Probleme (
    A INT,
    B INT,
    C INT,
    D INT,
    PRIMARY KEY (A, B)
);

-- Funktionsabhängigkeiten: A → C, B → D

-- Schritt 1: Prüfen auf 2NF
-- C hängt nur von A ab (partiell) → aufteilen
CREATE TABLE R1 (A INT PRIMARY KEY, C INT);
CREATE TABLE R2 (A INT, B INT, D INT, PRIMARY KEY (A, B));

-- Schritt 2: Prüfen auf 3NF
-- In R2: B → D (transitiv über (A,B) → B) → aufteilen
CREATE TABLE R3 (B INT PRIMARY KEY, D INT);
CREATE TABLE R4 (A INT, B INT, PRIMARY KEY (A, B));

-- Finale 3NF-Struktur
-- R1(A, C), R3(B, D), R4(A, B)

Praktische Beispiele

E-Commerce Datenbank

-- Normalisiertes E-Commerce Schema
CREATE TABLE Kunden (
    KundenNr INT PRIMARY KEY,
    Name VARCHAR(50),
    Email VARCHAR(100) UNIQUE,
    Adresse VARCHAR(200),
    Stadt VARCHAR(50),
    PLZ VARCHAR(10)
);

CREATE TABLE Kategorien (
    KategorieNr INT PRIMARY KEY,
    Name VARCHAR(50),
    Beschreibung TEXT
);

CREATE TABLE Produkte (
    ProduktNr INT PRIMARY KEY,
    Name VARCHAR(100),
    Preis DECIMAL(10,2),
    Beschreibung TEXT,
    KategorieNr INT,
    Lagerbestand INT,
    FOREIGN KEY (KategorieNr) REFERENCES Kategorien(KategorieNr)
);

CREATE TABLE Bestellungen (
    BestellNr INT PRIMARY KEY,
    KundenNr INT,
    Bestelldatum DATE,
    Gesamtsumme DECIMAL(10,2),
    Status VARCHAR(20),
    FOREIGN KEY (KundenNr) REFERENCES Kunden(KundenNr)
);

CREATE TABLE Bestellpositionen (
    BestellNr INT,
    ProduktNr INT,
    Menge INT,
    Einzelpreis DECIMAL(10,2),
    PRIMARY KEY (BestellNr, ProduktNr),
    FOREIGN KEY (BestellNr) REFERENCES Bestellungen(BestellNr),
    FOREIGN KEY (ProduktNr) REFERENCES Produkte(ProduktNr)
);

Bibliotheks-System

-- Normalisiertes Bibliotheks-Schema
CREATE TABLE Autoren (
    AutorNr INT PRIMARY KEY,
    Name VARCHAR(50),
    Geburtsjahr INT
);

CREATE TABLE Buecher (
    BuchNr INT PRIMARY KEY,
    Titel VARCHAR(100),
    ISBN VARCHAR(20) UNIQUE,
    Erscheinungsjahr INT,
    Verlag VARCHAR(50)
);

CREATE TABLE Buch_Autoren (
    BuchNr INT,
    AutorNr INT,
    PRIMARY KEY (BuchNr, AutorNr),
    FOREIGN KEY (BuchNr) REFERENCES Buecher(BuchNr),
    FOREIGN KEY (AutorNr) REFERENCES Autoren(AutorNr)
);

CREATE TABLE Leser (
    Lesernummer INT PRIMARY KEY,
    Name VARCHAR(50),
    Adresse VARCHAR(200),
    Telefon VARCHAR(20)
);

CREATE TABLE Exemplare (
    ExemplarNr INT PRIMARY KEY,
    BuchNr INT,
    Status VARCHAR(20),
    FOREIGN KEY (BuchNr) REFERENCES Buecher(BuchNr)
);

CREATE TABLE Ausleihen (
    AusleihNr INT PRIMARY KEY,
    Lesernummer INT,
    ExemplarNr INT,
    Ausleihdatum DATE,
    Rueckgabedatum DATE,
    FOREIGN KEY (Lesernummer) REFERENCES Leser(Lesernummer),
    FOREIGN KEY (ExemplarNr) REFERENCES Exemplare(ExemplarNr)
);

Denormalisierung

Wann und warum denormalisieren?

-- Performance-optimiertes Schema (denormalisiert)
CREATE TABLE Produkt_Statistiken (
    ProduktNr INT PRIMARY KEY,
    Name VARCHAR(100),
    Preis DECIMAL(10,2),
    KategorieName VARCHAR(50),    -- Denormalisiert
    KategorieBeschreibung TEXT,  -- Denormalisiert
    GesamtVerkaufsmenge INT,      -- Denormalisiert (Aggregat)
    LetzteBestellung DATE         -- Denormalisiert (Aggregat)
);

-- Vorteile:
-- Weniger JOINs erforderlich
-- Schnellere Abfragen
-- Bessere Read-Performance

-- Nachteile:
-- Redundanz
-- Update-Anomalien
-- Mehr Speicherbedarf

Strategien zur Denormalisierung

-- 1. Vorberechnete Aggregate
CREATE TABLE Monatsverkaufe (
    Monat DATE,
    ProduktNr INT,
    Verkaufsmenge INT,
    Umsatz DECIMAL(12,2),
    PRIMARY KEY (Monat, ProduktNr)
);

-- 2. Kopierte Attribute
CREATE TABLE Bestellungen_Kurz (
    BestellNr INT PRIMARY KEY,
    KundenName VARCHAR(50),      -- Kopiert von Kunden
    KundenEmail VARCHAR(100),    -- Kopiert von Kunden
    Bestelldatum DATE,
    Gesamtsumme DECIMAL(10,2)
);

-- 3. Hierarchische Daten
CREATE TABLE Mitarbeiter_Hierarchie (
    MitarbeiterNr INT PRIMARY KEY,
    Name VARCHAR(50),
    VorgesetzterNr INT,
    Pfad VARCHAR(200),           -- Denormalisierter Pfad
    Ebene INT                    -- Denormalisierte Tiefe
);

Prüfungsrelevante Konzepte

Wichtige Definitionen

  1. Funktionsabhängigkeit: X → Y bedeutet Y hängt von X ab
  2. Vollständige Abhängigkeit: Y hängt von ganzem X ab
  3. Partielle Abhängigkeit: Y hängt von Teil von X ab
  4. Transitive Abhängigkeit: X → Y und Y → Z ⇒ X → Z

Normalformen im Überblick

NormalformHauptproblemLösung
1NFWiederholte GruppenAtomare Werte
2NFPartielle AbhängigkeitenAufteilung nach Schlüsseln
3NFTransitive AbhängigkeitenEliminierung von Transitivität
BCNFNicht-Schlüssel-DeterminantenJede Determinant ist Superschlüssel

Typische Prüfungsaufgaben

  1. Identifizieren Sie Funktionsabhängigkeiten
  2. Normalisieren Sie gegebene Relationen
  3. Erklären Sie Anomalien und ihre Ursachen
  4. Vergleichen Sie Normalformen
  5. Entscheiden Sie über Denormalisierung

Zusammenfassung

Normalisierung ist fundamental für qualitativ hochwertige Datenbankdesigns:

  • 1NF: Atomare Werte und eindeutige Zeilen
  • 2NF: Eliminiert partielle Abhängigkeiten
  • 3NF: Eliminiert transitive Abhängigkeiten
  • BCNF: Stärkste Normalform für praktische Anwendung

Die richtige Balance zwischen Normalisierung und Performance ist entscheidend für erfolgreiche Datenbanksysteme.

Zurück zum Blog
Share:

Ähnliche Beiträge