Optimiertes Neuordnen von MySQL-Row
lima-city → Forum → Programmiersprachen → PHP, MySQL & .htaccess
ahnung
array
befehl
befehlen
code
datenbank
datum
effizienz
frage
milliarde
position
problem
schleife
server
set
tabelle
update
url
verschieben
versuch
-
Hallo,
gestern trat eine andere Person auf mich zu und fragte mich, wie man wohl am besten einzelne Elemente einer geordneten Tabelle verschieben könnte. Um das näher zu erklären: Ich habe eine MySQL-Tabelle, in welcher beispielsweise eine ID, eine Positionsspalte und halt irgendwelche Daten liegen. ( Letztere sind aber unerheblich. )
Der Aufgabensteller hatte versucht, das ganze über eine Schleife in PHP, in welcher sämtliche Elemente einzeln geupdated werden zu lösen. Für mich klingt das aber nach ziemlich viel Stress für den jeweiligen SQL-Server, da - vor allem, wenn die Tabellen größer werden - eine nicht ganz unerhebliche Menge an Befehlen an den Server gesendet werden müssen.
Nun hatte ich mir überlegt, dass das ganze doch sicher auch mit weniger Befehlen gehen würde. Um zum Punkt zu kommen - Ich habe folgende Lösung ersonnen:function moveTbRow($now, $goto){ /* Sicher stellen, dass $now und $goto int sind */ $now = intval($now); $goto = intval($goto); /* Tabellen-Einstellungen */ $table_name = 'somethingsomething'; $unique_column = 'id'; $position_column = 'position'; if($now == $goto) return false; // Keine änderung der Position /* Get Unique-Key from $now */ $sql = "SELECT `$unique_column` FROM `$table_name` WHERE `$position_column` = $now;"; $result = mysql_query($sql); $unique = mysql_result($result, 0); if(!$unique) return false; // $unique nicht bekommen, Element $now existiert nicht? ($now < $goto) ? $sql_move = "UPDATE `$table_name` SET `$position_column` = `$position_column`-1 WHERE `$position_column` > $now AND `$position_column` <= $goto;" : $sql_move = "UPDATE `$table_name` SET `$position_column` = `$position_column`+1 WHERE `$position_column` >= $goto AND `$position_column` < $now;"; $sql_set = "UPDATE `$table_name` SET `$position_column` = $goto WHERE `$unique_column` = '$unique';"; mysql_query($sql_move) or die(mysql_error()); // Bewege alle anderen mysql_query($sql_set) or die(mysql_error()); // Setze neue Position return true; }
Dazu habe ich nun zwei Fragen:
- Zum einen: Funktioniert die Lösung? Bei mir schon, aber der Aufgabensteller meinte zu mir, dass ein ganz ähnlicher Ansatz bei ihm nicht funktioniert hätte. Vielleicht liegt es ja nur an meinem Fehlertoleranten System? ( Ich habe das mit 20 Zufälligen Verschiebungen von 3 Werten ausprobiert. Ausgabe
- Zum anden - und was viel wichtiger ist: Fällt jemandem ein noch effizienterer Weg ein? -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
Oh man, fällt mir schwer dir da zu folgen.
Versuch doch einfach, die Daten in ein Array zu speichern
und je nachdem wie du es verschieben willst in ein anderes Array zu machen.
Dann kannst du sie per foreach oder anderem ausgeben. -
berlin208 schrieb:
Wie am Quelltext ersichtlich wird, geht es nicht darum, sie auszugeben. Es geht darum, eine Ordnung in der Tabelle herzustellen und aufrecht zu erhalten. Eine Foreach-Schleife wäre dort absolut unangebracht, weil das erheblichen Traffic und Mehr-Aufwand für den Server bedeuten würde.
Oh man, fällt mir schwer dir da zu folgen.
Versuch doch einfach, die Daten in ein Array zu speichern
und je nachdem wie du es verschieben willst in ein anderes Array zu machen.
Dann kannst du sie per foreach oder anderem ausgeben.
Die von mir beschriebene Funktion funktioniert! Die Frage wäre also, wie es effizienter ginge.
Zudem stehe ich vor dem Problem, dass beim Aufgabensteller offenbar nur ein UPDATE-Befehl ausgeführt wird. Ich weiß nicht so genau warum. Im Moment steht da
im Verdacht, aber bestätigt werden konnte das bisher nicht. Und wenn das Problem nicht behoben wird, ob es eine Möglichkeit gibt, das ganze mit nur einem UPDATE-Befehl hin zu bekommen.CLIENT_MULTI_STATEMENTS
-
berlin208 schrieb:
Eine milliarde? Wenn mein Query meinetwegen 30 Zeichen lang ist, meine tabelle 10000 Einträge hat und 1000 Nutzer das gleichzeitig benutzen, kommen da alleine ~300mb Traffic auf den Server zu. Und das bei nur je einem Sortiervorgang.
Was soll den dort für ein Server benutzt werden, dass das so langsam ist? Wenn man nicht eine Milliarde Einträge ausgibt oder unendlich viele Queries macht, ist daran auch nichts langsam.
Die Effizienz fängt beim Server an, an foreach() & Co. ist nichts unproduktiv, blöd oder langsam.
Wenn das ganze jedoch mit meiner bisherigen Variante gemacht wird, sind es ~60kb. Ein deutlicher Effizienz-Vorteil. Zudem kostet JEDER SQL-Befehl Rechenzeit. Je weniger, desto besser. Angenommen, ich benutze das ganze in einem Shared-Hosting-Enviroment wie Lima-City, verstoße ich mit 10 Millionen SQL-Befehlen wohl durchaus gegen das Fair-Use-Konzept, während 2000 wohl durchaus zumindest noch machbar sind.
Der Thread heißt "Optimiertes Neuordnen von MySQL-Row", nicht "Wie belaste ich den SQL-Server möglichst gravierend". -
Ach du meine Güte, dass muss doch weh tun!
Das war nicht mehr als eine gewollte Übertreibung..
Aber das kennt man ja (Sheldon-Cooper-Style) - viel Ahnung vom coden
aber keine von normalen Redewendungen :D
Meine Frage bezog sich darauf, wieso du die Effizienz verbessern willst.
In meinen Augen gibt es keine bessere Variante - und scheinbar hat auf kein anderer
in diesem Forum eine Ahnung, wie man das bewerkstelligen könnte.
Dann brauchst du wohl einen leistungsstarken (V-)Server, aber für Lima-City ist das nichts.
Da kann man noch lange nach effizienteren Möglichkeiten suchen.
PS: du nutzt noch mysql, welche bereits deprecated ist, die erste Möglichkeit um das zu beschleunigen wäre,
auf MySQLi umzusteigen. Das ist deutlich schneller und bequemer für den Server.
Beitrag zuletzt geändert: 15.2.2014 11:04:54 von berlin208 -
Wenn man beachtet, dass bisher berlin der einzige war, der was geposted hat, kann man davon ausgehen, dass niemand eine Ahnung hat, wie er es im letzen Post geschrieben hat. Ich auch nicht, das Script funktioniert, scheint nicht total schlecht und belastend für den Server geschrieben zu sein, eher das Gegenteil.
Benutz doch einfach mal das Script und wenns irgendwann wirklich ein Problem wird, kannst du ja noch mal ans Thema ran gehen, bis dahin weisst du vielleicht auch selbst schon, wie du es besser hinbekommen könntest.
Ich selbst arbeite am meisten mit JavaScript und von mysql hab ich nur so viel Ahnung wie ich grad brauch, aber 'hackyourlife' hat mir da bisher immer gut geholfen. Er ist leider nicht mehr so aktiv im Forum, aber schreib ihm doch mal eine PM, wenn dir das Script wirklich wichtig ist, er wird dir da schon helfen können. :)
Gruss c143 -
noxious schrieb:
datenbanken sind keine 'verschubbahnhöfe', sondern hauptsächlich 'such'-engines (wenn man das überhaupt so verstehen will). dieses missverständnis tritt oft (~3.5mio.) auf. datenbanken liefern (unter)mengen von gesammelten daten sortiert o. unsortiert. sortieren !== verschieben.
..., wie man wohl am besten einzelne Elemente einer geordneten Tabelle verschieben könnte.
..., in welcher beispielsweise eine ID, eine Positionsspalte und halt irgendwelche Daten liegen. (Letztere sind aber unerheblich.)
das ganze bisherige von dir ist für helfer ein bisschen wenig an gedankeninput.
ich bin überzeugt, dass das besagte problem durch datenbankkonforme datenorganisation ganz anders/besser zu lösen ist! dazu sollten wir genau wissen, was das für 'unerhebliche' daten sind!!?? ('unerhebliche' daten speichert man doch nicht in eine datenbank! ;) -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage