mmofacts.com

Wie viele spalten darf eine mysql-tabelle haben?

gepostet vor 19 Jahre, 3 Monate von Jackk
hallo,

meine spielerdaten-tabelle (mysql) hat 26 spalten und es werden wahrscheinlich noch mehr, wenn ich so weiter mache...

jetzt wollte ich einfach mal fragen, ob ich mir irgendwann sorgen um die performance der tabelle machen muss. wann sollte ich die tabelle lieber splitten? oder gibt es da keine probleme?

es spielt dabei bestimmt auch eine wichtige rolle, was die spalten für inhalte haben (bzw. was für daten da drin sind): also neben den hauptdaten, wie email-adresse, passwort, spielername und so, ist das meiste int(1-11), aber eine spalte beinhaltet zum beispiel auch einen text pro spieler, der länger als 255 zeichen werden kann.

wie sieht's aus? hat da jemand erfahrung mit und kann mir ein paar "richtwerte" geben?
gepostet vor 19 Jahre, 3 Monate von Teonas
Ich will hier keine Abhandlung über Normalisierung und Performance halten, aber das Thema Normalisierung könntest du dir zum Thema Begrenzung der Spalten im Hinblick auf Speicherffizienz mal anschauen.

Ich nehm zu dem Thema etwas schwerere Literatur, deshalb kann ich aus dem Stegreif nichts für Einsteiger nennen aber Google mal - vielleicht sagt dir das Thema auch was oder ein Folgepost verweist auf was. Bei Informatikvorkenntnissen auf FH/Uni-Niveau schreib mir mal ne PM.

Generell empfehle ich diesen Thread als Lektüre und empfehle die Requests anzuschauen, die auf deinen Daten laufen sollen und daraufhin die Spalten, die in einer Tabelle sind, zu designen. Je weniger JOINs verschiedener Tabellen du machen musst, desto besser für die Geschwindigkeit.

Aber generell würd ich sagen: NICHT _ALLES_ IN _EINE_ TABELLE ! Aber ich glaub, du bist da mit den INTs auf nem guten Weg. Wenn du die Daten selten brauchst (Spielerdaten sind in Browsergames jetzt nicht soo wichtig und häufig genutzt) ist zudem fast egal.
gepostet vor 19 Jahre, 3 Monate von Jackk
jo, normalisierung sagt mir schon was. aber ich halte ja schon so alle daten nach bestem wissen und gewissen auf dem minimum an benötigter speicherkapazität. ich behaupte also mal ganz von mir selbst überzeugt, dass mit einer normalisierung (zumindest in dem umfang, in dem ich eine normalisierung kenne) nicht mehr viel rauszuholen ist. es gehört einfach alles in diese tabelle!!! das einzige, was mir einfällt, was ich machen kann, ist, die tabelle aufzuteilen in mehrere tabellen, die dann jeweils eine 1:1-beziehung haben.

also ich glaube, ich werde die benutzerdaten, die meistens varchars (und in einem fall auch längerer text) sind und demnach auch ein bisschen mehr speicher fressen (dafür aber weniger genutzt werden) in eine neue tabelle verbannen. dann verbleiben nur noch die ganzen ints, die auch relativ häufig gebraucht werden (das sind dann allerdings auch noch so an die 20 spalten, aber dafür sind alles nur kleine ints). ist das sinnvoll?
gepostet vor 19 Jahre, 3 Monate von Teonas
Ok, ich hab jetzt mal kurz eine Hilfe gelesen und kann mir jetzt ansatzweise vorstellen, was dein Spiel macht und deine Daten wahrscheinlich so bedeuten werden.

Wenn alle deine Daten von der UserID abhängen und sich oft ändern (danach riecht das jetzt mal), wirst du bei entsprechend vielen Spielern das Problem bekommen, dass eine einzige Tabelle wohl zum ultimativen Hotspot wird.

Dauernd werden Updates darauf gefahren, ne MyISAM lockt alles immer komplett und du wirst an der Lastgrenze wahrscheinlich kontinuierlich Kollisionen auf der Tabelle bekommen. Das ganze multipliziert sich sich dann weil die abgewiesenen Requests mehrfach ausgeführt werden etc.

Deshalb würde ich es aus Performancegründen und unter der Randbedingung MySQL und MyISAM alles in möglichst viele einzelne Tabellen zerlegen. Natürlich nicht so viele, dass du für jede Seite 12 SELECTs / 12-fach-JOINS brauchst, sondern irgendwo logisch dazwischen.

Das Problem wird hier also nicht die Anzahl der Spalten in einer Tabelle, sondern der effiziente Zugriff - ein Kochrezept kann ich da nicht geben, das hängt viel zu sehr von deinem Seiten-Zugriffsdesign ab.
gepostet vor 19 Jahre, 3 Monate von HSINC
also ich würde sagen, bau einfach. ein richtiges db design ist zwar wichtig, jedoch um eins hinzubekommen braucht man viele infos und "kniffe" (zb ob dynamische oder starre tab, anzahl/grösse der tabs und der daraus resultierenden joins/selects/updates/deletes, normalisierung wie weit (nicht immer ist die 3 nf sinnvoll), welche storageengine (myisam/inno/etc), keys(wenn ja auf welche spalten/über welche spalten), config des servers,etc) die lernt man mit der zeit wenn man sich mit dem ganzen zeug auseinander setzt, zb ist die mysqlhilfe (u.a. wie (schnell) mysql welche operation ausführt, wie sucht,etc steht alles da drinne) da auch gar nicht mal so schlecht.

eine spaltenbegrenzung von mysql/myisam ist mir nicht bekannt, innodb hat/te 500 aber die info stammt vo knapp einem jahr.
meine grösste tab hatte rund 240 spalten als ich sie das letzte mal gezaehlt hab und ich bin bis jetzt recht gut damit gefahren.
gepostet vor 19 Jahre, 3 Monate von Kampfhoernchen
Es gibt eine grenze bei 64000 so weit ich weiß. Aber die Tabelle ist dann schon etwas zu groß. Ich denke mal, dass du bei Spielern ja auch E-Mail, Profil usw. mit reinspeicherst, und damit soviel Platz verbrauchst. Mein vorschlag wäre es, zwei weitere Tabellen anzulegen, die

spieler_zusatz_info
Spalten:
info_id, spieler_id, typ, wert (TEXT ist hier ganz sinnvoll)
ein Index über spieler

oder info_id weglassen und den Primärschlüssel über spieler_id und typ

und

zusatz_info_typ
mit Spalten typ_id und typ_name

In die Spielertabelle speicherst du dann nur die Daten rein, die du sehr oft brauchst (Name, Passwort, Hauptplanet ...)
Infos wie E-Mail, Registrierungsdatum ect. parkst du in der zusatzinfo-Tabelle, da du auf diese ja nicht allzuoft zugreifst.

Ist zwar auch nicht grad die strengste Normalform, aber es ist performancemäßig wohl das schnellste.

Generell kann man glaub ich sagen, dass bis 20 Spalten vertretbar sind, was darüber hinausgeht, eher nicht.
gepostet vor 19 Jahre, 3 Monate von HSINC
@kampfhörnchen, wenn du eine spalte text/varchar in irgendeiner tab anlegst, dann ist es sogut wie völlig sinnlos daten aus dieser tab auszulagern. denn dann bekommt die ganze tab eine dynamische datansatzlänge (was es schwieriger für die db die daten zu finden (via key) macht (da bei starren tabs er nur gefunde zeilenanzahl*datensatzlänge nehmen muss um zu wissen wo er anfängt)). und die daten die ehh nie gebraucht werden stehen dann halt drinne und werden nicht gebraucht. ist doch egal, perf mässig nehmen die nichts weg (bzw es kommt auch auf die daten drauf an, wirre text/blog spalten mit sehr unterschiedlichen längen die sich auch noch häufig ändern, machen schon was aus (wegen der reogansierung und fragmentierung))
aber wie gesagt ein trennen von tabs machts defintiv sinn wenn die eine tab auf die häufig zugegriffen wird, dann starr wird (und man die andere tab nicht häufig braucht(weil sonst wieder verluste durch sinnlose joins))
gepostet vor 19 Jahre, 3 Monate von Jackk
ok, erstmal danke für die ganze hilfe.

ich habe mich jetzt dazu entschlossen, die tabelle in einem späteren stadium aufzuteilen (hab ja im moment sowieso erst 20 testspieler). ich hab nur noch eine frage: was genau muss eine tabelle haben, damit sie dynamisch (und nicht starr) wird?
gepostet vor 19 Jahre, 3 Monate von HSINC
starres format: jede spalte hat eine definierte grösse (also besteht nur zb int,char(x)) (weil da jede zeile die gleiche länge hat(int 8byte,char x byte)) (die grösse wird aber dann auch immer belegt), dynamische grösse sind tabellen die ein varchar, text oder blog spaltentyp haben (wo also die länge der spalte von vornherein nicht feststeht (da man ja zb in eine zeile 65k text schreiben kann und in die nächste 1k und mysql da nur soviel speicher belegt wieviel wirklich benötigt wird))

im phpmyadmin steht in der tabübersicht unten recht was für ein typ das ist
gepostet vor 19 Jahre, 3 Monate von Jackk
ok, danke. ich glaube, jetzt weiß ich schon eine menge mehr
gepostet vor 19 Jahre, 3 Monate von Jackk
ich habe da noch eine frage und möchte dafür aber nicht wieder extra ein neues thema eröffnen:

kann eigentlich die ausführung eines php-scriptes vom client irgendwie unterbrochen werden, oder wird jedes angefangene script automatisch zuende ausgeführt (selbst wenn der benutzer sofort nach aufruf der seite den browser schließt bzw. auf "abbrechen" geht)? dann spricht ja eigentlich nichts dagegen, dass man lange und wichtige aktionen durch einen normalen seitenaufruf eines users auslöst (z.b. das erstellen von mehreren neuen tabellen mit ein paar datensätzen, die dann einen ganz neuen teil des ganzen spiels darstellen). oder?
gepostet vor 19 Jahre, 3 Monate von MannaZ
Schau dir mal die Funktion

ignore_user_abort();

genauer an. Das sollte dir weiterhelfen.
gepostet vor 19 Jahre, 3 Monate von Jackk
danke, es hat mir weiter geholfen (-;

Auf diese Diskussion antworten