Skip to content

Datenbank

LeonardNolting edited this page Aug 21, 2021 · 21 revisions

Anbieter

Aufgrund der einfachen (serverless, client-side) Benutzung und Realtime-Kompatibilität setzt dieses Projekt auf Googles NoSQL Firebase Realtime Database.

Anders als konventionelle Datenbanken, ist diese nicht aus Tabellen, Spalten, Zeilen, usw. aufgebaut, sondern ist letztendlich JSON.

Struktur VERALTET

Um den Code besser verstehen zu können, wird in diesem Abschnitt die Struktur der Datenbank erklärt. Dabei werden zur besseren Orientierung die Top-Level-Schlüssel in Klammern erwähnt.

Grundlegend

Es werden primär Eintragungen gespeichert (strecken).

Zur Unterteilung dieser in Schüler, Klassen und Schulen, werden diese separat gespeichert (fahrer, klassen, schulen).

Für ein möglichst schnelles First Meaningful Paint wird die insgesamt gefahrene Strecke nicht berechnet, sondern gesondert aufgeführt (strecke).

Zusätzlich

Weiterhin werden Daten gesammelt, die der Benutzererfahrung dienen oder später analysiert werden können.

Um dem Benutzer die Eingabe sich wiederholender Orte zu erleichtern, werden diese, zusammen mit der Häufigkeit der Benutzung, abgespeichert (orte). Dann können ihm beispielsweise die drei am häufigsten benutzten Orte jeweils zur Auswahl angezeigt werden.

Außerdem können die Koordinaten einer Strecke gespeichert werden, sofern diese bekannt sind (der Benutzer die Kilometeranzahl nicht direkt eingibt, sondern berechnen lässt). Da allerdings die Antwort des Distance Matrix Service keine Koordinaten beinhaltet, sondern nur die angegebenen Adressen, wird dieses Feld (routen) momentan nicht benutzt.

Struktur NEU

Die Datenbank ist unterteilt in zwei grobe "namespaces": "allgemein" und "spezifisch".

Allgemein

Hier werden Werte gespeichert, die sich über mehrere Saisons hinweg entwickeln/verändern.

Saisons

laufend

Saison, deren Startzeit in der Vergangenheit liegt und deren Endzeit entweder nicht gegeben ist oder in der Zukunft liegt.

aktiv

Saison, die standardmäßig bei der Saisonauswahl ausgewählt wird.

aktuell

Saison, die zuletzt eingetragen wurde und deren Endzeit nicht in der Vergangenheit liegt. Wie laufend, nur auch schon vor der Saisonstart passiert ist.

details

zeit

Die Zeiten der Saison werden lediglich zur Anzeige der Countdowns genutzt und sollen nicht anderweitig Verwendung finden. Um den Status einer Saison zu erfahren siehe global/saisons/laufend & global/saisons/aktiv.

Schulen

Spezifisch

Hier werden Werte gespeichert, die entweder für die aktuelle Saison wichtig sind oder für die Aktive, falls keine Aktuelle vorhanden ist.

Anmerkungen

(Zeitlich) Eindeutige Schlüssel werden über die JavaScript-API generiert, sodass von mehreren Orten aus gleichzeitig Listen-Einträge konfliktlos eingetragen werden können.

Die hier umgesetzte Denormalisierung der Struktur ist beabsichtigt und Best Practice bei NoSQL.

Zur Query-Optimierung werden in den Sicherheitsregeln der Datenbank einige Felder vorab geindexed.

Alle Längen werden in Metern gespeichert.

Beim Aktualisieren der strecke, anzahlStrecken, anzahlFahrer und angefeuert-Schlüssel muss Gleichzeitigkeit beachtet werden, sodass diese Werte immer richtig bleiben. Dieses Problem kann entweder durch sog. Transactions oder durch Atomic Server-side Increments gelöst werden.

Countdowns

Countdowns werden allgemein gespeichert (allgemein/saisons/countdowns), damit die entsprechenden functions durch Setzen dieser getriggert werden können. Sobald Start bzw. Ende passiert sind, werden diese in der entsprechenden Saison gespeichert (allgemein/saisons/:saison/zeit), zur evtl. späteren Auswertung.

Beispiel

Die hier benutzten Schlüssel dienen nur zur Veranschaulichung und sehen eigentlich anders aus.

x dient als Platzhalter für eine Zahl.

{
	"allgemein": {
		"strecke": x,
		"anzahlStrecken": x,
		"anzahlFahrer": x,
		"saisons": {
			"aktiv": "2021",
			"laufend": "2021",
			"aktuell": "2021",
			"anzahl": x,
			"anzahlHistorisch": x,
			"countdowns": {
				"start": x,
				"ende": x
			},
			"liste": {
				"2021": true
			},
			"details": {
				"2021": {
					"zeit": {
						"start": x,
						"ende": x
					},
					"runden": x,
					"strecke": x,
					"anzahlStrecken": x,
					"anzahlFahrer": x,
					"schulen": {
						"liste": {
							"Gymnasium Höchstadt": true
						},
						"details": {
							"Gymnasium Höchstadt": {
								"strecke": x,
								"anzahlStrecken": x,
								"anzahlFahrer": x,
								"potAnzahlFahrer": x,
								"angefeuert": x
							}
						}
					}
				}
			}
		},
		"schulen": {
			"liste": {
				"Gymnasium Höchstadt": true
			},
			"details": {
				"Gymnasium Höchstadt": {
					"saisons": {
						"liste": {
							"2021": true
						}
					}
				}
			}
		}
	},
	"spezifisch": {
		"klassen": {
			"leer": false,
			"liste": {
				"Gymnasium Höchstadt": {
					"9D": true
				}
			},
			"details": {
				"Gymnasium Höchstadt": {
					"9D": {
						"strecke": x,
						"anzahlStrecken": x,
						"anzahlFahrer": x,
						"potAnzahlFahrer": x,
						"email": "schmidt@gy-ho.de",
						"uid": "XA-32A98fAga-",
						"fahrer": {
							"Leonard Nolting": "fahrerEins"
						}
					}
				}
			}
		},
		"fahrer": {
			"fahrerEins": {
				"schule": "Gymnasium Höchstadt",
				"klasse": "klasseEins",
				"name": "Leonard Nolting",
				"strecke": x,
				"anzahlStrecken": x
			}
		},
		"strecken": {
			"streckeEins": {
				"fahrer": "fahrerEins",
				"strecke": x,
				"zeitpunkt": x
			}
		},
		"routen": {
			"streckeEins": {
				"von": {
					"ort": "Am Hopfengarten 5",
					"lat": x,
					"lng": x
				},
				"zu": {
					"ort": "Gymnasium Höchstadt a. d. Aisch",
					"lat": x,
					"lng": x
				}
			}
		},
		"orte": {
			"fahrerEins": {
				"Gymnasium Höchstadt a. d. Aisch": 5,
				"Am Hopfengarten 5": 3,
				"Eiffelturm": 1,
				"Eisdiele Höchstadt": 1
			}
		}
	}
}
Clone this wiki locally