2026-07-02 17:27:21 +02:00

668 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
theme: seriph
title: Ringstats Zwischenpräsentation
info: |
## Ringstats
Zwischenstandspräsentation Moderne Datenbanken
Justin Rost · Michelle Reichelt · Yasin Ergün
class: text-center
transition: slide-left
mdc: true
fonts:
sans: Inter
mono: Fira Code
---
# Ringstats
Eine Live Datenbank für Elden Ring
<div class="pt-6 opacity-80 text-lg">
Justin Rost · Michelle Reichelt · Yasin Ergün
</div>
<div class="pt-10 opacity-60 text-sm">
Zwischenpräsentation · Moderne Datenbanken · 08.06.2026
</div>
---
layout: center
class: text-center
---
# Inhalt
<div class="flex justify-center items-stretch gap-3 pt-14">
<div class="w-36 p-5 rounded-xl bg-gray-400/10">
<div class="text-4xl">🎯</div>
<div class="pt-3 font-semibold text-sm">Szenario</div>
</div>
<div class="flex items-center text-2xl opacity-40"></div>
<div class="w-36 p-5 rounded-xl bg-gray-400/10">
<div class="text-4xl">🗺️</div>
<div class="pt-3 font-semibold text-sm">ER-Modell</div>
</div>
<div class="flex items-center text-2xl opacity-40"></div>
<div class="w-36 p-5 rounded-xl bg-gray-400/10">
<div class="text-4xl">🧩</div>
<div class="pt-3 font-semibold text-sm">Drei Modelle</div>
</div>
<div class="flex items-center text-2xl opacity-40"></div>
<div class="w-36 p-5 rounded-xl bg-gray-400/10">
<div class="text-4xl">⚖️</div>
<div class="pt-3 font-semibold text-sm">Vergleich</div>
</div>
<div class="flex items-center text-2xl opacity-40"></div>
<div class="w-36 p-5 rounded-xl bg-red-400/10">
<div class="text-4xl"></div>
<div class="pt-3 font-semibold text-sm">Auswahl</div>
</div>
</div>
<!--
- kurzer Fahrplan durch die Präsentation
- erst Szenario, dann ER-Modell als Grundlage
- drei NoSQL-Modelle an unseren Daten zeigen
- vergleichen und am Ende eine Auswahl treffen
-->
---
layout: center
class: text-center
---
# Die Idee
<div class="opacity-70 pt-2">Eine Schnittstelle zwischen Spiel und Datenbank</div>
<div class="flex justify-center items-center gap-6 pt-12">
<div class="w-44 p-6 rounded-xl bg-gray-400/10">
<div class="text-5xl">🎮</div>
<div class="pt-3 font-semibold">Spiel</div>
<div class="pt-1 text-xs opacity-70">liest Position, Leben, Ausrüstung live aus</div>
</div>
<div class="text-3xl opacity-40"></div>
<div class="w-44 p-6 rounded-xl bg-red-400/10">
<div class="text-5xl">🗄️</div>
<div class="pt-3 font-semibold">Datenbank</div>
<div class="pt-1 text-xs opacity-70">speichert und liefert passende Infos</div>
</div>
<div class="text-3xl opacity-40"></div>
<div class="w-44 p-6 rounded-xl bg-gray-400/10">
<div class="text-5xl">🌐</div>
<div class="pt-3 font-semibold">Browser</div>
<div class="pt-1 text-xs opacity-70">gleiche Daten parallel abrufbar</div>
</div>
</div>
<!--
- Schnittstelle zwischen Spiel und Datenbank
- Im Spiel werden Daten ausgelesen
- Daten werden an Server gesendet und in DB verwalten
- Programm und Browser lesen Daten aus
-->
---
layout: default
---
# Kernidee: Hilfe für Spieler
<div class="grid grid-cols-2 gap-6 pt-10 text-center">
<div class="p-6 rounded-xl bg-gray-400/10">
<div class="text-4xl">🎮</div>
<div class="pt-3 font-semibold">Im-Spiel Anzeige</div>
<div class="pt-2 text-sm opacity-80">zeigt z.B. Bossangriffe live und Checkliste</div>
</div>
<div class="p-6 rounded-xl bg-gray-400/10">
<div class="text-4xl">🖥️</div>
<div class="pt-3 font-semibold">Browser App</div>
<div class="pt-2 text-sm opacity-80">Generelle Informationen und Analysen</div>
</div>
</div>
<div class="pt-8 text-center opacity-70">
Es muss extrem schnell gehen, ohne spürbare Verzögerung.
</div>
<!--
- Die Kernidee ist Hilfe für den Spieler
- Im Spiel wird Oberfläche angezeigt mit Informationen
- Browser App zeigt detaillreicher Infos zum Spieler und Welt
-->
---
layout: default
---
# Anwendungsfälle
<div class="grid grid-cols-3 gap-6 pt-12 text-center">
<div class="p-6 rounded-xl bg-gray-400/10">
<div class="text-5xl">⚔️</div>
<div class="pt-4 font-semibold">Bosskampf</div>
<div class="pt-2 text-sm opacity-70">Fenster mit Resistenzen und Angriffe</div>
</div>
<div class="p-6 rounded-xl bg-gray-400/10">
<div class="text-5xl">📦</div>
<div class="pt-4 font-semibold">Live-Standort</div>
<div class="pt-2 text-sm opacity-70">Checkliste, Truhen und Objekte in der Nähe</div>
</div>
<div class="p-6 rounded-xl bg-gray-400/10">
<div class="text-5xl">🌐</div>
<div class="pt-4 font-semibold">Website</div>
<div class="pt-2 text-sm opacity-70">Builds und Statistiken</div>
</div>
</div>
<!--
- Einige Informationen sind:
- Resistenzen und Angriffe von Bossen
- Truhen, Objekte und Checklisten in der Nähe
- Detaillierte Informationen zu Statistiken und Builds auf Website
-->
---
layout: default
---
# Das ER-Modell
<div class="flex justify-center pt-2">
<img src="/er-modell.png" class="h-100 rounded-lg bg-white p-2" />
</div>
<!--
- Zentrale Entity ist Player/Spieler
- Grear (Inventar) beinhaltet (Weapon, Armor, Shield, Talisman).
- Das sind alles Items, werden von Gegnern fallengelassen.
- In Regionen sind Player, Enemies und Items
-->
---
layout: center
class: text-center
---
# Drei NoSQL-Modelle
<div class="grid grid-cols-3 gap-8 pt-10">
<div class="p-8 rounded-xl bg-red-400/10">
<div class="text-3xl font-bold">Key-Value</div>
<div class="pt-3 opacity-80">Redis</div>
<div class="pt-2 text-sm opacity-70">Alles über Schlüssel</div>
</div>
<div class="p-8 rounded-xl bg-green-400/10">
<div class="text-3xl font-bold">Dokument</div>
<div class="pt-3 opacity-80">MongoDB</div>
<div class="pt-2 text-sm opacity-70">Alles im Dokument</div>
</div>
<div class="p-8 rounded-xl bg-blue-400/10">
<div class="text-3xl font-bold">Graph</div>
<div class="pt-3 opacity-80">Neo4j</div>
<div class="pt-2 text-sm opacity-70">Alles über Kanten</div>
</div>
</div>
<div class="pt-10 opacity-70">
Wir bilden die gleichen Daten in allen drei ab.
</div>
<!--
- Key-Value mit Redis: alles über Schlüssel
- Dokument mit MongoDB: alles im Dokument
- Graph mit Neo4j: alles über Kanten
- gleiche Daten in allen drei abgebildet
-->
---
layout: two-cols
layoutClass: gap-10
---
# Key-Value mit Redis
<div class="pt-8 text-lg space-y-4 opacity-80">
Keys sind Strings, eindeutig pro Objekt.
Aufbau: Entität : ID
</div>
::right::
<div class="pt-14">
```text
weapon:213
player:1
region:1:items
enemy:1
```
</div>
<!--
- Beim Key-Value-Modell läuft alles über Schlüssel
- Jeder Key ist ein String und steht für genau ein Objekt
- Aufbau ist einfach: Name der Entität, Doppelpunkt, ID
- Objekte speichern wir als Hash Map, Listen und Mengen als SET
-->
---
layout: default
---
# Key-Value: Schlüsselaufbau
<div class="text-sm pt-4">
| Datentyp | Key-Struktur | Attribute |
|----------|--------------|-----------|
| HMAP | `player:{id}` | id, name, health, level, region_id |
| SET | `player:{id}:armor` | item_id |
| HMAP | `enemy:{id}` | id, name, health, damage |
</div>
<div class="pt-4 opacity-70 text-sm">
Über den Key direkt ans Objekt.
</div>
<!--
- Jede Entität bekommt ihren eigenen Key
- Die Ausrüstung hängen wir über Sub-Keys dran, z.B. player:1:armor
- So kommen wir über den Key direkt ans Objekt, ganz ohne Suchen
-->
---
layout: two-cols
layoutClass: gap-10
---
# Dokument mit MongoDB
<div class="pt-8 text-lg space-y-4 opacity-80">
Zusammengehöriges in einem Dokument.
Jede Entität eine Collection.
Ausrüstung nur als ids.
</div>
::right::
<div class="pt-14">
```js
player {
id: 1,
name: "Jonas",
health: 100,
stamina: 100,
level: 1,
region_id: 1,
weapon: [ 12 ],
shield: 30,
armor: [ 41, 42 ],
talisman: [ 7 ]
}
```
</div>
<!--
- Beim Dokument-Modell packen wir Zusammengehöriges in ein Dokument
- Jede Entität bekommt ihre eigene Collection
- Vom Spieler aus halten wir bei der Ausrüstung nur die ids fest
-->
---
layout: default
---
# Dokument: Beispiele
<div class="grid grid-cols-3 gap-4 pt-6 text-sm">
```js
weapon {
id: 213,
item_type: {
id: 1,
name: "Dolch"
},
item_effect: {
id: 4,
name: "Stärke",
value: 5
},
weight: 2,
damage: 70
}
```
```js
enemy {
id: 1,
region_id: 1,
name: "Tree_Sentinel",
health: 30000,
level: 20,
damage: 70,
items: [ 5, 10 ]
}
```
```js
region {
id: 1,
name: "Limgrave",
items: [ 12, 19, 248 ],
enemies: [ 1, 245 ]
}
```
</div>
<div class="pt-6 opacity-70 text-sm">
Weapon trägt item_type und item_effect direkt. Sonst meist nur ids.
</div>
<!--
- Die Weapon bringt item_type und item_effect direkt mit
- Enemy und Region verweisen über ids auf ihre Items
- Bei uns sind es also meist nur ids statt tiefer Verschachtelung
-->
---
layout: two-cols
layoutClass: gap-10
---
# Graph mit Neo4j
<div class="pt-8 text-lg space-y-4 opacity-80">
Fokus auf den Beziehungen.
Jede Entität ein Knoten mit eigenen Werten.
</div>
::right::
<div class="pt-6 text-sm">
| Knoten | Attribute |
|--------|-----------|
| Player | id, name, health, level |
| Weapon | id, weight, damage |
| Enemy | id, name, health, damage |
</div>
<!--
- Beim Graph-Modell liegt der Fokus auf den Beziehungen
- Jede Entität wird ein Knoten und trägt ihre Werte direkt
- Die Verbindungen kommen dann über die Kanten dazu
-->
---
layout: default
---
# Graph: Kanten
<div class="text-sm pt-6">
| Von | Kante | Nach |
|-----|-------|------|
| Player | has_equipped | Weapon |
| Player | is_in | Region |
| Region | has | Enemy |
| Enemy | drops | Item |
</div>
<div class="pt-6 opacity-70 text-sm">
Kanten wie im ER-Modell.
</div>
<!--
- Die Kanten sind genau die Beziehungen aus dem ER-Modell
- Zum Beispiel has_equipped, is_in, has und drops
- Damit lassen sich die Beziehungen direkt verfolgen
-->
---
layout: default
---
# Vergleich: Key-Value
<div class="grid grid-cols-2 gap-8 pt-10">
<div class="p-6 rounded-xl bg-green-500/10">
<div class="font-bold text-green-500 pb-3">Vorteil</div>
Extrem schnell, direkter Zugriff über Key. Ideal für Live Daten.
</div>
<div class="p-6 rounded-xl bg-red-500/10">
<div class="font-bold text-red-500 pb-3">Nachteil</div>
Komplexe Abfragen müssen wir selbst zusammenbauen.
</div>
</div>
<!--
- Der Vorteil ist das Tempo: über den Key direkt ans Objekt, ideal für Live-Daten
- Der Nachteil: komplexe Abfragen müssen wir selbst zusammenbauen
- Zum Beispiel alle Weapon mit einem bestimmten item_effect
-->
---
layout: default
---
# Vergleich: Dokument
<div class="grid grid-cols-2 gap-8 pt-10">
<div class="p-6 rounded-xl bg-green-500/10">
<div class="font-bold text-green-500 pb-3">Vorteil</div>
Leserlich und einfach zu modellieren.
</div>
<div class="p-6 rounded-xl bg-red-500/10">
<div class="font-bold text-red-500 pb-3">Nachteil</div>
Bei uns meist nur ids. Stärke kaum genutzt.
</div>
</div>
<!--
- Der Vorteil: sehr leserlich und einfach zu modellieren
- Der Nachteil: bei uns sind es meist nur ids, kaum verschachtelt
- Die eigentliche Stärke nutzen wir damit kaum aus
-->
---
layout: default
---
# Vergleich: Graph
<div class="grid grid-cols-2 gap-8 pt-10">
<div class="p-6 rounded-xl bg-green-500/10">
<div class="font-bold text-green-500 pb-3">Vorteil</div>
Beziehungen sehr leicht abfragbar, ohne Umwege.
</div>
<div class="p-6 rounded-xl bg-red-500/10">
<div class="font-bold text-red-500 pb-3">Nachteil</div>
Für uns überdimensioniert. Wir brauchen vor allem Tempo.
</div>
</div>
<!--
- Der Vorteil: Beziehungen lassen sich super leicht abfragen
- Etwa welcher Player welche Weapon trägt oder welches Item ein Enemy droppt
- Der Nachteil: für unseren Fall ist das überdimensioniert
- Wir brauchen schnelles Schreiben und Lesen, keine tiefen Abfragen
-->
---
layout: default
---
# Was bringt uns welches Modell?
<div class="grid grid-cols-3 gap-6 pt-12 text-center">
<div class="p-6 rounded-xl bg-red-400/10">
<div class="text-2xl font-bold">Key-Value</div>
<div class="pt-4 text-3xl"></div>
<div class="pt-3 text-sm opacity-80">Live-Daten des Players sofort lesen</div>
</div>
<div class="p-6 rounded-xl bg-green-400/10">
<div class="text-2xl font-bold">Dokument</div>
<div class="pt-4 text-3xl">📖</div>
<div class="pt-3 text-sm opacity-80">Ganzer Player mit Ausrüstung in einem Dokument</div>
</div>
<div class="p-6 rounded-xl bg-blue-400/10">
<div class="text-2xl font-bold">Graph</div>
<div class="pt-4 text-3xl">🔗</div>
<div class="pt-3 text-sm opacity-80">Welches Item ein Enemy droppt, direkt abfragbar</div>
</div>
</div>
<div class="pt-10 text-center opacity-70">
Wir brauchen vor allem Tempo.
</div>
<!--
- Key-Value gibt uns Tempo pur
- Dokument ist schön übersichtlich
- Graph ist stark bei den Beziehungen
- Für uns zählt am Ende vor allem das Tempo
-->
---
layout: default
---
# Was uns wichtig ist
<div class="pt-10 text-lg">
| | Redis | MongoDB | Neo4j |
|---|:---:|:---:|:---:|
| Performanz | 2 | 1 | 1 |
| Indexing | 1 | 1 | 1 |
| Latenz | 2 | 0 | 0 |
| ... weitere Kriterien | ... | ... | ... |
| **Summe** | **30** | **15** | **14** |
</div>
<div class="pt-6 opacity-70 text-sm">
Redis gewinnt klar.
</div>
<!--
- Wir haben Kriterien aus dem Szenario aufgestellt und gewichtet
- Performanz und keine Lizenzkosten sind für uns Pflicht
- Am Ende gewinnt Redis klar: 30 gegen 15 gegen 14
-->
---
layout: center
class: text-center
---
# Fazit
<div class="text-2xl pt-4">
Wir wählen <span class="text-red-500 font-bold">Key-Value mit Redis</span>
</div>
<div class="grid grid-cols-3 gap-6 pt-10 text-left text-sm">
<div class="p-5 rounded-xl bg-gray-400/10">
<div class="font-semibold pb-2">Geschwindigkeit</div>
Live schreiben und lesen.
</div>
<div class="p-5 rounded-xl bg-gray-400/10">
<div class="font-semibold pb-2">Direkter Zugriff</div>
Über den Key sofort ans Objekt.
</div>
<div class="p-5 rounded-xl bg-gray-400/10">
<div class="font-semibold pb-2">Passende Größe</div>
Flache Daten, keine tiefe Verschachtelung.
</div>
</div>
<!--
- Unsere Wahl fällt auf Key-Value mit Redis
- Drei Gründe: Geschwindigkeit, direkter Zugriff und die passende Größe
- Komplexe Abfragen brauchen wir bei uns kaum
-->
---
layout: center
class: text-center
---
# Danke fürs Zuhören
<div class="pt-10 opacity-60">
Fragen?
</div>
<div class="pt-8 opacity-50 text-sm">
Justin Rost · Michelle Reichelt · Yasin Ergün
</div>
<!--
- Danke fürs Zuhören
- Als nächstes setzen wir die Datenbank auf dem Server auf und bauen das Schema um
- Jetzt sind wir offen für eure Fragen
-->