mmofacts.com

"MySQL Core" Codebesprechung

gepostet vor 15 Jahre, 6 Monate von Phoscur

Nachdem Fobby meinte, ich solle das in nem extra Topic machen, wenn ich über Code reden möchte, tue ich das nun.

Ich schreibe eine Engine in PHP für Browsergames. Die Struktur wird ähnlich wie hier: http://www.galaxy-news.de/groups/2_entwickler/forums/5131_oop_klassendesign_modulverwaltung.html bereits diskutiert ausehen, mehr auch auf meinem Blog.

Die Engine habe ich schön abstrahiert, aber bei Rohstoffberechnungen oder Eventhandlern muss man stark auf Performance achten, da ist Klassen/Objektdesign auch nicht umbedingt angebracht.

Ich arbeite an einem OGame ähnlichen Spiel, aber wie es aussieht wird mein Spiel besser, schon allein der Rohstoffbug wurde bei OGame einfach nie gefixt ^^.

// Habe gerade festgestellt, dass der Code nicht so kurz ist.. ich stell meinen Text mal voran:

Das ist der Code für einen Eventhandler und eine (vollständige) Rohstoffberechnung in MySQL.

Bisher habe ich das ganze leider noch nicht richtig testen können, aber valid ist er und die Struktur der (doch recht komplexen) Rohstoffberechnung habe ich schon das zweite Mal geschrieben, beim ersten Mal war es eine (unperformante) PHP Klasse.

Der Eventhandler soll tatsächlich bei jedem Klick angekickt werden - Ja. Allerdings sind das eine bzw. mehrere Stored Procedures, die da in MySQL angeschoben werden. Ein Cursor für die abzuarbeitenden Flotten und dann ein paar kleine Queries je nach Mission der Flotte.

Die Missionen sind auch noch gar nicht ganz fertig, aber darauf kommt es gar nicht an.

Interessant dürfte die Prozedur zum auf-den-Heimweg-setzen der Flotte sein. Da habe ich mir eine Formel ausgedacht, die die Effizienz des verbrauchten Treibstoffs senkt, wenn das Schiff nicht mit optimaler Geschwindigkeit fliegt.

Dann kommt die Rohstoffberechnung. Ein System ist quasi ein Planet, nur logischer (15 Planeten in einem Sonnensystem bewohnbar... klar...). Die Rohstoffe heißen Aluminium, Silicium, Deuterium und Energie (kein richtiger Rohstoff..). Im MySQL Script ist die Anzahl der Rohstoffe festgeschrieben, aber ich werde die Installation mit PHP machen, das kann die Proceduren noch vor dem eingeben umformen für mehrere Rohstoffe und mehrere Energien.

Ich kenne das, wenn man fremden Code sieht, das Einarbeiten dauert eine ganze Weile. Ich hoffe nur, dass sich hier einige die Mühe machen werden, vor allem die mit den meisten MySQL Kenntnissen, denn ich hätte in dieser Richtung gerne noch einige Optimierungen. Was ansonsten noch ansteht weiß ich nicht, des halb schreibe ich ja diesen Topic. Ich hoffe auf ein wenig kontruktive Kritik :D

hier nun der Code:

Tabellen: http://pastebin.ch/548 (?pre = Tabellen Präfix)

Eventhandler: http://pastebin.ch/549

Rohstoffberechnung: http://pastebin.ch/542

gepostet vor 15 Jahre, 6 Monate von Jackflash

Hi,

 [wenn jemand nen nopaste MySQL Highlighter weiß bitte sagen!]:

http://pastebin.ch/

Gruss, Sam.

gepostet vor 15 Jahre, 6 Monate von Phoscur

Original von Jackflash

Hi,

 [wenn jemand nen nopaste MySQL Highlighter weiß bitte sagen!]:

http://pastebin.ch/

Gruss, Sam.

 Danke :D

Ich hoffe jetzt ist es etwas übersichtlicher. ;D

gepostet vor 15 Jahre, 6 Monate von Drezil

ka. den mysql-code check ich auf anhieb nicht..

bei den tabellen fällt mir auf: keine indizes?

Wie sieht es mit der datenintegrität bei unvorhergesehenen ereignissen aus? Ich denke mal, du nimmst myisam-tabellen (war ja immer standard), also kannst du keine transaktionen nutzen.

Wie sieht das nu eigentlich aus, wenn der strom mitten in der Berechnung ausfällt? Oder die Ausführung vom php-script gecancelt wird (du triggerst das doch alles von php aus, oder?)?

Hast du dann nachher nur noch müll in der Datenbank stehen, oder wird alles ordentlich zurückgerollt?

gepostet vor 15 Jahre, 6 Monate von Phoscur

Naja, wenn der Strom ausfällt kann ich nicht viel machen, das gibt wohl ein kleines Datenchaos.

Ich weiß, dass PHP in normaler (sinnvoller) Config Abfragen solange verarbeitet bis sie abgeschlossen oder abgebrochen werden. Ich denke nicht, dass die MySQL Prozeduren des Eventhandlers davon betroffen wären, da sie für PHP aus einem einzigen Query bestehen, das entweder abgeschickt ist oder eben nocht nicht.

Nun, für den Engine Code (OT) habe ich noch einige kleinere Probleme bei Scriptabbruch, ja, weil ich das übliche Konzept 1. SQL, 2. PHP, 3. SQL verwende.

Hier soll PHP ein Haufen Arbeit abgenommen werden, indem die meisten Berechnungen bereits SQL intern ablaufen, noch bevor PHP etwas zu tun bekommt, das nenne ich MySQL-Core. [0. SQL-Verarbeitung]

gepostet vor 15 Jahre, 6 Monate von Kallisti

Zunächst: Deine Links oben haben zwar den richtigen "Text", den Links selbt fehlt aber der get param.

Dann stimme ich bzgl. der Indizes erst einmal Drezil zu. Solltest auf jeden Fall mal schauen welche Spalten Du z.B. in "WHERE" statements benutzt und Indizes über die häufig genutzten legen. Grad foreign IDs sind da gute Kandidaten, wenn Du die nicht eplizit als solche deklarierst.

Ich bin kein großer Freund von Business Logic in der Datenbank. Imho macht man sich damit die Codewartung viel komplizierter. Abgesehen davon, dass SQL nicht so flexibel ist, wie normale Programmiersprachen und viele Dinge weit aufwendiger sind, hat man immer noch die Wartung an zwei völlig unterschiedlichen Stellen.

Im Grunde ist es nichts anderes als ein weiterer Ansatz, um an einem Daemon vorbeizukommen, der Dich nur umso mehr Performance kostet. Bei jedem (!) Request die SQL Events zu triggern und im gleichen Zug von Performance zu reden, klingt doch ein wenig surreal. ;)

Für mehr möchte ich nicht in fremdem Code wühlen, aber meine Empfehlung ist hier ganz klar, sich sehr, sehr weit von dem SQL Kram zu distanzieren (und sich damit auch viel unabhängiger zu machen), einen eigenen Daemon zu schreiben und dort alles auf abstrakter Ebene zu verarbeiten.

gepostet vor 15 Jahre, 6 Monate von HSINC

generell ist die frage, wie kommst du darauf das proceduren/functions in mysql automatisch atomar wären ? grade in hinblick auf raceconditions und mögliche scriptunterbrechungen wird das sicher probleme geben.

deswegen ein paar tipps, transactions sind wohl sinnvoll, solltest du dich mal mit befassen. die businesslocic nicht unbedingt die die db packen, man hat schneller einen weiteren webserver hingestellt als die db serverkapa erweitert (das ist aber wohl eher geschmackssache). informier dich über indizes, besonders wie wo welche art sinn macht und wo nicht. weiterhin, nimm keine reservierten begriffe für spaltennamen (zb end). meistens ist es auch besser mehrere tables zu nehmen statt alles auf krampf in einer zu quetschen.

gepostet vor 15 Jahre, 6 Monate von Phoscur

generell ist die frage, wie kommst du darauf das proceduren/functions in mysql automatisch atomar wären ?

Naja, wenn du sie mit PHP vergleichst...? [Verstehe ich dein "atomar" falsch? Meinst du doch "unteilbar"?

grade in hinblick auf raceconditions und mögliche scriptunterbrechungen wird das sicher probleme geben.

Die Raceconditions hab ich schon im Auge. Was meinst du mit Scriptunterbrechnungen? Soweit ich weiß bricht eine Prozedur im Gegensatz zum PHP Script nicht ab, wenn die Anfrage abgebrochen wird.

deswegen ein paar tipps, transactions sind wohl sinnvoll, solltest du dich mal mit befassen. die businesslocic nicht unbedingt die die db packen, man hat schneller einen weiteren webserver hingestellt als die db serverkapa erweitert (das ist aber wohl eher geschmackssache).

PHP bekommt auch noch Arbeit! ;D

informier dich über indizes, besonders wie wo welche art sinn macht und wo nicht.

Danke, das werde ich!

weiterhin, nimm keine reservierten begriffe für spaltennamen (zb end).

Auch nicht x_end? Edit: ich sehs grad... der Highlighter is auch drauf angesprungen... das werde ich ändern.

meistens ist es auch besser mehrere tables zu nehmen statt alles auf krampf in einer zu quetschen.

Hmm, weiß nich wie das vom Speed her ist, aber bisher hab ich noch nicht gequetscht, ich hab eher weitere Tabellen eingeführt (im Vergleich zum vorigen Skript).

gepostet vor 15 Jahre, 6 Monate von Klaus

Original von Phlegma

generell ist die frage, wie kommst du darauf das proceduren/functions in mysql automatisch atomar wären ?

Naja, wenn du sie mit PHP vergleichst...? [Verstehe ich dein "atomar" falsch? Meinst du doch "unteilbar"?

"atomar" bedeutet, dass z.B. bei SQL-Transaktionen alle Queries erfolgreich ausgeführt werden oder gar nicht.

grade in hinblick auf raceconditions und mögliche scriptunterbrechungen wird das sicher probleme geben.

Die Raceconditions hab ich schon im Auge. Was meinst du mit Scriptunterbrechnungen? Soweit ich weiß bricht eine Prozedur im Gegensatz zum PHP Script nicht ab, wenn die Anfrage abgebrochen wird.

Ein PHP-Skript bricht normalerweise gar nicht ab wenn jemand auf "Abbrechen" klickt. Jedenfalls ist dies in der php.ini oder mittels ignore_user_abort() einstellbar.

gepostet vor 15 Jahre, 6 Monate von exe

Original von Phlegma

generell ist die frage, wie kommst du darauf das proceduren/functions in mysql automatisch atomar wären ?

Naja, wenn du sie mit PHP vergleichst...? [Verstehe ich dein "atomar" falsch? Meinst du doch "unteilbar"?

Die Procedure ist ausserhalb einer Transaktion nicht atomar, schliesslich können zwischen zwei Statements in der Procedure auch Statements aus einer anderen Verbindung sichtbar werden. Innerhalb einer Transaktion ist sie nur im Sinne der Transaktion atomar: alle Datenänderungen sind atomar, werden also ganz oder gar nicht geschrieben.  Eine Transaktion schützt dich allerdings nicht automatisch vor Raceconditions, zumindest nicht im default isolation level. Nur mit serialisierbaren Transaktionen kannst du dich über den Transaktionsmechanismus vor Raceconditions schützen, kostet nur etwas Performance und benötigt zusätzliches Handling im PHP-Code bzgl. wegen Raceconditions zu wiederholenden oder abzubrechenden Transaktionen.

gepostet vor 15 Jahre, 6 Monate von Phoscur

Ich mag "LOCK TABLES" nicht (Performance, vor allem bei sehr vielen Einträgen). Ich verwende mein eigenes System mit "used" Einträgen und einem Sleep Algorithmus, der verhindern soll, dass Einträge verwendet werden bevor ein bestimmter Prozess auf ihnen abgeschlossen ist. Das wird auch runter ins PHP geführt, nur dachte ich, dass ich es dort viel eher brauche, weil die Zeitdifferenzen zwischen den SELECT und UPDATE Queries heftiger sind. Im MySQL selbst wollte ich eigentlich darauf verzichten.

Dazu kommt noch, dass die Überschneidungen sehr gering sind. Es ist eine Sache der Wahrscheinlichkeit, ob sich die Queries von zwei Prozeduraufrufen jemals überschneiden. Ich hätte wirklich gern ein paar Zahlen an dieser Stelle.

gepostet vor 15 Jahre, 6 Monate von Drezil

Original von Phlegma

Ich mag "LOCK TABLES" nicht (Performance, vor allem bei sehr vielen Einträgen). Ich verwende mein eigenes System mit "used" Einträgen und einem Sleep Algorithmus, der verhindern soll, dass Einträge verwendet werden bevor ein bestimmter Prozess auf ihnen abgeschlossen ist. Das wird auch runter ins PHP geführt, nur dachte ich, dass ich es dort viel eher brauche, weil die Zeitdifferenzen zwischen den SELECT und UPDATE Queries heftiger sind. Im MySQL selbst wollte ich eigentlich darauf verzichten.

igitt? eigene sachen sind immer gepfuscht und wartungsanfällig..

wieso nicht

SQL:

begin transaction;
procedure_call();
commit;

da müsstest du zwar auf innodb wechseln, aber dann haste wenigstens transaktionen und row-level-locking.

Oder nimm gleich ne ordentliche db wie postgres, oracle oder mssql...

Dazu kommt noch, dass die Überschneidungen sehr gering sind. Es ist eine Sache der Wahrscheinlichkeit, ob sich die Queries von zwei Prozeduraufrufen jemals überschneiden. Ich hätte wirklich gern ein paar Zahlen an dieser Stelle.

bei 1000 eingeloggten usern haste das alle paar sekunden.

oder wenn du einen notorischen klicker hast (oder einen auf-links-doppelklicker). Dann werden 2 php-instanzen parallel gestartet (ignore_user_abort() ist ja an) und du hast innerhalb einer sekunde 2 anfragen... und dann kann es fröhlich durcheinander gehen, wenn das ganze nicht in nullzeit gerechnet ist :D

gepostet vor 15 Jahre, 6 Monate von Phoscur

wieso nicht

SQL:

begin transaction;
procedure_call();
commit;

da müsstest du zwar auf myisam wechseln, aber dann haste wenigstens transaktionen und row-level-locking.

Ja, das überlege ich noch zusätzlich zu machen, muss mir da noch etwas anlesen.. Bisher gefiel es mir wegen der LOCK TABLES nicht.

Oder nimm gleich ne ordentliche db wie postgres, oracle oder mssql...

Auch das überlege ich, aber was kann in diesem Fall Postgres was MySQL nicht kann?

oder wenn du einen notorischen klicker hast (oder einen auf-links-doppelklicker).

Ich brauche mit meinem (pseudo) Ajax sowieso client- und serverseitige Scripte, die mehrfache Aufrufe verhindern uÄ.

Dann werden 2 php-instanzen parallel gestartet (ignore_user_abort() ist ja an)

Nein!

und du hast innerhalb einer sekunde 2 anfragen... und dann kann es fröhlich durcheinander gehen, wenn das ganze nicht in nullzeit gerechnet ist :D

=> Nein, hoffentlich nicht. Ich tue mein Bestes dies zu verhindern.

gepostet vor 15 Jahre, 6 Monate von exe

Original von Phlegma

wieso nicht

SQL:

begin transaction;
procedure_call();
commit;

da müsstest du zwar auf myisam wechseln, aber dann haste wenigstens transaktionen und row-level-locking.

Ja, das überlege ich noch zusätzlich zu machen, muss mir da noch etwas anlesen.. Bisher gefiel es mir wegen der LOCK TABLES nicht.

Transaktionen locken dir ja gerade nicht die komplette Tabellen sondern nur einzelne Zeilen, da du mit Transaktionen InnoDB verwendest.

Oder nimm gleich ne ordentliche db wie postgres, oracle oder mssql...

Auch das überlege ich, aber was kann in diesem Fall Postgres was MySQL nicht kann?

Nichts, grundsätzlich gibt es keine großen Unterschiede zwischen PostgreSQL und MySQL. Postgres hat ein paar interessante Features, die hier aber nicht von Belang sind.

gepostet vor 15 Jahre, 6 Monate von Drezil

Original von exe

Oder nimm gleich ne ordentliche db wie postgres, oracle oder mssql...

Auch das überlege ich, aber was kann in diesem Fall Postgres was MySQL nicht kann?

Nichts, grundsätzlich gibt es keine großen Unterschiede zwischen PostgreSQL und MySQL. Postgres hat ein paar interessante Features, die hier aber nicht von Belang sind.

Nunja.. ich empfinde es als angenehmer nur eine sorte von tabellen zu haben, die dann datenbankseitig im ram vorgehalten werden und erst asynchron auf die platte kommen (so hab ich das zumindest in der anleitung verstanden..).

Bei MySql läuft es dann immer auf einen Mix zwischnen InnoDB und MyISAM heraus - das eine relativ langsam, das andere nicht sicher - aber das ist geschmackssache.

Hauptargument für mysql ist ja immer: "es ist schneller" - Das stimmt, solange man MyISAM-Tabellen nimmt und damit auf komplexere Datenbankanforderungen wie Transaktionen, ACID, row-level-Locking etc. verzichtet.

Ist aber nur eine persönliche Meinung.

Generell würd ich dir ohnehin zu einem Deamon mit Event-Trigger raten, um die aktionen quasi in echtzeit abzuwickeln (und unabhängig von irgendwelchen Seitenaufrufen). Außerdem kannst du dort alle wichtigen (semi-)statischen Daten im Ram vorhalten (Forschungsbaum, Event-Queues, ...) - wäre die performanteste Lösung.

Wenn ich aber richtig in der Annahme gehe, dass dies für dein Ugamela-Ding ist, kann man die Lösung vergessen. Kaum ein Free-Hoster erlaubt einem einen eigenen Daemon aufzusetzen und du bist faktische zu PHP+MySql gezwungen.

gepostet vor 15 Jahre, 6 Monate von Phoscur

Ich höre dabei heraus, dass ich immernoch viel zu wenig über MySQL und Konsorten weiß -.-

Ich werde mir da mal etwas anlesen.

Was du/ihr da schreibst klingt vielversprechend, wahrscheinlich ist dieses InnoDB Zeugs immernoch schneller als mein "used" Eintrag.

Kaum ein Free-Hoster erlaubt einem einen eigenen Daemon aufzusetzen

Ahhhh! Kein Free-Hoster!!!! Nein, wirklich nicht, aber selbst besitze ich bloß einen Webspace, daher ist das die Basis. Ich möchte mein Paket irgendwann mal so einfach installieren können wie ein Board oder ein Joomla, das ist alles.

Zudem ist PHP leider vorerst meine einzige Sprache, die ich mittlerweile (etwas) kann. Wenn ich nun mit einem Daemon in C oder Java anfangen würde... das gäbe nur Murcks glaub ich.

Andererseits finde ich, dass das Problem erst wirklich auftritt wenn man dem Eventhandlerthread die (recht komplexe) Kampfberechnung zuschiebt. Diese habe ich aber auf einen Cronjob (jaja ich weiß dass sich das doof anhört) ausgelagert, der EH führt nur ein Insert in eine Queue aus... das erinnert doch an einen Daemon...

Ein kompletter Daemon in dieser Richtung ist aber Mist, eine Mindestflugzeit und Flugzeiten im 2Minuten Raster wären sehr doof. (Der Cronjob wird alle 2 Minuten ausgeführt)

Aber eigentlich wollte ich hier nicht über Eventhandler und Daemons diskutieren sondern über meinen Code. Es wäre wirklich sehr nett, wenn jemand mal den Code überfliegen würde und vllt ein Kommentar lässt, wenn er etwas Verbesserungswürdiges findet. Zum Besipiel hat mir Jemand auf meinen Blog geschrieben, dass ich noch SELECT ... FOR UPDATE verwenden könnte, das wusste ich noch nicht.

Ich habe gelesen, dass man fast jeden Cursor in ein komplexes Query verwandeln kann. Das gelingt mir nicht, zumal ich auch die Übersicht und Erweiterbarkeit des Cursors behalten will.

gepostet vor 15 Jahre, 6 Monate von exe

Original von Drezil

Original von exe

Oder nimm gleich ne ordentliche db wie postgres, oracle oder mssql...

Auch das überlege ich, aber was kann in diesem Fall Postgres was MySQL nicht kann?

Nichts, grundsätzlich gibt es keine großen Unterschiede zwischen PostgreSQL und MySQL. Postgres hat ein paar interessante Features, die hier aber nicht von Belang sind.

Nunja.. ich empfinde es als angenehmer nur eine sorte von tabellen zu haben, die dann datenbankseitig im ram vorgehalten werden und erst asynchron auf die platte kommen (so hab ich das zumindest in der anleitung verstanden..).

Würden die Daten vollständig asynchron auf die Platte kommen gäbe es keine Transaktionssicherheit da dann selbst nach einem Commit noch die Daten verloren gehen könnten wenn der Server zwischen Commit und asynchronen Schreiben abstürzt. Deswegen schreibt Postgres auch das Write-Ahead-Log um die Daten in jedem Fall auf Platte zu kriegen und erst wenn das geschrieben ist werden die Daten vom writer-Prozess (asynchron) in die Tabelle geschrieben. Macht MySQL mit InnoDB über ihre doublewrite buffer auch ziemlich ähnlich. Von daher hast du mit einer transaktionssicheren Datenbank auf jedenfall einen Diskwrite wenn eine Transaktion commited wird. Vermeiden kannst du das nur wenn du Raidcontroller oder Platten mit batteriegetriebenen Buffern hast welche einen Servercrash überleben - dann kannst du die Daten auch erstmal im Buffer vom Raidcontroller oder der Platte selber lassen.

Bei MySql läuft es dann immer auf einen Mix zwischnen InnoDB und MyISAM heraus - das eine relativ langsam, das andere nicht sicher - aber das ist geschmackssache.

Das kann auch seine Vorteile haben. Wenn du statische Daten wie z.B. eine Spielkarte, Konfiguration oder Statistik hast welche sich nie oder nur sehr selten ändern und - im Falle einer Statistik - sowieso nur aus anderen Tabellen aggregiert werden brauchst du keine transaktionssichere Storage Engine und kannst dich damit auf das schnellere da balastärmere MyISAM beschränken. Ein kleiner Tuningvorteil den du mit Postgres z.B. nicht hast.

IMHO sind die Unterschiede zwischen MySQL und Postgres vorallem in speziellen Features gegeben. Gut, Postgres soll auf manch stärkerer Hardware dank MySQLs verhuntzter Threadsynchronisierung noch besser skalieren, aber im Großen und Ganzen sind die Unterschiede bzgl. Performance und Sicherheit relativ marginal. Interessant an Postgres finde ich eben so Spezialitäten wie Indexe auf Ausdrücke oder das Rulesystem (schonmal eine View gebaut in die man Inserts machen kann? Mit Postgres gehen solche Spielereien). Und die Ausgaben des Query Analyzer sind den Bordmitteln von MySQL natürlich haushoch überlegen ..

gepostet vor 15 Jahre, 6 Monate von Kallisti

Original von Phlegma

Ahhhh! Kein Free-Hoster!!!! Nein, wirklich nicht, aber selbst besitze ich bloß einen Webspace, daher ist das die Basis. Ich möchte mein Paket irgendwann mal so einfach installieren können wie ein Board oder ein Joomla, das ist alles.

Ein komplexes, umfangreiches und gutes Browsergame wird man meiner Meinung nach nie einfach so als Paket installieren koennen, da es immer individuelle Anpassungen braucht. Allein schon fuer die ordentliche Integration von Fremdsoftware und vor allem um ein System zu schaffen, das gut skaliert. Wobei ja die generelle Meinung zu sein scheint, auf Skalierbarkeit einfach mal komplett zu verzichten und einfach zig unabhaengige Welten nebeneinander zu knallen, anstatt mal ein wirkliches MMO zu erschaffen. ;) Bei Clientgames ist es logisch, weil sowohl Rechenleistung, als auch Netzwerkpakete n^2 wachsen und irgendwann auch 10gb fuer einen Server nicht mehr ausreichen (das passiert sogar relativ schnell), obwohl man Bewegungsvektoren, Buffering, viele lokale Checks usw benutzt (siehe WoW, ab 200-400 Leuten in naher Umgebung, gehen die Server in die Knie).

Ich schweife ab. ;) Imho verdirbt man sich selbst den Spass, wenn man sich die Limitierung "Webspace" aufhalst.

Zudem ist PHP leider vorerst meine einzige Sprache, die ich mittlerweile (etwas) kann. Wenn ich nun mit einem Daemon in C oder Java anfangen würde... das gäbe nur Murcks glaub ich.

Du kannst den auch in PHP schreiben. ;)

Andererseits finde ich, dass das Problem erst wirklich auftritt wenn man dem Eventhandlerthread die (recht komplexe) Kampfberechnung zuschiebt. Diese habe ich aber auf einen Cronjob (jaja ich weiß dass sich das doof anhört) ausgelagert, der EH führt nur ein Insert in eine Queue aus... das erinnert doch an einen Daemon...

Ein kompletter Daemon in dieser Richtung ist aber Mist, eine Mindestflugzeit und Flugzeiten im 2Minuten Raster wären sehr doof. (Der Cronjob wird alle 2 Minuten ausgeführt)

Wieso ist ein Daemon Mist? Du kannst alles in Echtzeit machen, hast keine negativen Performance Einfluesse,  keine komischen 2 Minuten Limits, keine Checks bei jedem Aufruf... -> nur Vorteile.

Aber eigentlich wollte ich hier nicht über Eventhandler und Daemons diskutieren sondern über meinen Code. Es wäre wirklich sehr nett, wenn jemand mal den Code überfliegen würde und vllt ein Kommentar lässt, wenn er etwas Verbesserungswürdiges findet. Zum Besipiel hat mir Jemand auf meinen Blog geschrieben, dass ich noch SELECT ... FOR UPDATE verwenden könnte, das wusste ich noch nicht.

Nun, wie Du bisher siehst, empfiehlt Dir so ziemlich jeder deine Business Logik nicht in der DB abzuwickeln, da Du dich damit nur von einem DBMS abhaengig machst und viel zu unflexibel bist. Denke mal, die wenigsten haben gross Lust sich deinen Source im Detail anzusehen, dazu ist der SQL Kram viel zu gruselig und vor allem fehlen Dir ordentliche Kommentare (was wohl das mit Abstand groesste Manko ist).

gepostet vor 15 Jahre, 6 Monate von Fobby

Ich möchte mal eine Zwischenfrage in dem Raum werfen: Mit Daemons habe ich mich bisher kaum bis gar nicht beschäftigt. Nach etwas Gegoogel bin ich nun zumindest etwas schlauer. Mir fehlt aber immernoch die Vorstellung, wie sowas dann tatsächlich realisiert aussieht. Kann mir da jemand ein schönes Beispiel nennen oder online-Literatur empfehlen?

Danke und 'tschuldigung für die Threadunterbrechung

gepostet vor 15 Jahre, 6 Monate von Kallisti

http://www.galaxy-news.de/groups/2_entwickler/forums/5053_scheduling_eventqueue_dispatching.html

Wobei das pastebin ausgelaufen ist, wenn Interesse besteht (war offensichtlich bislang nicht der Fall^^), kann ich es gern nochmal posten...

Das ist quasi die halbe Miete, also das Grundgeruest, der komplizierteren Dinge. "Daemonizen" selbst heisst ja nur, dass sich der Prozess von der Shell loest (z.B. durch forking) und im Hintergrund 24/7 laeuft. Ich hab z.B. vor ein HTTP Interface zur Verwaltung zu integrieren, das sind in Perl immer nur paar Zeilen Code.

Eine EventQueue arbeitet dann alles ab, was zu gewissen Zeiten passieren soll, ein Jobsystem arbeitet alle wiederkehrenden Events ab (z.B. Ressourcenvergabe oder Statistikberechnung). Ist eigentlich alles recht straight-forward. Man hat eben nur einen losgeloesten, dauerhaft aktiven Prozess, der alles erledigt, was nicht vom Spieler angestossen wird.

Falls Du weitere Fragen hast, wuerd ich nen neuen Thread oder meinen alten, oben verlinkten, vorschlagen. ;)

gepostet vor 15 Jahre, 6 Monate von Phoscur

Ich schweife ab. ;) Imho verdirbt man sich selbst den Spass, wenn man sich die Limitierung "Webspace" aufhalst.

Das wird sich zeigen. Ich denke sowieso nicht, dass es für ein Massive Multiplayer Game reichen wird, aber 1k Leutz wirds schon packen hoff ich.

Du kannst den Daemon auch in PHP schreiben. ;)

Ja toll. Aber mir scheint PHP dafür denkbar ungeeignet. Interessanter fände ich einen MySQL Daemon. Dafür gibt es wie ich grade mit Google finde sogar Event Shedule.

Ein kompletter Daemon in dieser Richtung ist aber Mist, eine Mindestflugzeit und Flugzeiten im 2Minuten Raster wären sehr doof. (Der Cronjob wird alle 2 Minuten ausgeführt)

Wieso ist ein Daemon Mist? Du kannst alles in Echtzeit machen, hast keine negativen Performance Einfluesse,  keine komischen 2 Minuten Limits, keine Checks bei jedem Aufruf... -> nur Vorteile.

Wie bereits beschrieben habe ich nur den 2Minuten Cron... damit wäre der Daemon Mist, ansonsten hast du natürlich recht.

Nun, wie Du bisher siehst, empfiehlt Dir so ziemlich jeder deine Business Logik nicht in der DB abzuwickeln, da Du dich damit nur von einem DBMS abhaengig machst und viel zu unflexibel bist.

ich glaube einfach nicht, dass ich verschiedene Datenbanksysteme brauche. Wenn einmal doch, dann muss man halt den Code überarbeiten, aber SQL Code gleicht sich mehr oder weniger.

Denke mal, die wenigsten haben gross Lust sich deinen Source im Detail anzusehen, dazu ist der SQL Kram viel zu gruselig und vor allem fehlen Dir ordentliche Kommentare (was wohl das mit Abstand groesste Manko ist).

Das kann ich ändern, wenn nötig. Ich will den Code ja sowieso OS machen, dann wären Kommentare vllt angebracht. Ich setz mich wahrscheinlich noch heute dran!

gepostet vor 15 Jahre, 6 Monate von exe

Original von Phlegma

Nun, wie Du bisher siehst, empfiehlt Dir so ziemlich jeder deine Business Logik nicht in der DB abzuwickeln, da Du dich damit nur von einem DBMS abhaengig machst und viel zu unflexibel bist.

ich glaube einfach nicht, dass ich verschiedene Datenbanksysteme brauche. Wenn einmal doch, dann muss man halt den Code überarbeiten, aber SQL Code gleicht sich mehr oder weniger.

Flexibilität bedeutet nicht nur das Wechseln der Datenbank sondern auch die Flexibilität der Programmiersprache. Überleg dir mal wie du vernünftig aus einer Stored Procedure raus Loggen willst. Oder Debuggen. Oder Wartungsmails verschicken. Eine andere Sache ist die Performance: je nach Spiel wird gerne mal die Datenbank der Flaschenhals. Wenn du deine Business Logik in der Datenbank hast verschärfst du das Problem zum einen, zum anderen wird es wesentlich schwieriger die Last zu verteilen. Einen Daemon kann man im zweifelsfall einfach auf eine andere Hardware auslagern. Bei deiner Lösung darfst du erstmal über Clustering oder Sharding deiner Datenbank nachdenken um Last zu verteilen - wobei Sharding schon grundsätzlich nicht zusammen mit Stored Procedures funktioniert - zumindest in MySQL nicht.

Prinzipiel ist die Idee die Spielberechnungen direkt in die Datenbank zu verlagern schon recht Charmant, ich würde sie aber aus den verschiedenen Gründen vermeiden.

gepostet vor 15 Jahre, 6 Monate von Phoscur

Nun, was hälst du davon wenn ich, wenn ich schon in diesem Stadium bin, dass der SQL Core quasi fertig ist, den Kram noch fertig mache und es einfach herausfinde, wie performant das ganze ist? Vllt erleben wir ja ein Überraschung^^

Ich denke, dass der PHP Teil auch noch genug zu tun bekommt und die Datenbank ganz froh sein wird, wenn sie mal ein bischen mehr tun darf als einzelne Queries zu verarbeiten. Die Last kann ich dann mithilfe der Sessions immernoch auf PHP rüberschieben.

Ich bin mir jedenfalls sicher, dass es weitaus schneller ist, Daten direkt in MySQL zu verarbeiten, als sie zum Apachen zu schicken und dort zu verarbeiten um sie dann wieder zurückzuschicken.

gepostet vor 15 Jahre, 6 Monate von TheUndeadable

> Ja toll. Aber mir scheint PHP dafür denkbar ungeeignet. Interessanter fände ich einen MySQL Daemon. Dafür gibt es wie ich grade mit Google finde sogar Event Shedule.

Mein erstes Browsergame (existiert nicht mehr) hatte einen PHP-Daemon, das ich mit 'php.exe -f daemon.php' oder so ähnlich gestartet hatte.

Dieser lief 2 Monate bis zum nächsten Patchday ohne Speicherlöcher oder anderen Scherzen durch. PHP ist nicht so schlecht, wie immer behauptet wird. Meist sind es die PHP-Programmierer.

Einen Daemon in MySQL hereinzubringen sehe ich als denkbar schlechte Idee. Insbesondere daher, dass du dann 100% auf MySQL geimpft bist und größte Schwierigkeiten haben wirst die Datenbank eines Tages zu wechseln. Die Firma hinter MySQL ist gewinnorientiert und es ist nicht garantiert, dass MySQL ewig unter der GPL bleiben wird. Eines Tages kann sie unter die AGPL fallen und du bist dann gezwungen entweder MySQL zu verlassen, dein Skript unter der AGPL zu veröffentlich oder dir eine kommerzielle Lizenz zu holen.

gepostet vor 15 Jahre, 6 Monate von Phoscur

PHP ist nicht so schlecht, wie immer behauptet wird. Meist sind es die PHP-Programmierer.

Das höre ich aus deinem Mund? Und was ist mit deiner Signatur? Widersprichst du dir oder bist du nur ironisch? Für letzteres kommt das aber nicht wirklich rüber.

Einen Daemon in MySQL hereinzubringen sehe ich als denkbar schlechte Idee. Insbesondere daher, dass du dann 100% auf MySQL geimpft bist und größte Schwierigkeiten haben wirst die Datenbank eines Tages zu wechseln. Die Firma hinter MySQL ist gewinnorientiert und es ist nicht garantiert, dass MySQL ewig unter der GPL bleiben wird. Eines Tages kann sie unter die AGPL fallen und du bist dann gezwungen entweder MySQL zu verlassen, dein Skript unter der AGPL zu veröffentlich oder dir eine kommerzielle Lizenz zu holen.

Ich meine immernoch, dass alle SQL Sprachen sehr ähnlich sind und das Umschreiben nicht sehr schwer fallen würde. Zudem bin ich noch ein recht junger Entwickler, ich denke nicht, dass dies mein einziges bzw wichtigstes Projekt bleiben wird, auch wenn die Idee schön ist, mit OS macht man nunmal kein Geld.

gepostet vor 15 Jahre, 6 Monate von TheUndeadable

> Widersprichst du dir oder bist du nur ironisch

Sehe meine Signatur als Ironie an. PHP halte ich in der Tat _als Laufzeitumgebung_ nicht zu schlecht. Die Sprache selbst ist geschmackssache und sollte nicht Thema des Threads sein. Aber: Wenn du ein funktionierendes PHP-Skript hast, dann würde es auch als Daemon funktionieren.

gepostet vor 15 Jahre, 6 Monate von Sarge

Original von Phlegma

Ich denke, dass der PHP Teil auch noch genug zu tun bekommt und die Datenbank ganz froh sein wird, wenn sie mal ein bischen mehr tun darf als einzelne Queries zu verarbeiten. Die Last kann ich dann mithilfe der Sessions immernoch auf PHP rüberschieben.

Ich bin mir jedenfalls sicher, dass es weitaus schneller ist, Daten direkt in MySQL zu verarbeiten, als sie zum Apachen zu schicken und dort zu verarbeiten um sie dann wieder zurückzuschicken.

Ja es mag prinzipiell erst einmal schneller sein. Aber das spielt keine Rolle. Das wichtige ist:

Die DB bei einem engpass nach oben zu skalieren ist verdammt aufwendig und nur begrenzt möglich. Dafür ist es aber überhaupt kein Problem das Frontend beliebig linear zu skalieren (wenn du dir nicht selbst begrenzungen eingebaut hast wie gemeinsamer shared memory etc aber auch das geht einfacher im vergleich zur db).  Reicht ein Apache nicht? Stell 2 hin.. oder 20. Daher wirst du jeden Betreiber eines etwas größeren BGs fragen können und er wird dir sagen schaufel soviel wie möglich weg von der db.

Natürlich musst du nicht drauf hören... aber beschwer dich dann bitte nicht wenn die Zeit kommt in der deine db zum flaschenhals wird.

gepostet vor 15 Jahre, 6 Monate von Klaus

Genau. Bleibe lieber eine Abstraktionsschicht von der Datenbank entfernt. Dann kannst du in dem von Undead beschriebenen 'Worst-Case' auch noch die DB-Software wechseln. Außerdem ist es ziemlich umständlich Verrenkunden in SQL zu formulieren.

gepostet vor 15 Jahre, 6 Monate von Phoscur

Also, ich hab mich dann mal schlau gemacht und darüber nachgedacht.

Wir reden immer von der Datenbank, MySQL hat vor allem die Aufgabe bestimmte Daten von der Platte zu holen und sie in meinem Fall an den Apachen zu schicken. Dabei ist die Limitierung vor allem die Festplatte mit bestimmten Zugriffszeiten sowieso Lese-/Schreibgeschwindigkeit. Dort finden wir den Flaschenhals, von dem ihr sprecht. Die Limitierung ist die Fesplatte, nicht der Prozessor, auch wenn dieser auch zu tun hat.

Ich schließe daraus, dass meine MySQL Programmierung nicht zu einem Flaschenhals führen wird, weil dadurch keine Mehrlast für die Festplatte entsteht. Ich muss lediglich in MySQL schreiben um den Weg zwischen MySQL Server und Apache einzusparen, was tatsächlich etwas umständlich ist, da sich MySQL doch etwas anders schreibt als PHP oder wie ich vermute andere Sprachen.

Ich würde versuchen die Datenbank möglichst sauber zu halten, damit Queries nicht zwischen alten Daten rumstochern müssen.

Ich spare übrigens Queries indem ich innerhalb des MySQL bleibe!

Ich habe dem Source einige Optimierungen und Kommentare hinzugefügt, ein Update kommt noch heute.

gepostet vor 15 Jahre, 6 Monate von Klaus

Wenn du 1000 Exabyte Daten hast, die MySQL sequentiell lesen musst, dann ist die Festplatte der Knackpunkt. Aber in allen anderen Anwendungsfälle liegen die wichtigsten Daten noch im RAM oder sogar fertig im Query-Cache. Dann muss MySQL nur noch den Prozessor belasten um die richtigen Daten rauszufischen.  Große komplexe Queries können hier shcwerer ins Gewicht fallen als ein paar kleine.

gepostet vor 15 Jahre, 6 Monate von HSINC

mal was generelles zu queryanzahlen. man liest zwar immer wieder on diversen foren das man die anzahl der querys minimieren muss, aber das ist völliger quatsch. im grunde kann man sagen, mach so viele querys wie du musst, es hat absolut keinen merkbaren einfluss. ok noch ein paar einschränkungen, klar kommt es auf die art der querys an, klar macht es einen unterschied ob man nun 1 oder 200000 querys macht. aber wenn man querys hinreichend optimiert (als zb 1 multiples insert statt 200k) ist das völlig ok. man sollte es einfach mit dem optimieren nur nicht übertreiben, weil das fällt einem dann irgendwann defintiv auf die füsse.

zur auslastung des db servers, also meiner lastet ram, cpu und platte ganz gut aus und ich würde eher sagen das mehr ram grad das meiste in sachen leistungssteigerung bringen würde. und cpu beansprucht der auch nicht grad wenig und der macht keine businiesslogic oder so.

aber im grunde ist es dir überlassen ob du nun teile der scripte in die db packst oder nicht und ehrlich gesagt halte ich es für eher unwahrscheinlich das du irgendwann in absehbarer zeit damit probleme bekommen wirst, aber wir haben dir hier trotzdem ein paar gründe genannt die dagegen sprechen. ob du sie nun behertzigst oder deine eigenen erfahrungen machen willst, nunja deine sache ^^ ich würde dir aber letzteres vorschlagen ^^

gepostet vor 15 Jahre, 6 Monate von Phoscur

Oh, natürlich beherzige ich was ihr mir sagt! Ich bin nur immer etwas stur, wenn ich mich einmal auf etwas festgelegt habe.

Zudem habe ich einige Zeit damit verbracht ein MySQL Niveau zu erreichen mit dem man das überhaupt fertig bringt einen Teil der Buisness Logik in MySQL zu schreiben. Ich habe noch von niemandem von euch gehört, dass er das schon versucht hat und dementsprechende Resultate vorfand, die ihr meint kritisieren zu müssen ohne Überhaupt Beweise zu haben.

Kommen wir überein, dass ich das erstmal testen sollte? Danach kann man immernoch wieder zurück auf das alte Schema alles dem Apachen zu überlassen.

gepostet vor 15 Jahre, 6 Monate von knalli

Original von HSINC

mal was generelles zu queryanzahlen. man liest zwar immer wieder on diversen foren das man die anzahl der querys minimieren muss, aber das ist völliger quatsch. im grunde kann man sagen, mach so viele querys wie du musst, es hat absolut keinen merkbaren einfluss. ok noch ein paar einschränkungen, klar kommt es auf die art der querys an, klar macht es einen unterschied ob man nun 1 oder 200000 querys macht. aber wenn man querys hinreichend optimiert (als zb 1 multiples insert statt 200k) ist das völlig ok. man sollte es einfach mit dem optimieren nur nicht übertreiben, weil das fällt einem dann irgendwann defintiv auf die füsse.

zur auslastung des db servers, also meiner lastet ram, cpu und platte ganz gut aus und ich würde eher sagen das mehr ram grad das meiste in sachen leistungssteigerung bringen würde. und cpu beansprucht der auch nicht grad wenig und der macht keine businiesslogic oder so.

aber im grunde ist es dir überlassen ob du nun teile der scripte in die db packst oder nicht und ehrlich gesagt halte ich es für eher unwahrscheinlich das du irgendwann in absehbarer zeit damit probleme bekommen wirst, aber wir haben dir hier trotzdem ein paar gründe genannt die dagegen sprechen. ob du sie nun behertzigst oder deine eigenen erfahrungen machen willst, nunja deine sache ^^ ich würde dir aber letzteres vorschlagen ^^

Ähm, wie bitte? Die pauschale Aussage, das eine minimale Anzahl von Queries optimal wäre, ist in der Tat ein Trugschluss. Es gibt sogar Fälle, wo es sinnvoll sein könnte, ein Query in zwei einzelne Aufzuteilen. Aber vor allem kommt es darauf an, WAS man in den Queries macht. Aber genausogut ist die pauschale Antwort des Gegenteils - also deine - auch falsch. Mit soviel Verallgemeinerung verschließt man sich einem Teil der Wahrheit.

Und: Ja, definitiv Datenbank entlasten. Was die Datenbank (ergo der Service) nicht machen oder kennen muss, das sollte er auch nicht. Wobei ich selber der Meinung bin, dass Constraints (und insofern Trigger, die für Constraint-Aufgaben gedacht sind) durchaus eine Berechtigung haben. Das ist nur leider meist nicht mehr mit der Abstraktionsschicht vereinbar :(

gepostet vor 15 Jahre, 6 Monate von Sarge

Original von Klaus

Wenn du 1000 Exabyte Daten hast, die MySQL sequentiell lesen musst, dann ist die Festplatte der Knackpunkt. Aber in allen anderen Anwendungsfälle liegen die wichtigsten Daten noch im RAM oder sogar fertig im Query-Cache. Dann muss MySQL nur noch den Prozessor belasten um die richtigen Daten rauszufischen.  Große komplexe Queries können hier shcwerer ins Gewicht fallen als ein paar kleine.

Lesen sollte eigtl nie zu hdd Problemen führen da hast du recht. Aber bei uns zumindestens sind die platten-geschwindigkeit eindeutiges bottleneck der DB.  Da es in einem BG sehr viele schreiboperationen gibt und die auf die platte müssen.

Allerdings kann mysql mit etwas komplexeren queries auch mal ganz schnell alle cpu-ressourcen futtern.

Aber generell geb ich Hsinc recht, vermutlich wirst du nicht annähernd in nächster Zeit an diese Probleme überhaupt stoßen. Aber andererseits, warum nicht gleich richtig machen ? Insbesondere wenn du es dir (imho) sogar einfacher machst

gepostet vor 15 Jahre, 6 Monate von Tron

Ein paar Anmerkungen. Die Datenbank brauchst du in deinem Spiel, um Zustände zu sichern. Wenn du Logik in deinem System verwendest, wo diese Zustände in Relation zu anderen Zuständen abgelegt werden, dann kann es schon Sinn machen, das in der Datenbank unterzubringen. Ebenso, wenn das Speichern oder Abrufen von Daten direkt Ereignisse im System auslösen soll, besonders wenn diese Ereignisse im Backend bleiben, sich also auf Modifikaton gespeicherter Zustände auswirken.

Für solche Logik wäre allerdings aus diversen Gründen eine Postgresql DB der mysql vorzuziehen:

  • Postgresql elaubt dir nicht nur, in C deine DB um Funktionen zu erweitern, sondern bietet noch etliche prozedurale Sprachen an um Automatismen zu implementieren, die von Triggern angestoßen werden können. Mysql ist im Vergleich hierzu deutlich begrenzter. siehe http://www.postgresql.org/docs/8.3/static/external-pl.html
  • Postgresql ist die erwachsenere Datenbank was Transaktionssichere atomisierte Zugriffe angeht. Atomisiert heißt in diesem Fall nicht faktisch Nullzeit, sondern ein Ganz oder Garnicht - entweder findet eine Transaktion komplett statt, oder sie wird abgebrochen und ein Rollback findet statt. Mysqls myIsam ist sehr schnell bei Systemen in denen die Lesezugriffe die Schreibzugriffe um ein vielfaches übersteigen, wie es z.B. bei Websites häufig der Fall ist, eine arbeit die Mysql hervorragend und sehr zuverlässig ausübt, aber weniger geeignet um konsistenz in updateintensiven Systemen zu gewährleisten.
  • Dann ist da noch die Lizenzfrage, sobald du intensiver an der DB rumentwickelst kommst du bei Mysql an die Frage, was du ob der GPL nun wiedr an code offenlegen müsstest, wenn ich mal voraussetze, daß du dich aus dem juristischen Geklüngel nicht mit ner kommerziellen Lizenz rauskaufen willst. Die BSD Lizenz von Postgresql läßt solche Kopfschmerzen garnicht erst aufkommen.

Zur Geschichte mit "ich kann nur PHP richtig", PHP kann keiner richtig, da würd ich keine Angst vorm Wechsel haben wenn Bedarf besteht, viel wichtiger ist bei größeren Projekten (und jedes Spiel ist das letztendlich) seine Fähigkeiten im modelling zu verbessern, wenn du da den Bogen rauskriegst, lernst du weitere Programmiersprachen "en passant". Man Kann sicher komplexe Applikationen entwickeln in PHP, aber ursprünglich gedacht war PHP dafür nie, und das merkt man PHP auch an. Persönliche Einschätzung hier ist, daß man langfristig weniger Zeit verliert, wenn man sich mal bei anderen Sprachen umsieht. Java ist da zum Beispiel ein ganz guter Kompromiss zwischen Performance und Produktivität (wenn man nicht zu religiös dabei wird ;) ), Python ist leicht erlernbar und bei nicht allzu performancekritischen Jobs wunderbar produktiv, und solltest du einen Draht zu Lisp entwickeln können, hast du einfach nur gewonnen :)

Gruß,

Stefan

gepostet vor 15 Jahre, 6 Monate von Phoscur

Vielen Dank für den Tipp, aber ich denke du wirst verstehen, dass ich erstmal bei den Sprachen bleiben möchte, mit denen ich es jetzt bereits im wiederholten Anlauf versuche. Ich möchte das fertig* bringen, danach fange ich mit einer anderen Sprache an.

* Soweit das möglich ist, ein Teil wird wohl immer an mir hängen bleiben^^

Also ich bin jetzt bei Transactions, habe aber so meine Probleme.

Wie sieht das überhaupt codemäßig aus?

1. Autocommit aus.

2. SELECTs (LOCK FOR UPDATE)

PHP Verarbeitung

3. UPDATEs

4. COMMIT

??

Vor allem aber kann ich mir nicht vorstellen was passiert, wenn InnoDB mit MyISAM Tabellen mische. Rollback funktioniert auf MyISAM nicht, was mache ich aber wenn die Transaction trotzdem zurückgerollt wird, weil sie sich vllt mit einer anderen verklemmt hat? Muss ich dann nur die Queries auf den InnoDB Tables erneut ausführen? Gibt es da eine einfache Technik oder muss ich um jedes MyISAM Query ein IF basteln?!

gepostet vor 15 Jahre, 6 Monate von Phoscur

Hm, wenn ihr jetzt nicht antwortet, soll ich daraus schließen,

- dass ich es mir irgendwie anlesen soll?

- dass ihr auch nicht weiter wisst?

- dass ihr die Lust an diesem Thread verloren habt?

- dass ich gerade dumm da stehe?

gepostet vor 15 Jahre, 6 Monate von TheUndeadable

a) + c)

gepostet vor 15 Jahre, 6 Monate von Phoscur

Okay, bin zwar hinischtlich letzter Frage noch nicht groß schlauer geworden, habe mich aber insgesamt gebildet :D

Es geht mir nun weiter um Optimierung für Geschwindigkeit und gegen Race Conditions. Ich werde nun für einige Tabellen InnoDB einsetzen um einzelne Einträge sperren zu können. Ich bin mir nur noch nicht sicher welche.

Tabellenstruktur:

1. A) Sonnensystem (InnoDB) mit B) Gebäuden (MyIsam) C) evtl mit Modulen (MyIsam)

2. A) Flotten (InnoDB) B) mit Schiffen (MyIsam) C) evtl mit Modulen (MyIsam)

Warum will ich MyIsam für Typ B?:

Ich führe öfter SUM() [Schadensumme, Neuberechnung der Ressproddi pro Stunde] aus, zudem sind die Tabellen sehr viel größer (ca. 10x-20x), angesprochen wird durch eine eindeutige ID zu Typ A [Indizes!]. Ich benutze hier aus Performancegründen kein InnoDB, ich denke außerdem, dass die Race Conditions vor allem auf Typ A zum tragen kommen.

Mir erscheint das nun sehr klar und logisch, aber vielleicht habe ich etwas übersehn?

Zudem habe ich immernoch keine Ahnung was ich tun muss wenn es zu einem Rollback kommt.

Über Hilfe oder Kritik würde ich mich freuen!

gepostet vor 15 Jahre, 6 Monate von Drezil

kann man innerhalb einer transaktion überhaupt innodb und myisam nutzen? verstösst das nicht irgendwie gegen ACID?

ich kenn mich da nicht aus .. wollts aber nur mal anmerken :D

gepostet vor 15 Jahre, 6 Monate von Phoscur

http://bugs.mysql.com/bug.php?id=333

Soweit ich das jetzt erfahren konnte kann man beide per Tranaktion ansprechen, auch mixed Queries sind möglich. Dafür lassen sie sich auf den MyIsam Tabellen nicht zurückrollen..

Soll ich einfach überall InnoDB nehmen?

gepostet vor 15 Jahre, 6 Monate von DrakeL

Original von Phlegma

http://bugs.mysql.com/bug.php?id=333

Soweit ich das jetzt erfahren konnte kann man beide per Tranaktion ansprechen, auch mixed Queries sind möglich. Dafür lassen sie sich auf den MyIsam Tabellen nicht zurückrollen..

Die Frage wäre eher, benötigst du einen Rollback auf die Stammtabellen? Deine Typ B Tabellen werden noch bei keinerlei Vorgängen verändert oder? Wenn keine Änderungen gemacht werden (mit Ausnahme der direkten Pflege der Stammtabellen wie neue Schiffe hinzufügen etc.), wirst darauf auch kein Rollback benötigen. Wenn du während den Berechnungen auch Änderungen an deinen Typ B Tabellen vornehmen musst, dann sind diese keine Stammtabellen und sollten eher auf InnoDB umgestellt werden.

PS: Strenge Einteilung in Stammtabellen und "Rest" wäre hier das ausschlaggebende Kriterium.

gepostet vor 15 Jahre, 6 Monate von Phoscur

Ah, gut!

Das bedeutet für mich, dass ich Wege finde auf Schreibrechte in den B Tabellen zu verzichten (zumindest für die größeren, wichtigeren Vorgänge) oder auch dort auf InnoDB wechsle.

Und wenn ich nun ein oder zwei Schreibqueries habe? Also gravierende Unterzahl zu den Lesevorgängen? Macht es Sinn ein eigenes Rollback Query bereitzustellen und es für den Rollback-Fall anzubinden? Ist das überhaupt möglich.

Ich habe nur eine ganze Klasse für MyIsam Rollbacks gefunden, die eigentlich auch nur Queries verwendet, die das Gegenteil der vorigen Abfolge darstellen.

gepostet vor 15 Jahre, 6 Monate von DrakeL

Original von Phlegma

Das bedeutet für mich, dass ich Wege finde auf Schreibrechte in den B Tabellen zu verzichten (zumindest für die größeren, wichtigeren Vorgänge) oder auch dort auf InnoDB wechsle.

Ich frage mich eher, was du in Stammtabellen ändern musst bei berechnende Vorgängen.

Und wenn ich nun ein oder zwei Schreibqueries habe? Also gravierende Unterzahl zu den Lesevorgängen? Macht es Sinn ein eigenes Rollback Query bereitzustellen und es für den Rollback-Fall anzubinden? Ist das überhaupt möglich.

Ich habe nur eine ganze Klasse für MyIsam Rollbacks gefunden, die eigentlich auch nur Queries verwendet, die das Gegenteil der vorigen Abfolge darstellen.

Was spricht dagegen auf InnoDB zu wechseln? Hast du Performanceprobleme mit der Datenbank?

Wenn ja würde ich vielleicht anfangen die Tipps hier zu beherzigen und der Datenbank alles an Last abnehmen was geht. Wenn nicht würde ich mir um die Performance noch keine Sorge machen und überall wo ein Rollback benötigt wird auf InnoDB wechseln.

Auf keinen Fall versuchen zu optimieren oder sogar Umwege gehen um Datenbankverhalten zu simulieren ohne ersichtlichen Grund. Bevor du Datenbanklogik zur Applikation ziehst, solltest du eher Buissness Logik aus der Datenbank entfernen.

Die Datenbank sollte ja eigentlich als relativ unabhängige Möglichkeit zur Speicherung von Daten verwendet werden und nicht als fest verdrahteter Bestandteil einer Applikation.

gepostet vor 15 Jahre, 6 Monate von meikel

Original von DrakeL

Die Datenbank sollte ja eigentlich als relativ unabhängige Möglichkeit zur Speicherung von Daten verwendet werden und nicht als fest verdrahteter Bestandteil einer Applikation.

Damit degradierst Du ein DBMS zum simplen Datenspeicher...

gepostet vor 15 Jahre, 6 Monate von Kallisti

Original von meikel

Original von DrakeL

Die Datenbank sollte ja eigentlich als relativ unabhängige Möglichkeit zur Speicherung von Daten verwendet werden und nicht als fest verdrahteter Bestandteil einer Applikation.

Damit degradierst Du ein DBMS zum simplen Datenspeicher...

Eher zum Datenspeicher, der es einem erlaubt Daten strukturiert, persistent abzulegen und performant und effizient wieder abzurufen. Und solang die API sich dabei auf einen definierten Standard beschraenkt, ist man in der Wahl des unterliegenden Systems flexibel.

gepostet vor 15 Jahre, 6 Monate von TheUndeadable

> Damit degradierst Du ein DBMS zum simplen Datenspeicher...

Was ich uneingeschränkt befürworte!

gepostet vor 15 Jahre, 6 Monate von meikel

Original von Kallisti

Original von meikel

Original von DrakeL

Die Datenbank sollte ja eigentlich als relativ unabhängige Möglichkeit zur Speicherung von Daten verwendet werden und nicht als fest verdrahteter Bestandteil einer Applikation.

Damit degradierst Du ein DBMS zum simplen Datenspeicher...

Eher zum Datenspeicher, der es einem erlaubt Daten strukturiert, persistent abzulegen und performant und effizient wieder abzurufen.

Es ist nicht effizient, einen Datensatz per SELECT anzufordern, mit PHP zu berechnen und mit UPDATE zu speichern.

Und solang die API sich dabei auf einen definierten Standard beschraenkt, ist man in der Wahl des unterliegenden Systems flexibel.

Wohl wahr: man beschränkt sich auf Simpel-SQL, damit man flexibel zwischen Oracle oder SQLite wählen kann.

gepostet vor 15 Jahre, 6 Monate von Kallisti

Naja mit dergleichen Pragmatismus kommst Du aber nicht wirklich weit. "Performant" und "effizient" sind natuerlich immer relativ und es gibt sicherlich eine Menge Overhead bei den momentanen Open Source DBMS. Dennoch ist es nun nicht so, als haetten Oracle oder SQLite (aehm, ja..) das Rad neu erfunden und seien der Weisheit letzter Schluss.

Ich weiss nicht, was nun die Intention deiner Postings ist, klingt grad aber eher nach einem "MySQL UND Postgres bashing". Das ist dann wohl die eher seltene Spezies derer, die beruflich ewig mit Oracle gearbeitet haben und nicht glauben, dass es da auch was gutes im Open Source Bereich gibt (wobei ich nicht sagen moechte, dass Oracle eine schlechte Wahl waere, ganz im Gegenteil).

Dass Datenbank IO allzu meist (um nicht zu sagen immer) das Bottleneck einer Webapplikation darstellt, ist auch nichts neues, haengt aber zumeist auch mit dem Software Design oder schlicht mit Hardware Limitierungen (RAM, CPU, Diskspeed) zusammen und weniger mit dem verwendeten DBMS.

Najo, es sei auch Dir gestattet, Dich den gaengigen Open Source DBMS zu verweigern. ;) Aber um ACID kostenguenstig und ohne grossen Aufwand zu implementieren gibt es nun einmal keine andere Wahl.

gepostet vor 15 Jahre, 6 Monate von meikel

Original von Kallisti

Naja mit dergleichen Pragmatismus kommst Du aber nicht wirklich weit. "Performant" und "effizient" sind natuerlich immer relativ und es gibt sicherlich eine Menge Overhead bei den momentanen Open Source DBMS.

[...]

Da haste mich offenbar etwas mißverstanden. Man nutzt die zur Verfügung stehenden Möglichkeiten aus und beschränkt sich nicht auf den kleinsten gemeinsamen Nenner.

1. Ein MySQL Server kann nicht nur Daten speichern und ausliefern - das Teil kann auch rechnen. Und es ist effizienter, MySQL rechnen zu lassen als die Daten mit SELECT rauszupolken, mit PHP zu bewuseln und ein UPDATE auszuführen. Ein MySQL Server versteht auch Multiline-Queries, wenn man den richtigen MySQL Client benutzt.

2. PostgreSQL (mein Favorit aus dem Preiswert-Segment) inclusive PL/PGSQL ist noch eine Ecke luxeriöser.

Browsergames plant man doch in der Regel so, daß sie mindestens auf einem entsprechend ausgestatteten vServer auf Linuxbasis zum Einsatz kommen sollen.

gepostet vor 15 Jahre, 6 Monate von Kallisti

Ohhkay, das kam wirklich nicht so rueber. ;)

Ich wuerd eher sagen zumindest root-, denn vserver, aber das tut dem Ganzen ja keinen Abbruch.

Nun, in den wenigsten Faellen ist Datenbankkommunikation so simpel. Dass man einen Wert, um ihn zu inkrementieren nicht erst ausliest und dann mit +1 wieder hereinschreibt (inkl. locking...), ist wohl jedem hier klar.

Aber zumeist macht man ja doch komplexere Dinge im Code und dann gelangt man eben sehr schnell an den Punkt, an dem ein Select und ein Update das DBMS weit weniger Arbeit kosten, als die Berechnung (wie im Ursprungsposting hier). Und da es eben nie ein Problem ist, weitere HTTP-Server dazu zu stellen, sondern die Skalierung der Datenbank dann eher das Problem wird, sollte man immer noch den Speicher so simpel wie moeglich halten.

Solang alles auf einem Server laeuft, mag das durchaus performanter sein, es in der Datenbank zu berechnen. Sobald man auf mehrere Kisten skalieren moechte jedoch nicht mehr. Von Problemen bei Codepflege und Wartung mal gar nicht zu sprechen..

Auf diese Diskussion antworten