Datenbank-Einträge mit '0' ans Ende
web_wolf
- php
Hallo Community,
Ich bin seit einiger Zeit dabei ein kleines Browserspiel zu entwickeln.
Das ganze hat bis jetzt super funktioniert. =)
Heute stehe ich vor einem Problem, für das ich Hilfe benötige.
Dabei geht es um ein Gruppen-System. Spieler können Gruppen bilden und dann gemeinsam spielen.
ich habe folgende Tabelle in meiner Datenbank (vereinfacht)
TABLE_BENUTZER
id
name
passwort
gruppen_id
TABLE_GRUPPEN
id
name
benutzer_1_id
benutzer_2_id
benutzer_3_id
benutzer_4_id
benutzer_5_id
Die Tabelle TABLE_BENUTZER enthält logischerweise alle angemeldeten Benutzer
und die Tabelle TABLE_GRUPPEN dann alle Gruppen, die zur Zeit existieren.
(Maximale Anzahl der Benutzer in einer Gruppe = 5)
Ich habe das bisher so gestalltet, dass in der Spalte 'gruppen_id' die Gruppe eingetragen ist,
in der sich der einzelne Spieler befindet.
In der Tabelle TABLE_GROUP enthält dann ein der Spalten "benutzer_1_id" oder "benutzer_2_id" usw. die ID dieses Spielers.
Natürlich geht das auch mittels nur einer Tabelle...dessen bin ich mir bewusst.
Der Benutzer, der unter dem Eintrag "benutzer_1_id" registriert ist, ist der Gruppenführer.
Er darf andere Gruppen-Mitglieder rausschmeißen.
Wirft er nun zB den Spieler "benutzer_2_id" heraus, wird die dort eingetragene ID in TABLE_GROUPS auf '0' gesetzt und
der Eintrag in der TABLE_USER auch.
Hier ein Beispiel nach der o.g. Aktion:
TABLE_BENUTZER
id = 16
name = Max_Mustermann
passwort = CCdd6CC
gruppen_id = 0 <-----------gruppen_id wird auf '0' gesetzt
TABLE_GRUPPEN
id = 2
name = Gruppe-XY
benutzer_1_id = 544
benutzer_2_id = 0 <-----------benutzer_id wird auf '0' gesetzt
benutzer_3_id = 223
benutzer_4_id = 434
benutzer_5_id = 2
Und hier setzt mein Problem an:
der Mitglieds-Eintrag mit der '0' soll nun auf den letzten Eintrag, also auf "benutzer_5_id" gesetzt werden.
Die ID's der anderen Spieler (223, 434 und 2) sollen nach oben verschoben werden, etwa so:
TABLE_GRUPPEN
id = 2
name = Gruppe-XY
benutzer_1_id = 544
benutzer_2_id = 223
benutzer_3_id = 434
benutzer_4_id = 2
benutzer_5_id = 0 <-----------der leere EIntrag wurde nach unten verschoben
Nur wie lässt sich das realisieren? O_o
Ich hatte da an eine SQL-FUnktion gedacht.
Mit PHP wird das natürlich auch funktionieren, was ich aber als sehr umständlich erachte.
Es würde mir sehr weiter helfen, wenn mir jemand zeigen könnte, wie ich das anstellen kann, danke.
Moin
Am einfachste wäre du überdenkst deine Struktur. Ich persönlich würde folgende Struktur mit Hilfstabelle empfehlen:
TABLE_BENUTZER
id = 16
name = Max_Mustermann
passwort = CCdd6CC
TABLE_GRUPPEN
id = 2
name = Gruppe-XY
TABLE GRUPPE-BENUTZER
Datensatz 1:
id=1
gruppe=2
benutzer=16
order=1
Datensatz 2
id=2
gruppe=2
benutzer=323
order=2
.
.
.
Datensatz 4
id=5
gruppe=2
benutzer=434
order=5
So, wenn jetzt ein Benutzer rausfällt wird einfach der entsprechende Eintrag in der Tabelle GRUPPE-BENUTZER gelöscht. Wenn nun für die Gruppe 2 ein neuer Benutzer hinzukommt, erhält dieser einfach den nächthöheren Wert bei Order. In diesem FAll '6'. Somit musst du nichts umkopieren und hast trotzdem die richtige Reihenfolge. Ausserdem sind die TAbellen untereinander nicht zigtausendfach referenziert.
Gruß Bobby
Vielen Dank für deine schnelle Antwort Boby =)
Ich werde das gleich mal ausprobieren.
Ich habe mich jetzt schon lange mit der Variante befasst und muss sagen, dass das clever gelöst ist, doch leider führt das nicht zu dem gewollten Effekt.
Also generell habe ich das folgendermaßen verstanden:
Nehmen wir mal an, in der Tabelle TABLE GRUPPE-BENUTZER wäre jetzt eine 'Lücke', also ein Mitglied wurde rausgeschmissen oder ist selber ausgestiegen.
+--------+------------+--------------+-----------+
| id | gruppe | benutzer | order |
++++++++++++++++++++++++++++++++++++++++++++++++++
| 1 | 50 | 5435 | 1 |
+--------+------------+--------------+-----------+
| 2 | 50 | 412 | 2 |
+--------+------------+--------------+-----------+
| | | | | <- Datendupel gelöscht.
+--------+------------+--------------+-----------+
| 4 | 50 | 412 | 4 |
+--------+------------+--------------+-----------+
...und ein neuer Benutzer würde jetzt der Gruppe beitreten:
+--------+------------+--------------+-----------+
| id | gruppe | benutzer | order |
++++++++++++++++++++++++++++++++++++++++++++++++++
| 1 | 50 | 5435 | 1 |
+--------+------------+--------------+-----------+
| 2 | 50 | 412 | 2 |
+--------+------------+--------------+-----------+
| 4 | 50 | 412 | 4 |
+--------+------------+--------------+-----------+
| 5 | 50 | 1546 | 3 | <- Neuer Eintrag
+--------+------------+--------------+-----------+
Der Neue benutzer erhält in diesem Falle die 3 bei Order, weil die noch nicht belegt ist.
Und genau so sollte es nicht sein.
Wenn ein neuer Benutzer der Gruppe beitritt, soll dieser 'ans Ende gesetzt werden' also hier die order 4 erhalten.
+--------+------------+--------------+-----------+
| id | gruppe | benutzer | order |
++++++++++++++++++++++++++++++++++++++++++++++++++
| 1 | 50 | 5435 | 1 |
+--------+------------+--------------+-----------+
| 2 | 50 | 412 | 2 |
+--------+------------+--------------+-----------+
| 4 | 50 | 412 | 3 | <- geändert von 4 auf 3
+--------+------------+--------------+-----------+
| 5 | 50 | 1546 | 4 | <- Neuer Eintrag
+--------+------------+--------------+-----------+
Bitte korrigiere mich, wenn ich deinen Vorschlag nicht richtig verstanden habe. Danke.
Hi,
...und ein neuer Benutzer würde jetzt der Gruppe beitreten:
+--------+------------+--------------+-----------+
| id | gruppe | benutzer | order |
++++++++++++++++++++++++++++++++++++++++++++++++++
| 1 | 50 | 5435 | 1 |
+--------+------------+--------------+-----------+
| 2 | 50 | 412 | 2 |
+--------+------------+--------------+-----------+
| 4 | 50 | 412 | 4 |
+--------+------------+--------------+-----------+
| 5 | 50 | 1546 | 3 | <- Neuer Eintrag
+--------+------------+--------------+-----------+Der Neue benutzer erhält in diesem Falle die 3 bei Order, weil die noch nicht belegt ist.
Dann hast du nicht das umgesetzt, was Bobby vorgeschlagen hatte:
So, wenn jetzt ein Benutzer rausfällt wird einfach der entsprechende Eintrag in der Tabelle GRUPPE-BENUTZER gelöscht. Wenn nun für die Gruppe 2 ein neuer Benutzer hinzukommt, erhält dieser einfach den nächthöheren Wert bei Order.
Also: Den nächsthöheren Wert zum aktuellen Maximalwert wählen, nicht einen zufälligerweise "freien".
Und genau so sollte es nicht sein.
Dann setze es so um, wie von Bobby vorgeschlagen.
Wenn ein neuer Benutzer der Gruppe beitritt, soll dieser 'ans Ende gesetzt werden' also hier die order 4 erhalten.
Nein, er sollte die order 5 erhalten, weil 4 der derzeit höchste vorkommende Wert ist.
MfG ChrisB
Nein, er sollte die order 5 erhalten, weil 4 der derzeit höchste vorkommende Wert ist.
Und wie genau stelle ich das an?
Mit AUTO_INCREMENT stelle ich mir das völlig nutzlos vor, da ich dann ja auch die ID nehmen könnte, um die Reihenfolge zu bestimmen.
Hier mal ein Beispiel mit 2 Gruppen, so wie ich mir das jetzt grade vorstelle
+--------+------------+--------------+-----------+
| id | gruppe | benutzer | order |
++++++++++++++++++++++++++++++++++++++++++++++++++
| 1 | 2 | 5435 | 1 |
+--------+------------+--------------+-----------+
| 2 | 2 | 412 | 2 |
+--------+------------+--------------+-----------+
| 3 | 2 | 412 | 3 | <- wird gelöscht
+--------+------------+--------------+-----------+
| 4 | 2 | 1546 | 4 |
+--------+------------+--------------+-----------+
| 5 | 5 | 51 | 1 |
+--------+------------+--------------+-----------+
| 6 | 5 | 14 | 2 |
+--------+------------+--------------+-----------+
| 7 | 5 | 125 | 3 |
+--------+------------+--------------+-----------+
| 8 | 5 | 3 | 4 |
+--------+------------+--------------+-----------+
Der Eintrag mit der id 3 wird gelöscht und es kommt ein neues Benutzer zur Gruppe 2 dazu.
+--------+------------+--------------+-----------+
| id | gruppe | benutzer | order |
++++++++++++++++++++++++++++++++++++++++++++++++++
| 1 | 2 | 5435 | 1 |
+--------+------------+--------------+-----------+
| 2 | 2 | 412 | 2 |
+--------+------------+--------------+-----------+
| 4 | 2 | 1546 | 4 |
+--------+------------+--------------+-----------+
| 5 | 5 | 51 | 1 |
+--------+------------+--------------+-----------+
| 6 | 5 | 14 | 2 |
+--------+------------+--------------+-----------+
| 7 | 5 | 125 | 3 |
+--------+------------+--------------+-----------+
| 8 | 5 | 3 | 4 |
+--------+------------+--------------+-----------+
| 9 | 2 | 3333 | 3 | <- Der neue Eintrag
+--------+------------+--------------+-----------+
Nur wie weiß ich jetzt bzw. wie sag ich PHP/MySQL, dass in die Spalte order die 3 rein muss?
Hi,
Nein, er sollte die order 5 erhalten, weil 4 der derzeit höchste vorkommende Wert ist.
Und wie genau stelle ich das an?
Du ermittelst den derzeit höchsten Wert, udn verwendest für den neuen Eintrag einen um eins erhöhten Wert.
(Dabei beachten, Ermittlung und Einlegen des neuen Eintrages so zu kapseln, dass nicht vor dem Eintrag durch einen anderen Prozess der ermittelte Wert schon nicht mehr der höhste ist.)
Nur wie weiß ich jetzt bzw. wie sag ich PHP/MySQL, dass in die Spalte order die 3 rein muss?
Hatten wir das nicht gerade - dass *nicht* der Wert 3 hinein soll, sondern der derzeit höchste Wert (4) plus 1, also 5?
MfG ChrisB
Hatten wir das nicht gerade - dass *nicht* der Wert 3 hinein soll, sondern der derzeit höchste Wert (4) plus 1, also 5?
Sorry, hab mich da vertan. Es sollte natürlich die 5 sein.
+--------+------------+--------------+-----------+
| id | gruppe | benutzer | order |
++++++++++++++++++++++++++++++++++++++++++++++++++
| 1 | 2 | 5435 | 1 |
+--------+------------+--------------+-----------+
| 2 | 2 | 412 | 2 |
+--------+------------+--------------+-----------+
| 4 | 2 | 1546 | 4 |
+--------+------------+--------------+-----------+
| 5 | 5 | 51 | 1 |
+--------+------------+--------------+-----------+
| 6 | 5 | 14 | 2 |
+--------+------------+--------------+-----------+
| 7 | 5 | 125 | 3 |
+--------+------------+--------------+-----------+
| 8 | 5 | 3 | 4 |
+--------+------------+--------------+-----------+
| 9 | 2 | 3333 | 5 | <- Der neue Eintrag
+--------+------------+--------------+-----------+
Du ermittelst den derzeit höchsten Wert, udn verwendest für den neuen Eintrag einen um eins erhöhten Wert.
(Dabei beachten, Ermittlung und Einlegen des neuen Eintrages so zu kapseln, dass nicht vor dem Eintrag durch einen anderen Prozess der ermittelte Wert schon nicht mehr der höhste ist.)
Die ganze Sache bringt mich irgendwie total durcheinander.
Hättest du hierfür vielleicht ein kleines Beispiel für mich? Würde mir echt helfen.
$sql="SELECT
*
FROM
gruppen_benutzer
WHERE
gruppe = 2"
$mitglieder_order = array();
$result = mysql_query($sql) OR die(mysql_error());
while($entry = mysql_fetch_assoc($result)) {
array_push($mitglieder_order,$entry['order']);
}
Das würde bei mir folgendes ausgeben:
array(3) {
[0]=>
int(1) "1"
[1]=>
int(1) "2"
[2]=>
int(1) "4"
[n] =>
int (1) "x"
}
....mir fehlt da jetzt wohl eine Funktion, mit der ich den höchsten Wert ermitteln kann. Was kann ich da nehmen ?
Hi,
Das würde bei mir folgendes ausgeben:
array(3) {
[0]=>
int(1) "1"
[1]=>
int(1) "2"
[2]=>
int(1) "4"
[n] =>
int (1) "x"
}....mir fehlt da jetzt wohl eine Funktion, mit der ich den höchsten Wert ermitteln kann. Was kann ich da nehmen ?
Die Datenbank.
Du brauchst nicht erst alle Werte auslesen und nach PHP rüberzuschaufeln, wenn dich nur der höchste interessiert.
Informiere dich über Aggregatfunktionen.
MfG ChrisB
Informiere dich über Aggregatfunktionen.
MfG ChrisB
Das werde ich gleich morgen machen.
Vielen Dank für eure Hilfe. =)
Das ganze mit der HIlfstabelle läuft schon ganz gut. Leider komme ich an einem Punkt nicht weiter. Und zwar habe ich zwei Arrays. In dem ersten Array sind die Benutzer-IDs mit der richtigen Reihenfolge. Aus einer anderen Tabelle in der Datenbank wähle ich nun die ganzen Benutzer-Informationen dieser IDs aus. Leider jedoch nicht in der richtigen Reihenfolge.
Wie also sortiere ich das zweite Array so, dass die Reihenfolge der IDs richtig ist?
ARRAY 1
---------
array(3) {
[0]=>
string(1) "7"
[1]=>
string(1) "3"
[2]=>
string(1) "4"
}
ARRAY 2
---------
array(3) {
[0]=>
array(5) {
[0]=>
string(1) "3" <---- IDs nicht in der richtigen Reihenfolge
[1]=>
string(12) "Dieter"
[2]=>
string(6) "323"
[3]=>
string(2) "50"
[4]=>
string(1) "0"
}
[1]=>
array(5) {
[0]=>
string(1) "4"
[1]=>
string(9) "Hans"
[2]=>
string(6) "433"
[3]=>
string(2) "60"
[4]=>
string(1) "1"
}
[2]=>
array(5) {
[0]=>
string(1) "7"
[1]=>
string(15) "Peter"
[2]=>
string(6) "asdasd"
[3]=>
string(2) "61"
[4]=>
string(1) "1"
}
}
Hi!
Wie also sortiere ich das zweite Array so, dass die Reihenfolge der IDs richtig ist?
Am einfachsten geht das mit einer der u*sort-Funktionen und einer benutzerdefinierten Vergleichsfunktion.
Lo!
Hi!
Wie also sortiere ich das zweite Array so, dass die Reihenfolge der IDs richtig ist?
Am einfachsten geht das mit einer der u*sort-Funktionen und einer benutzerdefinierten Vergleichsfunktion.
Lo!
Hi,
Danke für den Tip =)
Ich habe mir das mal angeschaut und auch regelrecht schnell begriffen.
function cmp($a, $b)
{
return strcmp($a[1], $b[1]);
}
usort($mein_array, "cmp");
Dieser kleine Code sortiert mein Array nach den Benutzernamen
array(3) {
[0]=>
array(5) {
[0]=>
string(1) "3"
[1]=>
string(12) "Dieter"
[2]=>
string(6) "11"
[3]=>
string(2) "50"
[4]=>
string(1) "0"
}
[1]=>
array(5) {
[0]=>
string(1) "4"
[1]=>
string(9) "Hans"
[2]=>
string(6) "3354"
[3]=>
string(2) "60"
[4]=>
string(1) "1"
}
[2]=>
array(5) {
[0]=>
string(1) "7"
[1]=>
string(15) "Peter"
[2]=>
string(6) "234"
[3]=>
string(2) "61"
[4]=>
string(1) "1"
}
}
array(3) {
[0]=>
string(1) "7"
[1]=>
string(1) "3"
[2]=>
string(1) "4"
}
Nur wie gestallte ich die Vergleichsfunktion, wenn ich das Array nach den IDs des anderen Array sortieren will ?
Ich benutze usort mit der Vergleichsfunktion zum ersten Mal und begreife demnach wohl sehr langsam =/
Könnte mir jemand ein Beispiel hierfür zeigen oder mir jedenfalls erkären könnte wie ich forgehen muss?
Das wäre super =P
Hi!
Nur wie gestallte ich die Vergleichsfunktion, wenn ich das Array nach den IDs des anderen Array sortieren will ?
Du kannst zwar über das zweite Array iterieren und bekommst dabei die IDs, aber du hast keine einfache Möglichkeit, anhand derer auf das passende Element aus dem ersten Array zuzugreifen. Zwei Lösungsmöglichkeiten fallen mir da ein: Du durchläufst (während du über das zweite Array iterierst) jedes Mal das erste Array und suchst den Eintrag mit der passenden ID. Oder - und diese Methode ist die vermutlich performantere - du durchläufst zuerst das erste Array und erstellst daraus ein neues Array, diesmal aber mit den IDs als Keys und nicht einfach fortlaufend automatisch nummeriert. Somit kannst du dann beim Durchlauf durch das zweite Array über die Keys im ersten Array den gewünschten Datensatz erhalten. Noch besser wäre es, wenn du das erste Array gleich so anlegen könntest.
Ich benutze usort mit der Vergleichsfunktion zum ersten Mal und begreife demnach wohl sehr langsam =/
Das ist auch etwas komplizierter, weil dafür dein derzeitiges Datenmodell nicht besonders geeignet ist. Du müsstest hier nicht nur eine Lösung suchen, sondern eher als Problem erkennen, dass das erste Array ungünstig aufgebaut ist.
Lo!
Moin
$sql="SELECT
*
FROM
gruppen_benutzer
WHERE
gruppe = 2"
$mitglieder_order = array();
$result = mysql_query($sql) OR die(mysql_error());
while($entry = mysql_fetch_assoc($result)) {
array_push($mitglieder_order,$entry['order']);
}Das würde bei mir folgendes ausgeben:
array(3) {
[0]=>
int(1) "1"
[1]=>
int(1) "2"
[2]=>
int(1) "4"
[n] =>
int (1) "x"
}....mir fehlt da jetzt wohl eine Funktion, mit der ich den höchsten Wert ermitteln kann. Was kann ich da nehmen ?
Alternativ kannst du das Orderfeld mit dem Datum der Erstellung des Datensatzes füllen. Dann kannst du nach Datum sortieren und hast das Problem mit dem umkopieren nicht. So ist das DAtum der Sortierwert.
Gruß Bobby