SQL [MySQL & PHP] Vor INSERT auf möglichen vorhanden Datensatz überprüfen

unXtremo

Ensign
Registriert
Feb. 2009
Beiträge
228
Hallo zusammen,
ich habe mal wieder einen Verständnishänger.

Hier meine DB Struktur:
PHP:
/**
 * Datenbank: entwicklung
 */

CREATE DATABASE entwicklung 
 DEFAULT CHARACTER SET utf8
 COLLATE utf8_unicode_ci
;

/*********
 * Beginn der Tabellen
 */

/**
 * Benutzer
 */
CREATE TABLE user (
 u_id INT NOT NULL UNIQUE AUTO_INCREMENT,
 vorname VARCHAR(50) NOT NULL,
 nachname VARCHAR(50) NOT NULL,
 mail VARCHAR(50) NOT NULL,
 username VARCHAR(50) NOT NULL,
 password VARCHAR(50) NOT NULL,
 u_status BOOLEAN NOT NULL DEFAULT 1,
 u_statistik INT NOT NULL DEFAULT 0,
 PRIMARY KEY (u_id)
);

/**
 * Ort
 */
CREATE TABLE ort (
 o_id INT NOT NULL UNIQUE AUTO_INCREMENT,
 o_name VARCHAR(50) NOT NULL,
 PRIMARY KEY (o_id)
);

/**
 * Ereignis Kategorien
 */
CREATE TABLE kategorie (
 kategorie_nr INT NOT NULL UNIQUE AUTO_INCREMENT,
 kategorie_name VARCHAR(50) NOT NULL,
 kategorie_tag VARCHAR(50) NOT NULL,
 kategorie_ort VARCHAR(50) NOT NULL,
 kategorie_uhrzeit TIME NOT NULL,
 max_anzahl_user INT NOT NULL,
 PRIMARY KEY (kategorie_nr),
 FOREIGN KEY (kategorie_ort)
 REFERENCES ort(o_name)
 ON DELETE CASCADE
) ENGINE=InnoDB;

/**
 * Ereignisse
 */
CREATE TABLE ereignis (
 e_id INT NOT NULL UNIQUE AUTO_INCREMENT,
 datum DATE NOT NULL,
 kategorie INT NOT NULL,
 PRIMARY KEY (e_id),
 FOREIGN KEY (kategorie)
 REFERENCES kategorie(kategorie_nr)
 ON DELETE CASCADE
) ENGINE=InnoDB;
 
/**
 * Anmeldung
 */
CREATE TABLE anmeldung (
 a_id INT NOT NULL UNIQUE AUTO_INCREMENT,
 user INT NOT NULL,
 ereignis INT NOT NULL,
 PRIMARY KEY (a_id),
 FOREIGN KEY (user)
 REFERENCES user(u_id),
 FOREIGN KEY (ereignis)
 REFERENCES ereignis(e_id)
 ON DELETE CASCADE
) ENGINE=InnoDB;

Also was ich vor habe: Angemeldete Benutzer sollen sich für ein bestimmtes Ereignis anmelden können, dabei gibt die Kategorie eines Ereignisses vor, wie viele Benutzer sich für dieses Ereignis anmelden können.

Ich habe also ein Formular entwickelt, welches die Ereignisse aus der DB abfragt und in Selektlisten nach Wochentag (je Mittwoch, Samstag, Sonntag, Rest gemischt) sortiert ausgibt. Wenn sich jetzt ein User anmelden will, dann wird ein INSERT ausgeführt:
PHP:
$sql_eintragen = "INSERT anmeldung (user, ereignis) values " . "('" . $userid . "', " . "'" . $ereignis . "')";
Natürlich werden die übermittelten Formulardaten aus sicherhitsgründen vorher escaped. Die $userid stammt aus der SESSION.
So jetzt soll aber vor dem Anmelden erst überprüft werden, ob sich der Benutzer schon bei genau diesem Ereignis angemeldet hat, um doppel Anmeldungen zu vermeiden. Und ob die maximale Anzahl der Anmeldungen bereits erreicht wurde.

Mein Problem ist jetzt:
In meinem Auswahl Formular zur Anmeldung wählen die User ein bestimmtes Datum in der Selektliste aus, es können aber an einem Tag zwei Ereignisse zu verschiedenen Uhrzeiten sein, sollte ich zu dem Datum des Ereignisses in der Liste auch die Uhrzeit angeben?

Wenn ich jetzt nämlich überprüfen will ob für dieses Ereignis bereits Anmeldungen vorliegen muss ich ja eine Abfrage auf die Tabelle anmeldung machen und über die Tabelle ereignis dem Datum und evetuell der Uhrzeit aus der Kategorie eine bestimmte ID des Ereignisses zuzuordnen (e_id) für diese e_id welche dem Feld ereignis in der anmeldungs Tabelle entspricht muss ich dann ein mysql_num_rows machen um die Anzahl der Anmeldungen zu ermitteln und diese mit der maximalen Anzahl in der Kategorie zu vergleichen. Und wegen der Doppelanmeldungen muss man auch prüfen ob es bereits einen datensatz mit dieser USer ID und Ereignis ID gibt.

Ich weiß nicht genau wieso, aber irgendwie komme ich nicht so recht auf ein SELECT Befehl, der mir diese Abfrage ermöglicht, könntet ihr mir vllt. weiterhelfen
Bisher bin ich soweit:
PHP:
$result_anmeldung = mysql_query("
SELECT *
FROM anmeldung 
INNER JOIN ereignis
ON anmeldung.ereignis = ereignis.e_id
WHERE user LIKE $userid
AND datum IN($mittwochs,$samstags,$sonntags,$rest)
");
$menge = mysql_num_rows($result_anmeldung);

if($menge == 0)
{
	$sql_eintragen = "INSERT ..." // siehe oben
}
beim INSERT weiß ich auch noch nicht wo ich die e_id her bekomme


// EDIT:
Ach ja was ich schon bei der Ausgabe im Formular realisiert habe ist, dass Ereignisse die in der Vergangenheit liegen und welche, die zwar noch kommen aber schon ausgebucht sind gar nicht zur Auswahl stehen.
Ergänzung ()

Ich habe gerade noch mal probiert, dabei fällt mir auf, das es doch gar nicht so einfach ist die Uhrzeit in der Selekt liste mit zu liefern:

Im Formular (in While Schleife):
PHP:
echo "<option >" . strftime("%d.%m.%Y",strtotime($row['datum'])) . " " . strftime("%H:%M",strtotime($row['datum'] ." ". $row_mi['kategorie_uhrzeit'])) . "</option>";
ist kein Problem und sieht dann z.B. so aus: "21.04.2012 18:30"

nur in der Auswertung hatte ich es bisher so gemacht (ohne escapen):
PHP:
$mittwochs = strftime("%Y-%m-%d",strtotime($_POST["mittwochs"]));
das kann ich aber mit der Uhrzeit hinten dran nicht mehr machen, oder?
// EDIT:
am besten trennte ich hier Datum und Uhrzeit wieder:
PHP:
$mittwochs = strftime("%Y-%m-%d",strtotime($_POST["mittwochs"]));
$mittwochs_zeit = strftime("%H:%M",strtotime($_POST["mittwochs"]));
 
Zuletzt bearbeitet:
wenn die anmeldung unique sein soll, wieso bildest du sie nicht dementsprechend in der datenbank ab?
würde das ganze eindeutiger machen und fehler ausschliessen.

CREATE TABLE anmeldung (
user INT NOT NULL REFERENCES user(u_id),
ereignis INT NOT NULL REFERENCES ereignis(e_id),
PRIMARY KEY (user, ereignis)
ON DELETE CASCADE
) ENGINE=InnoDB;


oder so ähnlich, kann zusammengesetzte primärschlüssel nicht ausm kopp.
(doppelanmeldungen lässt die datenbank somit nicht zu)

und die uhrzeit sollte in die tabelle ereignis, weil du da auch schon das datum drin hast. bzw. datum zu datetime oder timestamp ändern.
ich erkenne gerade nicht den sinn, die uhrzeit an die kategorie zu hängen?
damit sollten ereignisse zu verschiedenen uhrzeiten auch unterschiedliche primärschlüssel haben.

also dein datenmodell ist noch nicht ganz rund. wenn du das nicht glatt ziehst, wirste später wahrscheinlich noch ganz andere probleme bekommen.
 
Zuletzt bearbeitet:
Hallo DonnyDepp,
Ich habe aber doch mehrere Anmeldungen von verschiedenen Usern
also kann es sein, dass ich folgendes habe:

User | Ereignis
1 | 1
2 | 1
6 | 1
5 | 2
1 | 2
...

es darf nur nicht zwei mal 1|1 oder so vorkommen, wenn jetzt das Ereignis nur einmal vorkommen darf, dann kann sich doch nur einer anmelden, oder verstehe ich das falsch?

Das mit der Uhrzeit in der Kategorie ist ein guter Einwand, da bin ich mir auch noch nicht ganz sicher. Ich habe das bisher so gemacht, da die Kategorien ja den Tag und den Ort vorgeben und es sich oft wiederholende Ereignisse gibt, die jeweils am gleichen Wochentag am gleichen Ort und zur selben Zeit sattfinden.
 
nee, bei zusammengesetzten primärschlüsseln muss nur die kombination einmalig sein.
1|1 und 1|2 sind eindeutig, genauso wie 2|2 und 3|2

----

also hast du sowas wie eine "ereignisart", eine tabelle "ort" und eine tabelle "termin".
Diese werden zusammengetragen in einer tabelle "ereignis", die noch start und enddatum beinhaltet.
termin könnte zb. eine weitere tabelle sein, in dem eine liste von möglichen fiktiven wiederholungen gehalten wird. alle wochentage, xter tag im monat, jede woche etc.
musste mal nach googlen, gibt glaub ich einige datenmodelle für sowas.
 
Danke für die Anregungen, ich werde mich dann mal genauer schlau machen!
 
Zurück
Oben