Elia

Aus ProgrammingWiki

Wechseln zu: Navigation, Suche

Inhaltsverzeichnis

Idee & Ziel der Datenbank

Idee: Online Analytics Tool für das Spiel "League of Legends" nach dem Vorbild von u.gg

Ich selbst spiele gerne League of Legends. Bei diesem MOBA (Multiplayer-Online-Battle-Arena) spielen zwei Teams bestehend aus je 5 Spielern in einer Arena, der "Kluft der Beschwörer" gegeneinander.

Um zu gewinnen, muss ein Team den Nexus (eine Art Kristall) des gegnerischen Teams zerstören.
League of Legends Map
Jeder Spieler spielt dabei einen der über 150 Champions, und übernimmt eine der 5 Rollen: entweder spielt er auf der "Top-Lane", der "Mid-Lane", im "Jungle", oder auf der "Bot-Lane" (dort spielen Supporter und ADC zusammen). Zudem wählt man vor dem Spiel Runen für seinen Champion aus, die unterschiedliche Vorteile bringen. Über das Spiel hinweg generiert man durch das töten von Minions / Monstern oder durch einen Kill an einem gegnerischem Spieler Gold, mit dem man sich dann Items kaufen kann. Diese verbessern stark die Fähigkeiten des eigenen Champions, z.B. mit mehr Schaden oder Rüstung. Gewinnt man ein Match, steigt man im Ligasysten (Eisen, Bronze, Silber, Gold, Diamant,..) auf. Jetzt ist natürlich interessant zu wissen, z.B. welche Rune extrem gute Spieler in hohen Ligen auf welchem Champion verwenden, oder was sie sich für Items auf dem Champion "XY" kaufen. Das ist der grundlegende Nutzen von Seiten wie u.gg. Sie tracken alle Spiele in League of Legends, speisen diese Datenmengen in eine Datenbank, und machen sie jedermann zugänglich. Selbstverständlich können die Datenmengen dann noch sinnvoll analysiert werden, und so z.B. festgestellt werden, welche Items gerade mit welchen Champions eine hohe Winrate (also auf alle Spiele gerechnet prozentuale Erfolgswahrscheinlichkeit) haben. Programme wie "Mobalytics" gehen dann noch einen Schritt weiter, analysieren die Spieler des gegnerischen Teams, und zeigem einem vor dem Spiel ihre Schwächen und Stärken auf. So raffiniert das auch klingen mag, alles basiert auf einer Datenbank, und dieser will ich mich hier annehmen. Um den Aufwand im machbaren Bereich zu halten, werde ich mich bei z.B. Items oder Runen auf wenige, beispielhafte, Parameter beschränken; und den Spieler auch nur ein Item bzw. eine Rune pro Game erlauben.


ERM-Modell

Hilseduck Erm modulation(1)SMALL.jpg
Entitäten: Player, Game
Relations: spielt
Kardinalitäten:
[spielt]:
Ein Player spielt mehrere Games.
In einem Game spielen mehrere Player.
>> Beziehung Game - Player = n:m

Ich musste lange nachdenken, bis ich zu einem für mich zufriedenstellenden Ansatz für ein ERM-Modell gekommen bin. Mein ursprünglicher Plan war, einzelne Entitäten für Player, Game, Item, Champion und Rune zu erstellen. Das daraus resultierende Konstrukt ergab allerdings stets keinen Sinn. Denn Item, Champion und Runen sind in jedem Game unterschiedlich, aber werden gleichzeitig auch nur von einem Spieler gespielt. Nach langem Rätseln bin ich dann endlich auf die rettende Lösung gekommen: Champion, Rune, und Item sind Attribute der Beziehung zwischen Player & Game (namens "spielt"). Denn ein Player "spielt" in einem Game Champion xy, kauft sich und somit spielt Item xy & spielt den Runenpfad xy in einem Game; somit ist es für mich völlig logisch, diese als Attribute der Beziehung "spielt" zu werten.

Relationenmodell

Hilseduck Rm modell v1.jpg
um das ERM Modell in ein RM Modell zu transferieren, befolgte ich die folgenden Schritte:
Grundgerüst:
1. 2 Tabellen für die beiden Entitäten Game & Player
2. Tabelle für die n:m-Beziehung "spielt" dieser Entitäten Game & Player >> Name: "Game_Player". game_id & player_id als Fremdschlüssel; bilden zusammen den Primärschlüssel. Wichtig: Attribute der
Beziehung "spielt" wie champion_id, champion_name, item_id, rolle, win/team, etc. werden als weitere Nichtschlüsselattribute in die Tabelle Game_Player eingefügt.

Normalformen:
1. NF; alle Attribute sind bereits atomisiert (liegen in ihrer kleinstmöglichen Form da); nichts zu verändern
2. NF; alle Nichtschlüsselattribute hängen vom vollständigen Primärschlüssel ab.
3. NF; einige Nichtschlüsselattribute in Tabelle Game_Player hängen voneinenander ab; z.B. champion_name von champion_id. >> Auslagerung von allen Champion-, Item-, und Rune-Attributen in eigene Tabellen (namens Champion, Item, Rune). champion_id, item_id, rune_id als Fremdschlüssel in Game_Player.

letzte Veränderungen:
lange Attribute wie z.B. champion_id werden mit c_id abgekürzt, selbiges für item_... & rune_... >> i_... | r_...
Der Einheitlichkeit wegen wurden noch Start_Time bzw. End_Time von Game zu g_start_time bzw. g_end_time.
Der Primärschlüssel für Game_Player ist zusammengesetzt aus g_id und p_id, da ein Spieler in einem Game stets nur einmal spielt >> Einzigartig, keine Dopplungen >> eignet sich für Primärschlüssel.

SQL


Anmerkungen:
i_id in Game_Player darf NULL sein, da ja der Fall eintreten kann, dass ein Spieler nicht genügend Gold erwirtschaftet, um sich ein Item zu kaufen.
win_or_team darf lediglich 0 (für das Loosing Team) bzw. 1 (für das Winning Team) sein, daher die CHECKs.

Reflexion

Ich bin grundsätzlich zufrieden mit dem Ergebnis; das Ziel, welches ich mir zu Beginn gesteckt habe, wurde erreicht.

Verbesserungsvorschläge:
Würde man jetzt die Datenbank mit massenhaft Daten befüllen, könnte man tatsächlich nützliche Informationen gewinnen.
Selbstverständlich wurde alles stark vereinfacht; so kann ein Spieler in einem echten League of Legends Spiel bis zu 6 Items haben, ebenso fehlen in meiner Datenbank Parameter wie die Kills, Deaths und Assists in jedem Spiel, sowie das Gold, welches der Spieler im Spiel erwirtschaftet hat, und das Level, was er mit seinem Champion im Spiel erreicht hat. Die zusätzlichen Items könnte man mit 5 zusätzlichen Tabellen (Item_Slot_2, Item_Slot_3,...) lösen, die dann wieder via Fremdschlüssel in die Tabelle Game_Player eingebunden werden. Statistiken wie Kills, Deaths, Assists, oder auch das erwirtschaftete Gold bzw. das erreichte Champion Level im Spiel ließen sich sogar noch einfacher implementieren, indem man diese einfach als Nicht-Schlüssel-Attribute in die Tabelle Game_Player einfügt.
Selbstverständlich müssten dann noch die Millionen League of Legends-Accounts in die "Player" Tabelle gespeist werden, die 140 Champions in die Champion-Tabelle, und die sehr vielen Items in die Item-Tabelle.
Ein weiterer wichtiger Parameter, der für die Player wichtig wäre, ist die Region, also auf welchem Server die Spieler spielen (z.B. North-America, EU-West, Korea,...). Das wäre mittels einem einfachen Nicht-Schlüssel-Attribut namens "region" in der "Player" Tabelle realisierbar.
Vergleich
Das was die Datenbank des Projekts über ein game ausgibt:
Hilseduck Game overview.JPG
Das was u.gg über ein echtes League of Legends game ausgibt:
Hilseduck Original overview ugg.jpg
See no difference
Selbstkritik
Ich weiß nicht wie sinnvoll es war, z.B. den Item Namen auch bereits in der Item Tabelle i_name zu nennen, und in der Tabelle Game_Player denselben Namen i_name zu verwenden. Das führt nämlich dazu, dass man in den Abfragen stets z.B. item.i_name = game_player.i_name schreiben muss - etwas mehr Arbeit. Andererseits sieht man dadurch auch gleich, aus welchen Tabellen die Daten der Abfrage genommen werden, von daher ist es vielleicht auch gar nicht so schlecht.
Zudem sieht das ERM-Modell zugegeben etwas speziell aus - aber meinen Überlegungen zufolge gibt es keinen anderen sinnvollen Weg dafür, daher nehme ich das jetzt einfach mal so hin.
Zu guter Letzt ist noch zu sagen, dass ich die Tabelle Game_Player nur mit einem Game befüllt habe, des Aufwands wegen; selbstverständlich wäre es schön gewesen, evtl. 2 Game-Datensätze in dieser Tabelle zu haben.

Quellen

Verwendete Software:
sqlite.com >> schöner online sql editor/compiler, mit nützlichen Features wie Vervollständigungsvorschlägen
ERDplus.com
SQL-Tutorials:
sqlite check constraints - 18.03.2022
sql order by case - 24.03.2022
2 datetime werte voneinander abziehen >> via temporärer umwandlung ins julianday format - 24.03.2022
Projekt-Inspirationen:
u.gg - 18.03.2022

Persönliche Werkzeuge