Zum Inhalt

M165 Fragenkatalog - Vollständige Antworten

M165 01 Aktivierung Vorwissen

Einfache Fragen

Frage 1: Daten, Informationen und Wissen

Daten sind unverarbeitete, rohe Fakten und Zeichen ohne direkten Kontext oder Bedeutung. Sie sind die Grundbausteine der Informationsverarbeitung.

Unterschiede:

  • Daten: Rohe Fakten (z.B. "42", "Berlin", "15.01.2026")
  • Informationen: Daten in einem Kontext, die eine Bedeutung haben (z.B. "Die Temperatur in Berlin beträgt 42°C am 15.01.2026")
  • Wissen: Verarbeitete und verstandene Informationen, die mit Erfahrung und Kontext verbunden sind (z.B. "42°C im Januar ist ungewöhnlich warm für Berlin und könnte auf Klimaveränderungen hindeuten")

Merkhilfe

Daten → Informationen → Wissen stellt eine Hierarchie dar, bei der jede Stufe mehr Kontext und Bedeutung hinzufügt.

Frage 2: Unterschied relationalen Datenbanken und NoSQL-Datenbanken

Relationale Datenbanken:

  • Strukturierte Daten in Tabellen mit Zeilen und Spalten
  • Festes Schema (Schema-on-Write)
  • SQL als Abfragesprache
  • ACID-Eigenschaften (Atomicity, Consistency, Isolation, Durability)
  • Vertikale Skalierung
  • Beispiele: MySQL, PostgreSQL, Oracle

NoSQL-Datenbanken:

  • Flexible Datenmodelle (Dokumente, Key-Value, Graphen, Column-Stores)
  • Dynamisches Schema (Schema-on-Read)
  • Verschiedene Abfragesprachen
  • BASE-Eigenschaften (Basically Available, Soft state, Eventual consistency)
  • Horizontale Skalierung
  • Beispiele: MongoDB, Cassandra, Redis, Neo4j

Wichtig

Die Wahl zwischen relational und NoSQL hängt von den Anforderungen ab: Strukturierte Daten mit komplexen Beziehungen → relational; große Datenmengen mit flexiblem Schema → NoSQL.

Frage 3: Datenqualität

Bedeutung: Datenqualität bestimmt, wie gut Daten für ihren beabsichtigten Zweck geeignet sind. Schlechte Datenqualität führt zu fehlerhaften Analysen und Entscheidungen.

Vier wichtige Aspekte:

  1. Vollständigkeit: Alle erforderlichen Daten sind vorhanden
  2. Korrektheit: Daten sind fehlerfrei und genau
  3. Konsistenz: Daten sind widerspruchsfrei über verschiedene Systeme hinweg
  4. Aktualität: Daten sind zeitgemäß und auf dem neuesten Stand

Auswirkungen

Schlechte Datenqualität kann zu Fehlentscheidungen, Kundenunzufriedenheit und finanziellen Verlusten führen.

Frage 4: IT-Administrator in der Filmdatenbank

Rolle:

Der IT-Administrator ist für die technische Verwaltung und Sicherheit der gesamten Datenbank verantwortlich.

Berechtigungen:

  • Vollständiger Zugriff auf alle Datenbanken und Collections
  • Erstellen und Löschen von Datenbanken
  • Benutzerverwaltung (Erstellen, Ändern, Löschen von Benutzerkonten)
  • Rechtevergabe an andere Benutzer
  • Backup und Wiederherstellung
  • Performance-Monitoring und Optimierung
  • Sicherheitskonfiguration

Mittelschwere Fragen

Frage 5: Abstraktion in der Datenverarbeitung

Konzept:

Abstraktion bedeutet, komplexe Details zu verbergen und nur die wesentlichen Informationen darzustellen.

Verwendung in der Datenverarbeitung:

  • Datenabstraktion: Verstecken der physischen Speicherung von Daten
  • Schichtenmodell: Trennung von logischer und physischer Ebene
  • APIs: Bereitstellung einfacher Schnittstellen für komplexe Operationen
  • Datenmodelle: Vereinfachte Darstellung realer Objekte

Beispiel

Ein Benutzer arbeitet mit einer Tabelle "Kunden", ohne wissen zu müssen, wie die Daten physisch auf der Festplatte gespeichert sind.

Frage 6: Redundanz in Datenbanken

Bedeutung:

Redundanz bezeichnet das mehrfache Vorhandensein identischer Daten an verschiedenen Stellen in der Datenbank.

Probleme:

  1. Inkonsistenz: Bei Updates können Daten an verschiedenen Stellen unterschiedlich sein
  2. Speicherplatzverschwendung: Unnötiger Verbrauch von Speicherressourcen
  3. Wartungsaufwand: Mehrfacher Aufwand bei Änderungen
  4. Fehleranfälligkeit: Höheres Risiko für Datenfehler

Lösung

Normalisierung hilft, Redundanz zu reduzieren, allerdings kann kontrollierte Redundanz in NoSQL-Datenbanken zur Performance-Steigerung eingesetzt werden.

Frage 7: Normalisierung

Definition:

Normalisierung ist ein Prozess zur Organisation von Daten in relationalen Datenbanken, um Redundanz zu minimieren und Datenintegrität zu gewährleisten.

Drei wichtigste Normalformen:

  1. Erste Normalform (1NF):
  2. Alle Attribute enthalten nur atomare Werte
  3. Keine sich wiederholenden Gruppen
  4. Jede Zeile ist eindeutig identifizierbar

  5. Zweite Normalform (2NF):

  6. Erfüllt 1NF
  7. Alle Nicht-Schlüssel-Attribute sind vollständig vom gesamten Primärschlüssel abhängig
  8. Keine partiellen Abhängigkeiten

  9. Dritte Normalform (3NF):

  10. Erfüllt 2NF
  11. Keine transitiven Abhängigkeiten
  12. Nicht-Schlüssel-Attribute hängen direkt vom Primärschlüssel ab

Frage 8: Verwaltungspersonal in der Filmdatenbank

Rolle:

Das Verwaltungspersonal ist für die tägliche Pflege und Verwaltung der Filmdaten zuständig.

Berechtigungen:

  • Lesen von Filmdaten, Auszeichnungen, Kommentaren
  • Einfügen neuer Filme und Auszeichnungen
  • Aktualisieren bestehender Filminformationen
  • Löschen von veralteten oder fehlerhaften Einträgen
  • Keine Berechtigungen für:
  • Systemkonfiguration
  • Benutzerverwaltung
  • Datenbankstrukturänderungen

Prinzip der minimalen Rechte

Verwaltungspersonal erhält nur die Rechte, die für ihre tägliche Arbeit notwendig sind.

Schwere Fragen

Frage 9: NewSQL-Datenbanken

NewSQL-Datenbanken:

NewSQL-Datenbanken kombinieren die ACID-Garantien relationaler Datenbanken mit der horizontalen Skalierbarkeit von NoSQL-Datenbanken.

Unterschiede:

Aspekt Relational NoSQL NewSQL
ACID Teilweise
Skalierung Vertikal Horizontal Horizontal
SQL-Support
Schema Fest Flexibel Fest
Konsistenz Strong Eventual Strong

Vorteile von NewSQL:

  • Beste Eigenschaften beider Welten
  • ACID-Transaktionen bei hoher Skalierbarkeit
  • SQL-Unterstützung mit moderner Architektur
  • Beispiele: Google Spanner, CockroachDB, VoltDB

Frage 10: Rollenkonzept und Datensicherheit

Bedeutung:

Das Rollenkonzept ist ein zentrales Element der Zugriffskontrolle in Datenbanken.

Funktionsweise:

  1. Rollendefinition: Rollen werden basierend auf Aufgaben definiert
  2. Rechtezuweisung: Berechtigungen werden Rollen zugewiesen
  3. Benutzerzuordnung: Benutzer werden Rollen zugeordnet
  4. Vererbung: Rollen können hierarchisch strukturiert sein

Vorteile für Datensicherheit:

  • Prinzip der minimalen Rechte: Benutzer erhalten nur notwendige Berechtigungen
  • Vereinfachte Verwaltung: Zentrale Verwaltung von Berechtigungen
  • Nachvollziehbarkeit: Klare Zuordnung von Zugriffsrechten
  • Compliance: Erfüllung gesetzlicher Anforderungen

Beispiel

  • Rolle "Leser": nur SELECT-Rechte
  • Rolle "Editor": SELECT, INSERT, UPDATE
  • Rolle "Admin": Vollzugriff

Frage 11: Datensicherheitskonzepte für Unternehmen

Bedeutung:

Datensicherheitskonzepte schützen sensible Unternehmensdaten vor unbefugtem Zugriff, Verlust und Missbrauch.

Wichtige Aspekte:

  1. Vertraulichkeit: Schutz vor unbefugtem Zugriff
  2. Integrität: Schutz vor unberechtigten Änderungen
  3. Verfügbarkeit: Sicherstellung des Zugriffs für berechtigte Nutzer
  4. Authentifizierung: Überprüfung der Benutzeridentität
  5. Autorisierung: Kontrolle der Zugriffsrechte
  6. Verschlüsselung: Schutz der Daten bei Übertragung und Speicherung

Konsequenzen bei Nichteinhaltung:

  • Finanzielle Schäden: Bußgelder (DSGVO bis 20 Mio. € oder 4% des Umsatzes)
  • Reputationsverlust: Vertrauensverlust bei Kunden
  • Rechtliche Konsequenzen: Klagen, Haftung
  • Betriebsunterbrechungen: Systemausfälle
  • Datenverlust: Unwiederbringlicher Verlust kritischer Daten

DSGVO

Die Datenschutz-Grundverordnung sieht bei Verstößen erhebliche Strafen vor!

Frage 12: Rollenspiel zur Verdeutlichung von Rollen und Berechtigungen

Szenario: Fitnesscenter-Datenbank

Durchführung:

  1. Rollen definieren:
  2. Mitglieder: Zugriff auf eigene Daten
  3. Trainer: Zugriff auf Trainingspläne und Mitgliederdaten
  4. Rezeption: Verwaltung von Mitgliedschaften
  5. Manager: Zugriff auf Finanzdaten und Berichte
  6. IT-Admin: Systemverwaltung

  7. Szenarien durchspielen:

  8. Mitglied möchte Trainingsplan einsehen
  9. Trainer aktualisiert Trainingsplan
  10. Rezeption registriert neues Mitglied
  11. Manager erstellt Umsatzbericht
  12. Unbefugter Zugriff wird verhindert

  13. Lernziele:

  14. Verständnis für unterschiedliche Zugriffsbedürfnisse
  15. Bedeutung von Zugriffskontrollen
  16. Auswirkungen falscher Berechtigungen
  17. Datenschutz und Compliance

Didaktischer Wert

Durch das Rollenspiel werden abstrakte Konzepte erlebbar und verständlich.


M165 02 NoSQL-Grundlagen

Einfache Fragen

Frage 1: Hauptunterschiede zwischen relationalen und NoSQL-Datenbanken

Relationale Datenbanken:

  • Tabellenbasierte Struktur
  • Festes Schema vor Dateneingabe
  • SQL als standardisierte Abfragesprache
  • ACID-Transaktionen
  • Vertikale Skalierung (mehr Rechenleistung pro Server)
  • Relationen über Foreign Keys
  • Normalisierte Daten

NoSQL-Datenbanken:

  • Flexible Datenmodelle (Dokument, Key-Value, Graph, Column)
  • Schema-on-Read oder schemalos
  • Verschiedene Abfragemethoden
  • BASE-Eigenschaften (eventual consistency)
  • Horizontale Skalierung (mehr Server)
  • Denormalisierte Daten mit Embedded Documents
  • Hohe Performance bei großen Datenmengen

Wann was nutzen?

Relational: Komplexe Beziehungen, Transaktionen, strukturierte Daten
NoSQL: Große Datenmengen, flexible Schemas, hohe Skalierbarkeit

Frage 2: CAP-Theorem

Definition:

Das CAP-Theorem (auch Brewer's Theorem) besagt, dass ein verteiltes Datensystem maximal zwei der drei folgenden Eigenschaften gleichzeitig garantieren kann:

  1. Consistency (Konsistenz):
  2. Alle Knoten sehen zur gleichen Zeit die gleichen Daten
  3. Jede Leseoperation liefert die aktuellsten geschriebenen Daten

  4. Availability (Verfügbarkeit):

  5. Jede Anfrage erhält eine Antwort (Erfolg oder Fehler)
  6. System bleibt auch bei Ausfällen verfügbar

  7. Partition Tolerance (Partitionstoleranz):

  8. System funktioniert trotz Netzwerkausfällen zwischen Knoten
  9. Aufteilung des Netzwerks wird toleriert

Trade-off

In der Praxis muss immer ein Kompromiss eingegangen werden, da Netzwerkpartitionen in verteilten Systemen unvermeidbar sind.

Frage 3: Vier Haupttypen von NoSQL-Datenbanken

  1. Key-Value-Datenbanken:
  2. Einfachstes Modell: Schlüssel → Wert
  3. Sehr schnell für einfache Operationen
  4. Beispiele: Redis, Amazon DynamoDB, Riak
  5. Anwendung: Caching, Session-Management

  6. Dokumentenorientierte Datenbanken:

  7. Dokumente (JSON, BSON, XML) als Dateneinheiten
  8. Flexible Schemas
  9. Beispiele: MongoDB, CouchDB
  10. Anwendung: Content-Management, E-Commerce

  11. Column-Family-Datenbanken:

  12. Daten in Spaltenfamilien organisiert
  13. Optimiert für Schreib- und Leseoperationen auf Spalten
  14. Beispiele: Apache Cassandra, HBase
  15. Anwendung: Analytics, Time-Series-Daten

  16. Graph-Datenbanken:

  17. Knoten und Kanten zur Darstellung von Beziehungen
  18. Optimiert für Beziehungsabfragen
  19. Beispiele: Neo4j, Amazon Neptune
  20. Anwendung: Social Networks, Empfehlungssysteme

Frage 4: Vorteile von JSON im Vergleich zu XML

JSON-Vorteile:

Aspekt JSON XML
Lesbarkeit Kompakter und übersichtlicher Verbose, viele Tags
Dateigröße Kleiner (ca. 30% weniger) Größer durch Tags
Parsing Schneller Langsamer
Datentypen Native Unterstützung (String, Number, Boolean, Array, Object) Alles ist Text
JavaScript Native Integration Zusätzliche Parser nötig

JSON-Beispiel:

{
  "name": "Max Mustermann",
  "age": 30,
  "active": true
}

XML-Beispiel:

<person>
  <name>Max Mustermann</name>
  <age>30</age>
  <active>true</active>
</person>

Wann XML?

XML bietet Vorteile bei komplexen Dokumenten mit Metadaten, Namespaces und Schema-Validierung (XSD).

Mittelschwere Fragen

Frage 5: Vorteile und Herausforderungen von NoSQL in großen Anwendungen

Vorteile:

  1. Skalierbarkeit:
  2. Horizontale Skalierung durch Hinzufügen von Servern
  3. Kostengünstigere Commodity-Hardware
  4. Linear wachsende Performance

  5. Flexibilität:

  6. Schema-Änderungen ohne Downtime
  7. Verschiedene Datenstrukturen in einer Datenbank
  8. Schnelle Anpassung an neue Anforderungen

  9. Performance:

  10. Hoher Durchsatz bei Lese- und Schreiboperationen
  11. Optimiert für spezifische Use Cases
  12. Effizientes Handling großer Datenmengen

  13. Verfügbarkeit:

  14. Replikation über mehrere Standorte
  15. Keine Single Points of Failure
  16. Hohe Ausfallsicherheit

Herausforderungen:

  1. Konsistenz:
  2. Eventual Consistency erfordert Anwendungslogik
  3. Komplexität bei verteilten Transaktionen
  4. Mögliche temporäre Inkonsistenzen

  5. Komplexität:

  6. Verschiedene Systeme für verschiedene Anwendungsfälle
  7. Fehlendes einheitliches Query-Interface
  8. Höherer Lernaufwand

  9. Tooling:

  10. Weniger ausgereifte Tools als bei SQL
  11. Monitoring und Management anspruchsvoller
  12. Weniger Standardisierung

  13. Datenmodellierung:

  14. Erfordert Umdenken von relationalen Konzepten
  15. Denormalisierung kann zu Redundanz führen
  16. Abfragemuster müssen im Voraus bekannt sein

Frage 6: Datenmodellierung in MongoDB

Grundprinzipien:

MongoDB verwendet ein flexibles, dokumentenbasiertes Modell mit BSON (Binary JSON).

Modellierungsstrategien:

  1. Embedded Documents (Einbettung):
    {
      "_id": 1,
      "title": "Inception",
      "year": 2010,
      "cast": [
        {"name": "Leonardo DiCaprio", "role": "Cobb"},
        {"name": "Ellen Page", "role": "Ariadne"}
      ],
      "ratings": {
        "imdb": 8.8,
        "tomatoes": 87
      }
    }
    
  2. Vorteile: Schneller Zugriff, atomare Updates
  3. Nachteile: Dokumentgröße begrenzt (16 MB), Redundanz

  4. Referenzen (References):

    // Film-Dokument
    {
      "_id": 1,
      "title": "Inception",
      "director_id": 101
    }
    
    // Regisseur-Dokument
    {
      "_id": 101,
      "name": "Christopher Nolan"
    }
    

  5. Vorteile: Keine Redundanz, flexible Updates
  6. Nachteile: Mehrere Abfragen nötig

Entscheidungskriterien:

  • Embed wenn: 1:1 oder 1:wenige Beziehungen, Daten werden zusammen gelesen
  • Reference wenn: 1:viele oder viele:viele Beziehungen, Daten werden unabhängig aktualisiert

Schema Design

In MongoDB ist das Schema-Design abfrageorientiert: "Design your schema based on how you query your data!"

Frage 7: Eventual Consistency

Definition:

Eventual Consistency (eventuelle Konsistenz) ist ein Konsistenzmodell in verteilten Systemen, bei dem garantiert wird, dass alle Knoten letztendlich den gleichen Datenstand haben werden, wenn keine neuen Updates erfolgen.

Funktionsweise:

  1. Schreiboperation: Daten werden auf einem Knoten aktualisiert
  2. Replikation: Änderungen werden asynchron an andere Knoten verteilt
  3. Zwischenzustand: Verschiedene Knoten haben temporär unterschiedliche Datenstände
  4. Konvergenz: Nach einiger Zeit haben alle Knoten den gleichen Stand

Beispiel:

Zeit | Knoten A | Knoten B | Knoten C
-----|----------|----------|----------
t0   | v1       | v1       | v1
t1   | v2       | v1       | v1       (Update auf A)
t2   | v2       | v2       | v1       (Replikation zu B)
t3   | v2       | v2       | v2       (Replikation zu C)

Vor- und Nachteile:

✓ Höhere Verfügbarkeit
✓ Bessere Performance
✓ Partitionstoleranz
✗ Temporäre Inkonsistenzen
✗ Komplexere Anwendungslogik nötig

Anwendungsfall

Social Media: Es ist akzeptabel, wenn ein Like einige Sekunden später für alle Nutzer sichtbar wird.

Frage 8: CP-, AP- und CA-Datenbanken nach CAP-Theorem

CP-Datenbanken (Consistency + Partition Tolerance):

  • Priorisieren Konsistenz über Verfügbarkeit
  • Bei Netzwerkpartition: Einige Anfragen werden abgelehnt
  • Beispiele: MongoDB, HBase, Redis
  • Anwendung: Finanzsysteme, Inventarverwaltung

Eigenschaften:

Netzwerkpartition → System verweigert Schreibzugriff
Vorteil: Garantierte Konsistenz
Nachteil: Reduzierte Verfügbarkeit

AP-Datenbanken (Availability + Partition Tolerance):

  • Priorisieren Verfügbarkeit über Konsistenz
  • Bei Netzwerkpartition: Alle Knoten bleiben verfügbar
  • Beispiele: Cassandra, CouchDB, DynamoDB
  • Anwendung: Social Media, Analytics

Eigenschaften:

Netzwerkpartition → Alle Knoten antworten
Vorteil: Maximale Verfügbarkeit
Nachteil: Eventual Consistency

CA-Datenbanken (Consistency + Availability):

  • Theoretisches Konstrukt ohne Partitionstoleranz
  • In der Praxis nicht realisierbar in verteilten Systemen
  • Beispiele: Traditionelle relationale Single-Server-DBs
  • Anwendung: Lokale Systeme ohne Verteilung

Wichtig

In verteilten Systemen sind Netzwerkpartitionen unvermeidbar, daher ist CA praktisch nicht umsetzbar. Die Wahl ist immer zwischen CP und AP.

Schwere Fragen

Frage 9: Vor- und Nachteile der Denormalisierung in NoSQL

Denormalisierung:

Das bewusste Einführen von Redundanz durch Einbettung zusammenhängender Daten in ein Dokument.

Vorteile:

  1. Performance:
  2. Weniger Joins nötig (in MongoDB oft keine Joins)
  3. Daten werden in einem Read-Vorgang geladen
  4. Reduzierte Latenz

  5. Atomare Operationen:

  6. Updates auf ein Dokument sind atomar
  7. Keine Transaktionen über mehrere Collections nötig
  8. Einfachere Konsistenzgarantien

  9. Skalierbarkeit:

  10. Besser geeignet für horizontale Skalierung
  11. Daten einer Entität bleiben zusammen
  12. Reduzierte Netzwerkkommunikation

Beispiel:

{
  "_id": 1,
  "title": "The Matrix",
  "director": {
    "name": "Lana Wachowski",
    "born": 1965,
    "nationality": "American"
  },
  "actors": [
    {"name": "Keanu Reeves", "role": "Neo"},
    {"name": "Laurence Fishburne", "role": "Morpheus"}
  ]
}

Nachteile:

  1. Datenredundanz:
  2. Gleiche Daten an mehreren Stellen
  3. Erhöhter Speicherbedarf
  4. Schwierigere Datenpflege

  5. Update-Anomalien:

  6. Änderungen müssen an mehreren Stellen durchgeführt werden
  7. Risiko inkonsistenter Daten
  8. Komplexere Update-Logik

  9. Dokumentgröße:

  10. MongoDB-Limit: 16 MB pro Dokument
  11. Performance-Einbußen bei sehr großen Dokumenten
  12. Netzwerk-Overhead

  13. Flexibilität:

  14. Änderungen am Datenmodell aufwendiger
  15. Schwierigere Reorganisation
  16. Abfragemuster müssen bekannt sein

Best Practice

Denormalisieren Sie basierend auf Zugriffsmustern: Daten, die zusammen gelesen werden, sollten zusammen gespeichert werden.

Frage 10: Datenintegrität in NoSQL ohne vollständige ACID-Eigenschaften

Herausforderungen:

NoSQL-Datenbanken opfern oft ACID-Garantien für Skalierbarkeit und Performance.

Strategien zur Sicherstellung der Datenintegrität:

  1. Dokumenten-Level Atomicity:
  2. MongoDB garantiert ACID auf Dokumentebene
  3. Nutzen Sie eingebettete Dokumente für zusammenhängende Daten

    db.accounts.updateOne(
      { _id: 123 },
      { $inc: { balance: -100 }, $push: { transactions: {...} } }
    )
    

  4. Multi-Document Transactions (ab MongoDB 4.0):

    session.startTransaction();
    try {
      db.accounts.updateOne({ _id: 1 }, { $inc: { balance: -100 } }, { session });
      db.accounts.updateOne({ _id: 2 }, { $inc: { balance: 100 } }, { session });
      session.commitTransaction();
    } catch (error) {
      session.abortTransaction();
    }
    

  5. Schema Validation:

    db.createCollection("users", {
      validator: {
        $jsonSchema: {
          required: ["name", "email"],
          properties: {
            email: { bsonType: "string", pattern: "^.+@.+$" }
          }
        }
      }
    })
    

  6. Application-Level Consistency:

  7. Implementierung von Geschäftslogik in der Anwendung
  8. Two-Phase Commit Patterns
  9. Saga Pattern für verteilte Transaktionen
  10. Compensating Transactions

  11. Write Concerns:

    db.collection.insertOne(
      { ... },
      { writeConcern: { w: "majority", j: true } }
    )
    

  12. Read Concerns:

    db.collection.find().readConcern("majority")
    

  13. Idempotente Operationen:

  14. Operationen so designen, dass mehrfaches Ausführen das gleiche Ergebnis liefert
  15. Verwendung von eindeutigen IDs

Best Practices

  • Nutzen Sie Schema Validation für kritische Felder
  • Implementieren Sie Retry-Logik mit Exponential Backoff
  • Verwenden Sie Unique Indexes für Eindeutigkeit
  • Loggen Sie alle kritischen Operationen

Frage 11: Indizes in NoSQL vs. relationalen Datenbanken

Rolle von Indizes:

Indizes beschleunigen Suchabfragen, indem sie einen schnellen Zugriffspfad zu den Daten bereitstellen.

Indizes in NoSQL (MongoDB):

  1. Single Field Index:

    db.movies.createIndex({ title: 1 })  // 1 = aufsteigend
    

  2. Compound Index:

    db.movies.createIndex({ year: -1, rating: -1 })
    

  3. Multikey Index:

    db.movies.createIndex({ genres: 1 })  // Array-Feld
    

  4. Text Index:

    db.movies.createIndex({ plot: "text" })
    

  5. Geospatial Index:

    db.locations.createIndex({ location: "2dsphere" })
    

Unterschiede zu relationalen Datenbanken:

Aspekt Relational NoSQL (MongoDB)
Array-Unterstützung Nein Ja (Multikey)
Nested Fields Nein Ja (mit Dot-Notation)
Text-Suche Full-Text mit Einschränkungen Native Text-Indizes
Geospatial Mit Erweiterungen Native Unterstützung
Flexibilität Schema-abhängig Sparse Indexes möglich

Besonderheiten in MongoDB:

  • Sparse Indexes: Nur Dokumente mit dem Feld werden indiziert
  • TTL Indexes: Automatisches Löschen nach Zeit
  • Partial Indexes: Nur Dokumente die Filter erfüllen
  • Covered Queries: Query wird komplett aus Index beantwortet

Performance

Zu viele Indizes verlangsamen Schreiboperationen. Erstellen Sie Indizes basierend auf tatsächlichen Query-Mustern.

Frage 12: Anwendungsfälle für verschiedene NoSQL-Typen

1. Key-Value Stores

Eigenschaften: - Einfachstes Datenmodell - Sehr hohe Performance - Horizontale Skalierbarkeit

Anwendungsfälle: - Session-Speicherung: User-Sessions in Webanwendungen - Caching: Zwischenspeicherung von DB-Abfragen, API-Responses - Shopping Carts: E-Commerce Warenkörbe - User Preferences: Einstellungen und Konfigurationen - Real-time Recommendations: Produkt-Empfehlungen

Beispiel (Redis):

SET user:1000:session "token123abc"
GET user:1000:session

2. Document Stores

Eigenschaften: - JSON/BSON Dokumente - Flexible Schemas - Abfragen auf verschachtelten Strukturen

Anwendungsfälle: - Content Management Systeme: Blog-Posts, Artikel - E-Commerce: Produktkataloge mit variierenden Attributen - User Profiles: Unterschiedliche Nutzerprofile - Mobile Apps: Backend für Apps mit flexiblen Daten - Katalog-Systeme: Verschiedene Produkttypen

Beispiel (MongoDB):

{
  "product_id": "A123",
  "name": "Laptop",
  "specs": {
    "cpu": "Intel i7",
    "ram": "16GB"
  },
  "reviews": [...]
}

3. Column-Family Stores

Eigenschaften: - Spaltenorientierte Speicherung - Optimiert für Schreib-intensive Workloads - Massive Skalierbarkeit

Anwendungsfälle: - Event Logging: System-Logs, Application-Logs - Time-Series Data: Sensordaten, Metriken - IoT Applications: Telemetriedaten - Financial Data: Transaktionshistorie - Analytics: Big Data Analysen

Beispiel (Cassandra):

CREATE TABLE sensor_data (
  sensor_id text,
  timestamp timestamp,
  temperature double,
  PRIMARY KEY (sensor_id, timestamp)
)

4. Graph Databases

Eigenschaften: - Knoten und Kanten - Optimiert für Beziehungsabfragen - Traversierung von Graphen

Anwendungsfälle: - Social Networks: Freundschaftsbeziehungen, Follower - Recommendation Engines: "Kunden kauften auch..." - Fraud Detection: Mustererkennung in Transaktionen - Network and IT Operations: Abhängigkeiten, Topologien - Knowledge Graphs: Wissensdatenbanken

Beispiel (Neo4j Cypher):

MATCH (user:Person)-[:FRIEND]->(friend)-[:LIKES]->(movie:Movie)
WHERE user.name = "Alice"
RETURN movie.title

Auswahlkriterien

  • Key-Value: Einfache Zugriffe, höchste Performance
  • Document: Komplexe Objekte, flexible Schemas
  • Column: Massive Schreiblast, Time-Series
  • Graph: Komplexe Beziehungen, Netzwerkanalysen

M165 03 NoSQL-Datenbank implementieren

Einfache Fragen

Frage 1: Was sind NoSQL-Datenbanken und wofür werden sie verwendet?

Definition:

NoSQL (Not Only SQL) Datenbanken sind nicht-relationale Datenbankensysteme, die für spezifische Anforderungen moderner Anwendungen entwickelt wurden.

Verwendungszwecke:

  1. Big Data Anwendungen:
  2. Verarbeitung großer Datenmengen
  3. Hoher Durchsatz bei Lese- und Schreiboperationen
  4. Beispiel: Social Media Feeds

  5. Real-time Web Applications:

  6. Schnelle Antwortzeiten
  7. Hohe Verfügbarkeit
  8. Beispiel: Chat-Anwendungen

  9. Flexible Datenmodelle:

  10. Änderungen an der Datenstruktur ohne Schema-Migration
  11. Verschiedene Datentypen in einer Datenbank
  12. Beispiel: Content Management Systeme

  13. Skalierbare Systeme:

  14. Horizontale Skalierung über viele Server
  15. Geografisch verteilte Systeme
  16. Beispiel: Globale E-Commerce Plattformen

  17. IoT und Sensordaten:

  18. Millionen von Events pro Sekunde
  19. Time-Series Daten
  20. Beispiel: Smart Home Systeme

Wann NoSQL?

NoSQL eignet sich besonders für Anwendungen mit großen Datenmengen, häufigen Schema-Änderungen und hohen Skalierungsanforderungen.

Frage 2: Drei Arten von NoSQL-Datenbanken

1. Key-Value Datenbanken

Hauptmerkmale: - Einfachste NoSQL-Form - Zugriff über eindeutige Schlüssel - Wert kann beliebig sein (String, JSON, Binary) - Sehr hohe Performance

Beispiele: - Redis: In-Memory Store - Amazon DynamoDB: Managed Service - Riak: Distributed Key-Value Store

2. Document Stores

Hauptmerkmale: - Dokumente als Dateneinheiten (JSON, BSON, XML) - Flexible, selbstbeschreibende Strukturen - Verschachtelte Daten möglich - Abfragen auf Dokumentinhalte

Beispiele: - MongoDB: BSON-basiert - CouchDB: JSON-basiert - Elasticsearch: Dokumentensuche

3. Graph Datenbanken

Hauptmerkmale: - Knoten (Entities) und Kanten (Beziehungen) - Optimiert für Beziehungsabfragen - Traversierung von Netzwerken - Effiziente Pfadfindung

Beispiele: - Neo4j: Property Graph - Amazon Neptune: Managed Graph DB - ArangoDB: Multi-Model (inkl. Graph)

Frage 3: Unterschied zwischen relationalen und NoSQL-Datenbanken

Strukturelle Unterschiede:

Eigenschaft Relational NoSQL
Datenmodell Tabellen, Zeilen, Spalten Flexibel (Dokumente, Key-Value, etc.)
Schema Festes Schema (Schema-on-Write) Flexibles Schema (Schema-on-Read)
Beziehungen Foreign Keys, Joins Embedded oder References
Skalierung Vertikal (größerer Server) Horizontal (mehr Server)
Transaktionen ACID-Garantien Oft BASE (Eventual Consistency)
Abfragesprache SQL (standardisiert) Verschiedene APIs
Datenintegrität Strenge Constraints Anwendungsseitig

Operationale Unterschiede:

Relational:

-- Normalisierte Struktur
SELECT c.name, o.order_date, p.product_name
FROM customers c
JOIN orders o ON c.id = o.customer_id
JOIN order_items oi ON o.id = oi.order_id
JOIN products p ON oi.product_id = p.id
WHERE c.id = 123

NoSQL (MongoDB):

// Denormalisierte Struktur
db.customers.findOne({
  _id: 123
}, {
  name: 1,
  "orders.order_date": 1,
  "orders.items.product_name": 1
})

Analogie

Relational = Bibliothekskatalog (strukturiert, kategorisiert)
NoSQL = Persönliche Notizen (flexibel, schnell erweiterbar)

Frage 4: Vorteile von NoSQL-Datenbanken

1. Skalierbarkeit - Horizontale Skalierung durch Sharding - Lineare Performance-Steigerung - Kostengünstigere Hardware (Commodity Servers) - Automatische Datenverteilung

2. Flexibilität - Dynamische Schemas - Verschiedene Datentypen in einer Collection - Schnelle Anpassung an neue Anforderungen - Keine Schema-Migrationen nötig

3. Performance - Optimiert für spezifische Use Cases - Hoher Durchsatz bei Lese-/Schreiboperationen - Denormalisierung reduziert Joins - In-Memory-Optionen verfügbar

4. Verfügbarkeit - Automatische Replikation - Multi-Region Deployments - Keine Single Points of Failure - Selbstheilung bei Ausfällen

5. Entwicklerfreundlichkeit - Datenmodell nah an Objekten in der Programmierung - JSON/BSON = native JavaScript Objekte - Weniger Impedance Mismatch - Schnellere Entwicklung

6. Spezialisierung - Graph DBs für Beziehungsanalysen - Time-Series DBs für Zeitreihen - Full-Text Search Engines - Verschiedene Tools für verschiedene Probleme

Trade-offs beachten

NoSQL-Vorteile kommen oft mit Trade-offs bei Konsistenz und Transaktionen. Wählen Sie basierend auf Ihren Anforderungen.

Mittelschwere Fragen

Frage 5: Dokumentenmodell in NoSQL-Datenbanken

Definition:

Das Dokumentenmodell speichert Daten in selbstbeschreibenden, hierarchischen Dokumenten (meist JSON/BSON), die Felder und Werte enthalten.

Eigenschaften:

  1. Selbstbeschreibend: Jedes Dokument enthält seine Struktur
  2. Flexibel: Verschiedene Dokumente können unterschiedliche Felder haben
  3. Verschachtelt: Unterstützt komplexe, hierarchische Datenstrukturen
  4. Typisiert: Verschiedene Datentypen (String, Number, Boolean, Array, Object)

Beispiel: E-Commerce Produkt

{
  "_id": "prod_12345",
  "name": "Gaming Laptop",
  "category": "Electronics",
  "price": 1299.99,
  "currency": "EUR",
  "inStock": true,
  "specifications": {
    "cpu": "Intel i7-12700H",
    "ram": "16GB DDR5",
    "storage": "1TB NVMe SSD",
    "display": "15.6 inch FHD 144Hz"
  },
  "images": [
    "https://cdn.example.com/img1.jpg",
    "https://cdn.example.com/img2.jpg"
  ],
  "reviews": [
    {
      "user": "Max M.",
      "rating": 5,
      "comment": "Excellent performance!",
      "date": "2026-01-10"
    },
    {
      "user": "Anna K.",
      "rating": 4,
      "comment": "Great but a bit heavy",
      "date": "2026-01-08"
    }
  ],
  "tags": ["gaming", "laptop", "performance"],
  "metadata": {
    "created": "2025-12-01T10:00:00Z",
    "updated": "2026-01-10T15:30:00Z",
    "views": 1547
  }
}

Vorteile:

  • Alle Produktinformationen in einem Dokument
  • Schneller Zugriff ohne Joins
  • Einfach erweiterbar (z.B. neue Felder hinzufügen)
  • Natürliche Abbildung von Objekten aus der Programmierung

Vergleich mit Relational

In einer relationalen DB bräuchten Sie separate Tabellen für: products, specifications, images, reviews, tags - mit entsprechenden Joins.

Frage 6: Unterschiede zwischen Key-Value und dokumentenorientierten Datenbanken

Key-Value Datenbanken:

Struktur:

Schlüssel → Wert (opak, nicht abfragbar)

Eigenschaften: - Wert ist eine "Black Box" für die Datenbank - Zugriff nur über den Schlüssel - Keine Abfragen auf Wert-Inhalte - Maximale Performance und Einfachheit

Operationen:

SET user:1000 "{\"name\":\"Max\",\"age\":30}"
GET user:1000
DELETE user:1000

Beispiel (Redis):

// Setzen
client.set('session:abc123', JSON.stringify({
  userId: 1000,
  loginTime: '2026-01-12T10:00:00Z'
}))

// Abrufen
const session = await client.get('session:abc123')

Dokumentenorientierte Datenbanken:

Struktur:

ID → Dokument (strukturiert, abfragbar)

Eigenschaften: - Datenbank versteht Dokumentstruktur - Abfragen auf beliebige Felder - Indizes auf verschachtelte Felder - Komplexe Queries möglich

Operationen:

// Einfügen
db.users.insertOne({
  _id: 1000,
  name: "Max",
  age: 30,
  address: {
    city: "Berlin",
    zip: "10115"
  }
})

// Abfragen
db.users.find({
  age: { $gt: 25 },
  "address.city": "Berlin"
})

Vergleich:

Aspekt Key-Value Document
Abfragen Nur über Key Über alle Felder
Indizes Nur auf Key Auf beliebige Felder
Komplexität Sehr einfach Moderat
Performance Höchste Sehr hoch
Flexibilität Begrenzt Hoch
Use Case Caching, Sessions Komplexe Objekte

Wann was?

Key-Value: Wenn Sie nur einfachen Get/Set brauchen (Caching, Sessions)
Document: Wenn Sie komplexe Queries auf strukturierte Daten brauchen (Kataloge, CMS)

Frage 7: Indizes in NoSQL-Datenbanken

Bedeutung:

Indizes sind Datenstrukturen, die schnelle Suchoperationen ermöglichen, indem sie einen organisierten Zugriffspfad zu den Daten bereitstellen.

Index-Typen in MongoDB:

1. Single Field Index:

// Index auf ein einzelnes Feld
db.movies.createIndex({ title: 1 })  // 1 = aufsteigend, -1 = absteigend

// Verwendung
db.movies.find({ title: "Inception" })  // Nutzt Index

2. Compound Index:

// Index auf mehrere Felder
db.movies.createIndex({ year: -1, rating: -1 })

// Effiziente Abfragen
db.movies.find({ year: 2010, rating: { $gte: 8 } })
db.movies.find({ year: 2010 })  // Nutzt Index (Prefix)

3. Multikey Index:

// Index auf Array-Felder
db.movies.createIndex({ genres: 1 })

// Findet Filme mit spezifischem Genre
db.movies.find({ genres: "Action" })

4. Text Index:

// Volltextsuche
db.movies.createIndex({ plot: "text", title: "text" })

// Textsuche
db.movies.find({ $text: { $search: "space adventure" } })

5. Geospatial Index:

// Für Standortdaten
db.restaurants.createIndex({ location: "2dsphere" })

// Suche in der Nähe
db.restaurants.find({
  location: {
    $near: {
      $geometry: { type: "Point", coordinates: [13.4050, 52.5200] },
      $maxDistance: 1000  // Meter
    }
  }
})

Vorteile:

✓ Drastische Performance-Steigerung bei Suchen
✓ Effiziente Sortierung
✓ Unterstützung für Unique Constraints
✓ Covered Queries (Antwort nur aus Index)

Nachteile:

✗ Speicher-Overhead
✗ Langsamere Schreiboperationen
✗ Wartungsaufwand

Best Practices:

// Index-Nutzung analysieren
db.movies.find({ title: "Inception" }).explain("executionStats")

// Sparse Index (nur Dokumente mit Feld)
db.users.createIndex({ email: 1 }, { sparse: true })

// TTL Index (automatisches Löschen)
db.sessions.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 })

// Partial Index (nur bestimmte Dokumente)
db.orders.createIndex(
  { status: 1 },
  { partialFilterExpression: { status: "active" } }
)

Performance-Tipp

Erstellen Sie Indizes basierend auf tatsächlichen Query-Mustern. Zu viele Indizes verlangsamen Schreiboperationen erheblich.

Frage 8: Graphdatenbanken und Anwendungsfälle

Definition:

Graphdatenbanken modellieren Daten als Netzwerk von Knoten (Entities) und Kanten (Beziehungen), optimiert für die Traversierung und Analyse von Beziehungen.

Grundkonzepte:

  1. Knoten (Nodes): Repräsentieren Entities
  2. Kanten (Edges/Relationships): Verbindungen zwischen Knoten
  3. Properties: Attribute von Knoten und Kanten
  4. Labels: Kategorien für Knoten

Beispiel: Soziales Netzwerk

// Knoten erstellen
CREATE (alice:Person {name: "Alice", age: 28})
CREATE (bob:Person {name: "Bob", age: 32})
CREATE (charlie:Person {name: "Charlie", age: 25})
CREATE (movie:Movie {title: "Inception", year: 2010})

// Beziehungen erstellen
CREATE (alice)-[:FRIEND_OF {since: 2020}]->(bob)
CREATE (bob)-[:FRIEND_OF {since: 2019}]->(charlie)
CREATE (alice)-[:LIKES {rating: 5}]->(movie)
CREATE (bob)-[:LIKES {rating: 4}]->(movie)

// Komplexe Abfrage: Freunde von Freunden, die denselben Film mögen
MATCH (me:Person {name: "Alice"})-[:FRIEND_OF*1..2]-(friend)-[:LIKES]->(movie)
WHERE (me)-[:LIKES]->(movie)
RETURN DISTINCT friend.name, movie.title

Anwendungsfälle:

1. Social Networks:

// Finde Freunde von Freunden
MATCH (user:Person {name: "Alice"})-[:FRIEND_OF]->(friend)-[:FRIEND_OF]->(fof)
WHERE NOT (user)-[:FRIEND_OF]->(fof) AND user <> fof
RETURN fof.name AS suggested_friend

2. Recommendation Engines:

// "Kunden, die X kauften, kauften auch Y"
MATCH (user:Customer)-[:PURCHASED]->(p1:Product),
      (other:Customer)-[:PURCHASED]->(p1),
      (other)-[:PURCHASED]->(p2:Product)
WHERE NOT (user)-[:PURCHASED]->(p2) AND user <> other
RETURN p2.name, COUNT(*) AS recommendations
ORDER BY recommendations DESC
LIMIT 5

3. Fraud Detection:

// Verdächtige Muster: Mehrere Accounts mit gleicher Adresse
MATCH (account:Account)-[:REGISTERED_AT]->(address:Address)
WITH address, COUNT(account) AS account_count
WHERE account_count > 3
MATCH (suspicious:Account)-[:REGISTERED_AT]->(address)
RETURN suspicious, address

4. Netzwerk- und IT-Management:

// Finde alle abhängigen Services
MATCH path = (service:Service {name: "WebAPI"})-[:DEPENDS_ON*]->(dependency)
RETURN path

5. Knowledge Graphs:

// Wissensnetzwerk durchsuchen
MATCH (concept:Concept {name: "Machine Learning"})-[:RELATED_TO*1..3]-(related)
RETURN related.name, related.type

Vorteile von Graphdatenbanken:

✓ Sehr effizient bei Beziehungsabfragen
✓ Natürliche Modellierung vernetzter Daten
✓ Flexible Schema-Erweiterung
✓ Intuitive Query-Sprache (Cypher)
✓ Konstante Performance bei tiefen Traversierungen

Vergleich: SQL vs. Graph

SQL: Freunde von Freunden = mehrere Joins, Performance sinkt mit Tiefe
Graph: Direkte Traversierung, konstante Performance auch bei 3+ Ebenen

Schwere Fragen

Frage 9: Horizontale vs. vertikale Skalierung in NoSQL

Vertikale Skalierung (Scale Up):

Konzept: - Erhöhung der Ressourcen eines einzelnen Servers - Mehr CPU, RAM, schnellere Festplatten

Vorteile: - Einfache Implementierung - Keine Änderungen an der Anwendung - Konsistente Performance - Einfaches Management

Nachteile: - Hardware-Limits (maximale Größe) - Hohe Kosten bei High-End-Hardware - Single Point of Failure - Downtime bei Upgrades - Nicht linear skalierbar

Beispiel:

Server 1: 4 CPU, 16GB RAM → Server 1: 16 CPU, 64GB RAM

Horizontale Skalierung (Scale Out):

Konzept: - Hinzufügen weiterer Server zum Cluster - Datenverteilung über mehrere Knoten (Sharding)

Mechanismen in NoSQL:

1. Sharding (Datenpartitionierung):

// MongoDB Sharding
sh.shardCollection("mydb.users", { "user_id": "hashed" })

// Daten werden automatisch verteilt
Shard 1: user_id 0-333
Shard 2: user_id 334-666
Shard 3: user_id 667-999

2. Replikation:

Primary Node → Secondary Node 1
            → Secondary Node 2
            → Secondary Node 3

Vorteile: - Nahezu unbegrenzte Skalierung - Kostengünstigere Commodity-Hardware - Hohe Verfügbarkeit (keine Single Point of Failure) - Geografische Verteilung möglich - Linear wachsende Performance

Nachteile: - Komplexere Architektur - Eventual Consistency - Netzwerk-Overhead - Komplexeres Deployment und Management - Distributed Transactions schwieriger

Sharding-Strategien:

1. Range-based Sharding:

// Basiert auf Wertebereichen
Shard 1: A-G
Shard 2: H-N
Shard 3: O-Z
- Vorteil: Einfache Range-Queries - Nachteil: Ungleiche Verteilung möglich

2. Hash-based Sharding:

// Basiert auf Hash des Schlüssels
hash(key) % num_shards = shard_number
- Vorteil: Gleichmäßige Verteilung - Nachteil: Range-Queries über Shards

3. Geographic Sharding:

// Basiert auf Standort
EU-Shard: Europäische Nutzer
US-Shard: US Nutzer
ASIA-Shard: Asiatische Nutzer
- Vorteil: Niedrige Latenz, Datenschutz-Compliance - Nachteil: Ungleiche Last möglich

Vergleich:

Aspekt Vertikal Horizontal
Kosten Hoch (bei Größe) Moderat (Commodity HW)
Limits Hardware-Maximum Praktisch unbegrenzt
Komplexität Niedrig Hoch
Verfügbarkeit SPOF-Risiko Hohe Redundanz
Konsistenz Strong Eventual (oft)

Best Practice

Moderne Systeme kombinieren oft beide: Vertikale Skalierung pro Node + horizontale Skalierung durch mehr Nodes.

Frage 10: Datenkonsistenz in verteilten NoSQL-Datenbanken

Herausforderungen:

In verteilten Systemen ist es schwierig, Konsistenz, Verfügbarkeit und Partitionstoleranz gleichzeitig zu garantieren (CAP-Theorem).

Konsistenzmodelle:

1. Strong Consistency: - Alle Knoten sehen sofort die gleichen Daten - Schreiboperation blockiert bis alle Replicas aktualisiert sind - Höhere Latenz, niedrigere Verfügbarkeit

// MongoDB mit Write Concern "majority"
db.users.insertOne(
  { name: "Max" },
  { writeConcern: { w: "majority", wtimeout: 5000 } }
)

2. Eventual Consistency: - Knoten konvergieren über Zeit zum gleichen Zustand - Sofortige Bestätigung, asynchrone Replikation - Temporäre Inkonsistenzen möglich

// Cassandra - Eventual Consistency
INSERT INTO users (id, name) VALUES (1, 'Max')
// Wird asynchron repliziert

3. Causal Consistency: - Kausal verbundene Operationen sehen alle in gleicher Reihenfolge - Balance zwischen Strong und Eventual

Lösungsansätze:

1. Quorum-basierte Replikation:

W + R > N

W = Write Quorum (Anzahl Bestätigungen beim Schreiben)
R = Read Quorum (Anzahl Knoten beim Lesen)
N = Replikationsfaktor (Gesamtanzahl Replicas)

Beispiel:

// Cassandra Consistency Levels
// Strong Consistency: W=2, R=2, N=3
INSERT INTO users (id, name) VALUES (1, 'Max') 
USING CONSISTENCY QUORUM;

SELECT * FROM users WHERE id = 1 
USING CONSISTENCY QUORUM;

2. Vector Clocks: - Tracking von Kausalität zwischen Updates - Erkennung konkurrierender Updates

Node A: [(A,1)]
Node B: [(A,1), (B,1)]  // B sah Update von A
Node C: [(A,1), (C,1)]  // C sah Update von A
// B und C sind concurrent → Konflikt

3. Conflict Resolution:

Last-Write-Wins (LWW):

// Timestamp-basiert
Document 1: { value: "A", timestamp: 1000 }
Document 2: { value: "B", timestamp: 1001 }
// "B" gewinnt

Application-Level Merge:

// Anwendung entscheidet
const conflictedVersions = [
  { cart: ["item1"], version: "A" },
  { cart: ["item2"], version: "B" }
]
// Merge: { cart: ["item1", "item2"] }

4. CRDTs (Conflict-free Replicated Data Types):

// Beispiel: Counter CRDT
class GCounter {
  constructor() {
    this.counts = {}
  }

  increment(nodeId) {
    this.counts[nodeId] = (this.counts[nodeId] || 0) + 1
  }

  value() {
    return Object.values(this.counts).reduce((a, b) => a + b, 0)
  }

  merge(other) {
    for (let node in other.counts) {
      this.counts[node] = Math.max(
        this.counts[node] || 0,
        other.counts[node]
      )
    }
  }
}

5. Two-Phase Commit (2PC):

Phase 1 (Prepare):
Coordinator → All Participants: "Can you commit?"
Participants → Coordinator: "Yes" or "No"

Phase 2 (Commit):
If all "Yes":
  Coordinator → All: "Commit"
Else:
  Coordinator → All: "Abort"

Praktische Strategien:

// 1. Read-Your-Own-Writes
db.users.insertOne({ _id: 1, name: "Max" }, { writeConcern: { w: 1 } })
db.users.findOne({ _id: 1 }, { readConcern: "local" })  // Sieht eigenes Write

// 2. Monotonic Reads
// Einmal ein Wert gelesen → spätere Reads sehen niemals ältere Werte

// 3. Session Consistency
const session = client.startSession()
session.startTransaction()
try {
  db.accounts.updateOne({ _id: 1 }, { $inc: { balance: -100 } }, { session })
  db.accounts.updateOne({ _id: 2 }, { $inc: { balance: 100 } }, { session })
  await session.commitTransaction()
} catch (error) {
  await session.abortTransaction()
}

Trade-offs

  • Strong Consistency: Höhere Latenz, niedrigere Verfügbarkeit
  • Eventual Consistency: Bessere Performance, aber komplexere Anwendungslogik
  • Wahl abhängig von: Use Case, SLA-Anforderungen, geografische Verteilung

Frage 11: Transaktionsmanagement NoSQL vs. Relational

Relationale Datenbanken:

ACID-Eigenschaften: - Atomicity: Alles oder nichts - Consistency: Datenbank bleibt in gültigem Zustand - Isolation: Transaktionen beeinflussen sich nicht - Durability: Commits sind persistent

Beispiel:

BEGIN TRANSACTION;
  UPDATE accounts SET balance = balance - 100 WHERE id = 1;
  UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;

Vorteile: ✓ Garantierte Datenkonsistenz
✓ Komplexe Transaktionen über mehrere Tabellen
✓ Rollback bei Fehlern
✓ Isolationslevel konfigurierbar

Nachteile: ✗ Performance-Overhead (Locking)
✗ Schwierig über mehrere Server zu verteilen
✗ Skalierungsgrenzen

NoSQL-Datenbanken:

BASE-Eigenschaften: - Basically Available: System funktioniert (meist) - Soft state: Zustand kann sich ändern - Eventual consistency: Wird konsistent

Ansätze:

1. Einzeldokument-Transaktionen:

// MongoDB - Atomar auf Dokumentebene
db.accounts.updateOne(
  { _id: 1 },
  {
    $inc: { balance: -100 },
    $push: { transactions: { amount: -100, date: new Date() } }
  }
)
// Beide Operationen sind atomar

Vorteile: ✓ Sehr performant
✓ Einfach zu implementieren
✓ Gut skalierbar

Nachteile: ✗ Nur ein Dokument
✗ Datenmodell muss passen

2. Multi-Document Transactions (MongoDB 4.0+):

const session = client.startSession()
session.startTransaction({
  readConcern: { level: 'snapshot' },
  writeConcern: { w: 'majority' }
})

try {
  await db.accounts.updateOne(
    { _id: 1 },
    { $inc: { balance: -100 } },
    { session }
  )

  await db.accounts.updateOne(
    { _id: 2 },
    { $inc: { balance: 100 } },
    { session }
  )

  await session.commitTransaction()
  console.log("Transaction successful")
} catch (error) {
  await session.abortTransaction()
  console.log("Transaction aborted:", error)
} finally {
  session.endSession()
}

Vorteile: ✓ ACID über mehrere Dokumente
✓ Ähnlich zu SQL-Transaktionen

Nachteile: ✗ Performance-Overhead
✗ Nicht in allen NoSQL-DBs verfügbar
✗ Komplexer in Sharded Clusters

3. Saga Pattern:

// Verteilte Transaktion als Serie lokaler Transaktionen
async function transferMoney(from, to, amount) {
  try {
    // Step 1: Geld abziehen
    await debitAccount(from, amount)

    try {
      // Step 2: Geld gutschreiben
      await creditAccount(to, amount)
    } catch (error) {
      // Compensating Transaction
      await creditAccount(from, amount)  // Rollback
      throw error
    }
  } catch (error) {
    console.log("Transfer failed:", error)
  }
}

4. Two-Phase Commit Pattern:

// Manuelle Implementierung
const transaction = {
  _id: "txn_123",
  state: "pending",
  operations: [
    { collection: "accounts", _id: 1, update: { $inc: { balance: -100 } } },
    { collection: "accounts", _id: 2, update: { $inc: { balance: 100 } } }
  ]
}

// Phase 1: Prepare
await db.transactions.insertOne(transaction)
await db.accounts.updateOne({ _id: 1 }, { $set: { pendingTxn: "txn_123" } })
await db.accounts.updateOne({ _id: 2 }, { $set: { pendingTxn: "txn_123" } })

// Phase 2: Commit oder Rollback
try {
  // Apply all operations
  for (let op of transaction.operations) {
    await db[op.collection].updateOne({ _id: op._id }, op.update)
  }
  await db.transactions.updateOne({ _id: "txn_123" }, { $set: { state: "committed" } })
} catch (error) {
  await db.transactions.updateOne({ _id: "txn_123" }, { $set: { state: "aborted" } })
}

Vergleich:

Aspekt Relational NoSQL
ACID Vollständig Teilweise/Optional
Scope Multi-Table Oft Single-Document
Performance Overhead Meist schneller
Komplexität Einfach (Built-in) Oft manuell
Skalierung Schwierig Besser
Isolation Konfigurierbar Begrenzt

Best Practices für NoSQL:

  1. Datenmodell anpassen: Embedded Documents nutzen um Multi-Doc Transactions zu vermeiden
  2. Idempotenz: Operationen so designen, dass sie mehrfach ausgeführt werden können
  3. Compensation: Bei Fehlern Ausgleichsaktionen durchführen
  4. Optimistic Locking: Versionsnummern verwenden
  5. Event Sourcing: Status aus Event-Log ableiten

Entscheidungshilfe

  • Kritische Finanztransaktionen → Relational mit ACID
  • Social Media Posts → NoSQL mit Eventual Consistency
  • E-Commerce Checkout → NoSQL mit Multi-Doc Transactions oder Saga Pattern

Frage 12: CAP-Theorem und Bedeutung für NoSQL

Definition:

Das CAP-Theorem besagt, dass ein verteiltes Datensystem maximal zwei der drei folgenden Garantien gleichzeitig bieten kann:

C - Consistency (Konsistenz): - Alle Knoten sehen zur gleichen Zeit die gleichen Daten - Jeder Read liefert das aktuellste Write

A - Availability (Verfügbarkeit): - Jede Anfrage erhält eine Antwort - Keine Request schlägt fehl (außer Netzwerkfehler)

P - Partition Tolerance (Partitionstoleranz): - System funktioniert trotz Netzwerkausfällen - Knoten können temporär isoliert sein

Warum nur 2 von 3?

Szenario: Netzwerkpartition zwischen Knoten A und B

Option 1 (CP - Consistency + Partition Tolerance):
- Bei Partition: Verweigere Anfragen
- → Verfügbarkeit geht verloren

Option 2 (AP - Availability + Partition Tolerance):
- Bei Partition: Beide Knoten antworten
- → Konsistenz geht verloren (different data)

Option 3 (CA - Consistency + Availability):
- Nur möglich ohne Partitionen
- → Nicht praktikabel in verteilten Systemen

NoSQL-Datenbanken und CAP:

CP-Systeme (Consistency + Partition Tolerance):

Beispiel: MongoDB (mit majority write concern)

// Konfiguration für CP
db.users.insertOne(
  { name: "Max" },
  { writeConcern: { w: "majority" }, readConcern: "majority" }
)

// Bei Netzwerkpartition:
// - Minderheitsknoten akzeptieren keine Writes
// - Garantiert Konsistenz
// - Verfügbarkeit reduziert

Weitere CP-Systeme: - HBase - Redis (bei bestimmter Config) - Bigtable

Anwendungsfälle: - Finanztransaktionen - Inventarverwaltung - Buchungssysteme

AP-Systeme (Availability + Partition Tolerance):

Beispiel: Cassandra

-- Konfiguration für AP
INSERT INTO users (id, name) VALUES (1, 'Max')
USING CONSISTENCY LOCAL_ONE;

-- Bei Netzwerkpartition:
-- - Alle Knoten bleiben verfügbar
-- - Eventual Consistency
-- - Temporäre Inkonsistenzen möglich

Weitere AP-Systeme: - DynamoDB - Couchbase - Riak

Anwendungsfälle: - Social Media - Analytics - IoT-Datensammlung - Shopping Carts

CA-Systeme (Consistency + Availability):

Realität: - Nicht praktikabel in verteilten Systemen - Netzwerkpartitionen sind unvermeidbar - Nur in Single-Server Setups

Beispiel: - Traditionelle Single-Server RDBMS - Lokale SQLite Datenbank

Praktische Auswirkungen:

1. CP-System Beispiel (MongoDB):

// Primär-Knoten fällt aus
// Replica Set wählt neuen Primär

// Während Election:
try {
  await db.users.insertOne({ name: "Max" })
} catch (error) {
  // Error: "not master" oder Timeout
  // Verfügbarkeit temporär beeinträchtigt
}

// Nach Election: System funktioniert wieder

2. AP-System Beispiel (Cassandra):

-- Partition zwischen DC1 und DC2

-- In DC1:
INSERT INTO users (id, name) VALUES (1, 'Max');
-- Erfolgreich

-- In DC2 (gleichzeitig):
INSERT INTO users (id, name) VALUES (1, 'Anna');
-- Ebenfalls erfolgreich

-- Später (nach Partition-Heilung):
-- Last-Write-Wins oder Application Logic entscheidet

Tuning des CAP-Trade-offs:

MongoDB - Flexibles Tuning:

// Mehr Consistency, weniger Availability
db.collection.insertOne(data, {
  writeConcern: { w: "majority", wtimeout: 5000 },
  readConcern: "majority"
})

// Mehr Availability, weniger Consistency
db.collection.insertOne(data, {
  writeConcern: { w: 1 },
  readConcern: "local"
})

Cassandra - Consistency Levels:

-- Strong Consistency
INSERT INTO users (id, name) VALUES (1, 'Max') 
USING CONSISTENCY QUORUM;

SELECT * FROM users WHERE id = 1 
USING CONSISTENCY QUORUM;

-- Eventual Consistency
INSERT INTO users (id, name) VALUES (1, 'Max') 
USING CONSISTENCY ONE;

SELECT * FROM users WHERE id = 1 
USING CONSISTENCY ONE;

Erweiterte Konzepte:

PACELC-Theorem: Erweitert CAP um Latenz:

IF Partition:
  Trade-off zwischen Availability und Consistency (CAP)
ELSE:
  Trade-off zwischen Latency und Consistency

PA/EL: Cassandra (Availability bei Partition, Low Latency sonst)
PC/EC: HBase (Consistency bei Partition, Consistency sonst)
PA/EC: MongoDB (konfigurierbar)

Entscheidungshilfe:

Anforderung Wahl
Finanz-Transaktionen CP (MongoDB, HBase)
Social Media Feed AP (Cassandra, DynamoDB)
Shopping Cart AP (DynamoDB)
Inventar-Management CP (MongoDB)
Analytics/Logs AP (Cassandra)
Session Storage AP (Redis Cluster)

Wichtig

Das CAP-Theorem ist keine binäre Entscheidung. Moderne Systeme bieten Tuning-Optionen für verschiedene Consistency/Availability-Trade-offs je nach Anwendungsfall.


M165 04 Arbeiten mit MongoDB

Einfache Fragen

Frage 1: Verbindung zur Datenbank und Erstellen der moviesDB

Verbindung herstellen:

// Node.js mit MongoDB Driver
const { MongoClient } = require('mongodb')

const uri = "mongodb://localhost:27017"
const client = new MongoClient(uri)

async function connect() {
  try {
    await client.connect()
    console.log("Connected to MongoDB")

    // Datenbank erstellen/auswählen
    const db = client.db('moviesDB')

    return db
  } catch (error) {
    console.error("Connection failed:", error)
  }
}

MongoDB Shell (mongosh):

// Verbindung
mongosh "mongodb://localhost:27017"

// Datenbank erstellen/wechseln
use moviesDB

// Datenbank wird erst beim Einfügen von Daten physisch erstellt
db.movies.insertOne({ title: "Test" })

// Datenbanken anzeigen
show dbs

// Aktuelle Datenbank prüfen
db

Mit Authentifizierung:

mongosh "mongodb://username:password@localhost:27017/moviesDB?authSource=admin"

MongoDB Compass (GUI):

  1. Connection String eingeben: mongodb://localhost:27017
  2. Connect klicken
  3. "Create Database" Button
  4. Database Name: moviesDB
  5. Collection Name: movies

Tipp

Die Datenbank wird erst physisch erstellt, wenn das erste Dokument eingefügt wird. Vorher existiert sie nur logisch.

Frage 2: Filmdaten in die movies-Collection einfügen

Einzelnes Dokument einfügen:

db.movies.insertOne({
  title: "Inception",
  year: 2010,
  director: "Christopher Nolan",
  genres: ["Action", "Sci-Fi", "Thriller"],
  runtime: 148,
  cast: [
    { actor: "Leonardo DiCaprio", role: "Cobb" },
    { actor: "Joseph Gordon-Levitt", role: "Arthur" },
    { actor: "Ellen Page", role: "Ariadne" }
  ],
  ratings: {
    imdb: 8.8,
    rottenTomatoes: 87
  },
  plot: "A thief who steals corporate secrets through dream-sharing technology..."
})

Mehrere Dokumente einfügen:

db.movies.insertMany([
  {
    title: "The Matrix",
    year: 1999,
    director: "Lana Wachowski, Lilly Wachowski",
    genres: ["Action", "Sci-Fi"],
    runtime: 136,
    cast: [
      { actor: "Keanu Reeves", role: "Neo" },
      { actor: "Laurence Fishburne", role: "Morpheus" },
      { actor: "Carrie-Anne Moss", role: "Trinity" }
    ],
    ratings: {
      imdb: 8.7,
      rottenTomatoes: 88
    }
  },
  {
    title: "Interstellar",
    year: 2014,
    director: "Christopher Nolan",
    genres: ["Adventure", "Drama", "Sci-Fi"],
    runtime: 169,
    cast: [
      { actor: "Matthew McConaughey", role: "Cooper" },
      { actor: "Anne Hathaway", role: "Brand" },
      { actor: "Jessica Chastain", role: "Murph" }
    ],
    ratings: {
      imdb: 8.6,
      rottenTomatoes: 72
    }
  },
  {
    title: "The Dark Knight",
    year: 2008,
    director: "Christopher Nolan",
    genres: ["Action", "Crime", "Drama"],
    runtime: 152,
    cast: [
      { actor: "Christian Bale", role: "Bruce Wayne" },
      { actor: "Heath Ledger", role: "Joker" },
      { actor: "Aaron Eckhart", role: "Harvey Dent" }
    ],
    ratings: {
      imdb: 9.0,
      rottenTomatoes: 94
    }
  }
])

Mit automatischer _id Generierung:

// MongoDB generiert automatisch eine ObjectId als _id
const result = db.movies.insertOne({
  title: "Pulp Fiction",
  year: 1994,
  director: "Quentin Tarantino"
})

console.log("Inserted ID:", result.insertedId)

Mit benutzerdefinierter _id:

db.movies.insertOne({
  _id: "movie_001",
  title: "Fight Club",
  year: 1999,
  director: "David Fincher"
})

Wichtig

  • insertOne() fügt ein einzelnes Dokument ein
  • insertMany() fügt mehrere Dokumente ein (Array)
  • _id wird automatisch generiert, wenn nicht angegeben
  • _id muss eindeutig sein

Frage 3: Eingefügte Daten in der movies-Collection prüfen

Alle Dokumente anzeigen:

// Alle Filme
db.movies.find()

// Schön formatiert
db.movies.find().pretty()

// Anzahl der Dokumente
db.movies.countDocuments()

Spezifische Abfragen:

// Film nach Titel
db.movies.findOne({ title: "Inception" })

// Filme nach Jahr
db.movies.find({ year: 2010 })

// Filme nach Genre
db.movies.find({ genres: "Sci-Fi" })

// Filme nach Regisseur
db.movies.find({ director: "Christopher Nolan" })

Projektion (nur bestimmte Felder):

// Nur Titel und Jahr
db.movies.find({}, { title: 1, year: 1, _id: 0 })

// Alle außer Plot
db.movies.find({}, { plot: 0 })

Limit und Sort:

// Top 5 Filme nach IMDb-Rating
db.movies.find().sort({ "ratings.imdb": -1 }).limit(5)

// Neueste Filme zuerst
db.movies.find().sort({ year: -1 })

Erweiterte Prüfungen:

// Dokumentstruktur anzeigen
db.movies.findOne()

// Verfügbare Collections
show collections

// Collection-Statistiken
db.movies.stats()

// Indizes prüfen
db.movies.getIndexes()

// Validate Collection
db.movies.validate()

Debugging-Tipp

Nutzen Sie .explain() um zu sehen, wie MongoDB Ihre Query ausführt:

db.movies.find({ year: 2010 }).explain("executionStats")

Frage 4: Award in die awards-Collection einfügen

Einfache Award-Struktur:

db.awards.insertOne({
  name: "Academy Award",
  category: "Best Picture",
  year: 2011,
  movie_id: ObjectId("..."),  // Referenz zum Film
  winner: true
})

Detaillierte Award-Struktur:

db.awards.insertMany([
  {
    _id: "award_001",
    awardName: "Academy Awards",
    category: "Best Picture",
    year: 2011,
    movie: {
      _id: "movie_inception",
      title: "Inception"
    },
    won: false,
    nominated: true,
    nominees: ["Inception", "The King's Speech", "The Social Network"]
  },
  {
    _id: "award_002",
    awardName: "Academy Awards",
    category: "Best Visual Effects",
    year: 2011,
    movie: {
      _id: "movie_inception",
      title: "Inception"
    },
    won: true,
    nominated: true
  },
  {
    _id: "award_003",
    awardName: "Golden Globe Awards",
    category: "Best Director - Motion Picture",
    year: 2011,
    director: "Christopher Nolan",
    movie: {
      _id: "movie_inception",
      title: "Inception"
    },
    won: false,
    nominated: true
  },
  {
    _id: "award_004",
    awardName: "BAFTA Awards",
    category: "Best Film",
    year: 2011,
    movie: {
      _id: "movie_inception",
      title: "Inception"
    },
    won: false,
    nominated: true
  }
])

Awards direkt im Film-Dokument (embedded):

db.movies.updateOne(
  { title: "Inception" },
  {
    $set: {
      awards: [
        {
          name: "Academy Awards",
          wins: 4,
          nominations: 8,
          details: [
            { category: "Best Visual Effects", won: true },
            { category: "Best Sound Mixing", won: true },
            { category: "Best Sound Editing", won: true },
            { category: "Best Cinematography", won: true },
            { category: "Best Picture", won: false },
            { category: "Best Original Screenplay", won: false }
          ]
        },
        {
          name: "BAFTA Awards",
          wins: 3,
          nominations: 9
        }
      ]
    }
  }
)

Prüfen:

// Alle Awards
db.awards.find()

// Awards eines bestimmten Films
db.awards.find({ "movie.title": "Inception" })

// Gewonnene Awards
db.awards.find({ won: true })

// Awards nach Jahr
db.awards.find({ year: 2011 })

Design-Entscheidung

  • Separate Collection: Wenn Awards unabhängig vom Film verwaltet werden
  • Embedded: Wenn Awards immer mit dem Film gelesen werden
  • Hybride Ansätze sind auch möglich

Mittelschwere Fragen

Frage 5: Verschachtelte Bewertungen (IMDb und Tomatometer) hinzufügen

Verschachtelte Struktur erstellen:

db.movies.updateOne(
  { title: "Inception" },
  {
    $set: {
      ratings: {
        imdb: {
          rating: 8.8,
          votes: 2300000,
          id: "tt1375666"
        },
        rottenTomatoes: {
          tomatometer: 87,
          audienceScore: 91,
          consensus: "Smart, innovative, and thrilling...",
          fresh: 285,
          rotten: 42,
          url: "https://www.rottentomatoes.com/m/inception"
        },
        metacritic: {
          score: 74,
          url: "https://www.metacritic.com/movie/inception"
        }
      }
    }
  }
)

Mehrere Filme gleichzeitig aktualisieren:

const moviesWithRatings = [
  {
    title: "The Matrix",
    ratings: {
      imdb: { rating: 8.7, votes: 1800000 },
      rottenTomatoes: { tomatometer: 88, audienceScore: 85 },
      metacritic: { score: 73 }
    }
  },
  {
    title: "Interstellar",
    ratings: {
      imdb: { rating: 8.6, votes: 1700000 },
      rottenTomatoes: { tomatometer: 72, audienceScore: 86 },
      metacritic: { score: 74 }
    }
  }
]

moviesWithRatings.forEach(movie => {
  db.movies.updateOne(
    { title: movie.title },
    { $set: { ratings: movie.ratings } }
  )
})

Ratings beim Einfügen direkt angeben:

db.movies.insertOne({
  title: "The Shawshank Redemption",
  year: 1994,
  director: "Frank Darabont",
  genres: ["Drama"],
  ratings: {
    imdb: {
      rating: 9.3,
      votes: 2600000,
      topRank: 1,  // #1 auf IMDb Top 250
      id: "tt0111161"
    },
    rottenTomatoes: {
      tomatometer: 91,
      audienceScore: 98,
      certified_fresh: true,
      consensus: "The Shawshank Redemption is an uplifting, deeply satisfying prison drama..."
    },
    metacritic: {
      score: 81,
      userScore: 9.1
    },
    letterboxd: {
      rating: 4.5,
      votes: 1200000
    }
  }
})

Abfragen auf verschachtelte Felder:

// Filme mit IMDb-Rating über 8.5
db.movies.find({ "ratings.imdb.rating": { $gte: 8.5 } })

// Filme mit Tomatometer über 80
db.movies.find({ "ratings.rottenTomatoes.tomatometer": { $gt: 80 } })

// Filme mit hohen Ratings in beiden Systemen
db.movies.find({
  "ratings.imdb.rating": { $gte: 8.0 },
  "ratings.rottenTomatoes.tomatometer": { $gte: 80 }
})

// Nur Ratings zurückgeben
db.movies.find(
  {},
  { title: 1, "ratings.imdb.rating": 1, "ratings.rottenTomatoes.tomatometer": 1 }
)

Ratings aktualisieren:

// IMDb-Votes aktualisieren
db.movies.updateOne(
  { title: "Inception" },
  { $set: { "ratings.imdb.votes": 2400000 } }
)

// Neues Rating-System hinzufügen
db.movies.updateOne(
  { title: "Inception" },
  { $set: { "ratings.tmdb": { rating: 8.3, votes: 28000 } } }
)

Dot-Notation

Verwenden Sie die Dot-Notation ("ratings.imdb.rating") um auf verschachtelte Felder zuzugreifen. Anführungszeichen sind wichtig!

Frage 6: Kommentare mit Benutzerinformationen hinzufügen

Kommentare als Array im Film-Dokument:

```javascript db.movies.updateOne( { title: "Inception" }, { $set: { comments: [ { _id: ObjectId(), user: { _id: "user_001", name: "Max Mustermann", email: "max@example.com", avatar: "https://example.com/avatars/max.jpg" }, text: "Mind-blowing movie! The plot is incredibly complex yet so engaging.", rating: 5, likes: 127, date: new Date("2026-01-10T14:30:00Z"), replies: [ { user: { _id: "user_002", name: "Anna Schmidt" }, text: "Totally agree! Watched it 3 times and still discovering new details.", date: new Date("2026-01-10T16:45:00Z") } ] }, { _id: ObjectId(), user: { _id: "user_003", name: "John Doe", email: "john@example.com" }, text: "The visual effects are stunning. Nolan is a genius!", rating: 5, likes: 89, date: new Date("2026-01-11T09:15:00Z"), spoiler: