2026-06-02 15:00:51 +02:00

682 lines
15 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
Eine einfache und schnelle Lösung für unstrukturierte Daten.
Keys sind Strings und identifizieren ein Objekt eindeutig.
Aufbau: Name der Entität, Doppelpunkt, ID des Objekts.
::right::
<div class="pt-14">
```text
weapon:213
player:1
region:1:items
enemy:1
```
</div>
<div class="pt-6 opacity-80">
Die meisten Entitäten liegen als Hash Map. Listen und Mengen als SET.
</div>
<!--
- Keys sind Strings und identifizieren ein Objekt eindeutig
- Aufbau: Name der Entität, Doppelpunkt, ID
- meiste Entitäten 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 | `weapon:{id}` | id, item_effect_id, item_type_id, weight, damage |
| HMAP | `item:{id}` | id, name, gear_type, gear_id |
| HMAP | `player:{id}` | id, name, health, stamina, level, region_id |
| SET | `player:{id}:armor` | item_id |
| STRING | `player:{id}:shield` | item_id |
| HMAP | `region:{id}` | id, name |
| SET | `region:{id}:enemies` | enemy_id |
| HMAP | `enemy:{id}` | id, name, health, level, damage |
</div>
<div class="pt-4 opacity-70 text-sm">
Über den Key kommen wir direkt an ein Objekt, ohne lange zu suchen.
</div>
<!--
- jede Entität bekommt einen eigenen Key
- Ausrüstung des Players über Sub-Keys, z.B. player:1:armor
- über den Key direkt ans Objekt, ohne Suchen
-->
---
layout: two-cols
layoutClass: gap-10
---
# Dokument mit MongoDB
Alles was zusammengehört, liegt gebündelt in einem Dokument.
Jede Entität wird zu einem Dokument in einer eigenen Collection.
Der Player hält von seiner Ausrüstung nur die ids fest, denn Weapon und Co. liegen in eigenen Dokumenten.
::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>
<!--
- alles Zusammengehörige gebündelt in einem Dokument
- jede Entität eigene Collection
- Player hält von 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 bringt item_type und item_effect direkt mit. Player, Item, Region und Enemy zeigen meist nur über ids.
</div>
<!--
- Weapon bringt item_type und item_effect direkt mit
- Enemy und Region verweisen über ids auf ihre Items
- bei uns meist nur ids statt tiefer Verschachtelung
-->
---
layout: two-cols
layoutClass: gap-10
---
# Graph mit Neo4j
Der Fokus liegt auf den Beziehungen zwischen den Objekten.
Jede Entität wird zu einem Knoten, der seine Werte direkt mitträgt.
::right::
<div class="pt-6 text-sm">
| Knoten | Attribute |
|--------|-----------|
| Player | id, name, health, stamina, level |
| Weapon | id, weight, damage |
| Type | id, name |
| item_effect | id, name, value |
| Item | id, name |
| Region | id, name |
| Enemy | id, name, health, level, damage |
</div>
<!--
- Fokus liegt auf den Beziehungen zwischen Objekten
- jede Entität wird ein Knoten und trägt seine Werte direkt
-->
---
layout: default
---
# Graph: Kanten
<div class="text-sm pt-6">
| Von | Kante | Nach |
|-----|-------|------|
| Player | has_equipped | Weapon, Armor, Shield, Talisman |
| Player | is_in | Region |
| Weapon, Armor, Shield | has | Type |
| Weapon, Armor, Shield, Talisman | has | item_effect |
| Weapon, Armor, Shield, Talisman | is | Item |
| Region | has | Item, Enemy |
| Enemy | drops | Item |
</div>
<div class="pt-6 opacity-70 text-sm">
Die Kanten verbinden die Knoten so, wie es schon das ER-Modell vorgibt.
</div>
<!--
- Kanten sind die Beziehungen aus dem ER-Modell
- has_equipped, is_in, has, drops
- Beziehungen lassen sich 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>
Redis ist extrem schnell. Über die Keys kommen wir direkt an ein Objekt. Genau das brauchen wir für die Live Daten des Players.
</div>
<div class="p-6 rounded-xl bg-red-500/10">
<div class="font-bold text-red-500 pb-3">Nachteil</div>
Komplexe Abfragen sind schwierig. Alle Weapon mit einem bestimmten item_effect müssen wir in der Anwendung selbst zusammenbauen.
</div>
</div>
<!--
- Vorteil: extrem schnell, direkter Zugriff über Key, ideal für Live-Daten
- Nachteil: komplexe Abfragen müssen wir selbst zusammenbauen
- Beispiel: alle Weapon mit bestimmtem 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>
Sehr leserlich und einfach zu modellieren. Jedes Dokument ist für sich verständlich und man sieht direkt, welche Daten zusammengehören.
</div>
<div class="p-6 rounded-xl bg-red-500/10">
<div class="font-bold text-red-500 pb-3">Nachteil</div>
Bei uns wird das meiste über ids referenziert und nur wenig verschachtelt. Wir nutzen die Stärke des Modells kaum.
</div>
</div>
<!--
- Vorteil: sehr leserlich und einfach zu modellieren
- Nachteil: bei uns meist ids, kaum verschachtelt
- die eigentliche Stärke nutzen wir kaum
-->
---
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 lassen sich sehr leicht abfragen. Welcher Player welche Weapon trägt oder welches Item ein Enemy fallen lässt, ohne Umwege.
</div>
<div class="p-6 rounded-xl bg-red-500/10">
<div class="font-bold text-red-500 pb-3">Nachteil</div>
Neo4j ist für unseren Fall überdimensioniert. Wir schreiben und lesen vor allem schnell, statt ständig tiefe Beziehungen abzufragen.
</div>
</div>
<!--
- Vorteil: Beziehungen sehr leicht abfragbar
- Beispiel: welcher Player welche Weapon trägt, welches Item ein Enemy droppt
- Nachteil: für unseren Fall überdimensioniert
- wir brauchen schnelles Schreiben und Lesen, keine tiefen Abfragen
-->
---
layout: default
---
# Gegenüberstellung
<div class="pt-8 text-lg">
| | Key-Value | Dokument | Graph |
|---|:---:|:---:|:---:|
| Schreiben und Lesen | ✅ sehr schnell | 🟡 gut | 🟡 mehr Aufwand |
| Direkter Objektzugriff | ✅ über Key | ✅ über Collection | 🟡 über Knoten |
| Komplexe Abfragen | 🔴 schwierig | 🟡 mittel | ✅ stark |
| Passt zu Live Daten | ✅ ideal | 🟡 ok | 🔴 überdimensioniert |
</div>
<div class="pt-8 opacity-70">
Unsere Daten sind flach und ändern sich ständig. Tiefe Beziehungen brauchen wir kaum.
</div>
<!--
- Tabelle fasst die drei Modelle zusammen
- Key-Value vorn bei Tempo und direktem Zugriff
- unsere Daten flach und ständig in Bewegung
-->
---
layout: default
---
# Was uns wichtig ist
<div class="grid grid-cols-2 gap-8 pt-6 text-sm">
<div>
| Kriterium | Muss | Gewicht |
|-----------|:----:|:-------:|
| Hohe Performanz | ja | 5 |
| Keine Lizenzkosten | ja | 5 |
| Daten-Streaming | ja | 3 |
| Niedrige Latenz | ja | 3 |
| Indexing | nein | 2 |
</div>
<div>
| | MariaDB | Redis | MongoDB |
|---|:---:|:---:|:---:|
| Performanz | 0 | 2 | 1 |
| Streaming | 0 | 2 | 0 |
| Latenz | 1 | 2 | 0 |
| **Summe** | **11** | **30** | **15** |
</div>
</div>
<div class="pt-6 opacity-70 text-sm">
Latenzfrei und performant ist für uns Pflicht. In den Tests gewinnt Redis klar.
</div>
<!--
- Kriterien aus dem Szenario gewichtet
- Performanz und keine Lizenzkosten sind Pflicht
- in den Tests gewinnt Redis klar: 30 vs 11 vs 15
-->
---
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>
Daten des Players live schreiben und genauso live zurücklesen.
</div>
<div class="p-5 rounded-xl bg-gray-400/10">
<div class="font-semibold pb-2">Direkter Zugriff</div>
Über die Keys sofort an ein Objekt, ohne lange Suche.
</div>
<div class="p-5 rounded-xl bg-gray-400/10">
<div class="font-semibold pb-2">Passende Größe</div>
Rund 100 Regionen, 500 Gegner, 3.300 Gegenstände. Keine tiefe Verschachtelung nötig.
</div>
</div>
<!--
- Wahl fällt auf Key-Value mit Redis
- drei Gründe: Geschwindigkeit, direkter Zugriff, passende Größe
- komplexe Abfragen brauchen wir kaum
-->
---
layout: center
class: text-center
---
# Danke
<div class="opacity-80 pt-4 text-lg">
Nächste Schritte: Datenbank auf dem Server aufsetzen und Schema umsetzen
</div>
<div class="pt-10 opacity-60">
Fragen?
</div>
<div class="pt-8 opacity-50 text-sm">
Justin Rost · Michelle Reichelt · Yasin Ergün
</div>
<!--
- Dank fürs Zuhören
- nächste Schritte: Datenbank auf Server aufsetzen, Schema umsetzen
- offen für Fragen
-->