Mysql If else
Nikki
- php
Hi
ich habe eine DB mit 3 Tabellen zum Thema Musik. Mal vereinfacht dargestellt:
tab1:
id titel
tab2:
id interpret
tab3:
id_1 id_2
In Tabelle 1 zb.
1 My Way
2 Hier steht ein Mensch
3 Purple Rain
4 Summer of 69
In Tabelle 2 zb.
1 Elvis Presley
2 Frank Sinatra
3 Falco
4 Peter Alexander
5 Bryan Adams
6 Prince
In Tabelle 3 dann die Zuordnungen:
1 2
1 1
2 4
2 3
3 6
4 5
Dss bedeutet somit, dass mehrer Interpreten eventuell das gleiche Lied gesungen haben.
Bisher denke ich so:
Datensatz kommt rein, bestehend aus Titel und Interpret.
In Tabelle eins suchen ob das Lied bereits vohanden ist ansonsten eintragen. In Tabelle 2 suchen ob Interpret vorhanden, sonst eintragen.
In Tabelle 3 prüfen ob Zuordung Titel-Interpret besteht, sonst eintragen.
--------------------------------------
Join Abfragen fallen ja irgendwie aus, weil sonst wäre der Ablauf ja so:
Prüfen ob Title+Interpret vorhanden ist und eine Zuornung besteht.
Wenn nicht, dann erst mal prüfen ob Titel+Interpret vorhanden ist.
Wenn auch das nicht dann jeweils einzeln doch wieder prüfen ob Titel oder Interpret vorhanden ist und anfangen jeweils einzutragen.
Jetzt lässt sich das zwar alles bewerkstelligen aber eben mit vielen Abfragen und auf viel PHP-Basis, erst recht kompliziert wird es wenn nicht nur ein Datensatz reinkommt sondern viele auf einmal.
Irgend jemand eine Idee dazu, am Besten mit wenig PHP stattdessen mehr Mysql Möglichkeiten?
Nikki
Hi,
Irgend jemand eine Idee dazu, am Besten mit wenig PHP stattdessen mehr Mysql Möglichkeiten?
arbeite mit Unique-Constraints, mache drei Inserts, rechne mit Fehlern.
Cheatah
Hi
arbeite mit Unique-Constraints, mache drei Inserts, rechne mit Fehlern.
Das kann doch nicht wirklich die optimale Lösung sein?
Datensatz kommt rein mit 200 Einträgen = 600 Inserts <= 300 Erorrs
Ausserdem ist kommen noch die Abfrage hinzu, eintragen alleine reicht ja nicht muss ja auch wegen der Zuordung noch die IDs abfragen.
Nikki
Hi,
arbeite mit Unique-Constraints, mache drei Inserts, rechne mit Fehlern.
Das kann doch nicht wirklich die optimale Lösung sein?
warum nicht? Dafür sind Constraints da. Der Vorteil ist, dass das System portierbar auf andere DBMSse ist. Wenn Dir dies egal ist, kannst Du natürlich proprietäre Fertigkeiten wie INSERT IGNORE verwenden.
Ausserdem ist kommen noch die Abfrage hinzu, eintragen alleine reicht ja nicht muss ja auch wegen der Zuordung noch die IDs abfragen.
Bei einem INSERT-Statement kannst Du auch Unterabfragen durchführen.
Cheatah
warum nicht? Dafür sind Constraints da. Der Vorteil ist, dass das System portierbar auf andere DBMSse ist. Wenn Dir dies egal ist, kannst Du natürlich proprietäre Fertigkeiten wie INSERT IGNORE verwenden.
Die Inserts sind nicht das Problem.
Ausserdem ist kommen noch die Abfrage hinzu, eintragen alleine reicht ja nicht muss ja auch wegen der Zuordung noch die IDs abfragen.
Bei einem INSERT-Statement kannst Du auch Unterabfragen durchführen.
Ja und wie sollte das dann aussehen?
Wenn x in tab1 vorhanden, dann prüfe ob y auch in tab2 und wenn auch da dann nimm die ID der beiden und ordne sie in Tab3 an wenn nicht sowieso schon vorhanden.
Das soll in einer einzigen Insertabfrage möglich sein? Wäre natürlich schön.
Nikki
Hi,
Die Inserts sind nicht das Problem.
das ist gut!
Bei einem INSERT-Statement kannst Du auch Unterabfragen durchführen.
Ja und wie sollte das dann aussehen?
Nach was hast Du gesucht, was hast Du gefunden, was ausprobiert, auf welche Probleme bist Du gestoßen?
Wenn x in tab1 vorhanden, dann prüfe [...]
Nein, Du prüfst nichts. Du fügst ein und verwendest. Die anderen Werte liegen ja schon vor, Du hast sie bereits eingefügt falls sie noch nicht da waren.
Cheatah
Nach was hast Du gesucht, was hast Du gefunden, was ausprobiert, auf welche Probleme bist Du gestoßen?
Habe ich doch schon geschrieben, es sind viel zu viele Querys notwendig.
Wenn x in tab1 vorhanden, dann prüfe [...]
Nein, Du prüfst nichts. Du fügst ein und verwendest. Die anderen Werte liegen ja schon vor, Du hast sie bereits eingefügt falls sie noch nicht da waren.
Ja soweit ist das schon klar was aber eben wie gesagt viele unnötige Insertversuche bedeutet, weil ja bereits vorhanden und dann muss ich dennoch prüfen/abfragen wie die IDs der beiden Tabellen sind um diese in die dritte Tabelle einzutragen, wenn nicht sogar unnötig weil schon vorhanden. Und diesen vielen inserts&selects nur um einen Datansatz einzutragen finde ich schon heftig, aber wenn es dann im Batchverfahren sehr viel Daten sind wird es krass.
Also kann ich nicht glauben, dass das nicht besser gehen sollte?
Nikki
Hi,
Nach was hast Du gesucht, was hast Du gefunden, was ausprobiert, auf welche Probleme bist Du gestoßen?
Habe ich doch schon geschrieben, es sind viel zu viele Querys notwendig.
drei Stück. Unter Umständen sogar insgesamt drei, nicht etwa drei pro Eintrag. Finde ich nicht gerade viel.
Ja soweit ist das schon klar was aber eben wie gesagt viele unnötige Insertversuche bedeutet, weil ja bereits vorhanden
Die unnötigen Insertversuche kannst Du durch die exakt selbe Menge Selects ersetzen, hast dadurch aber die Notwendigkeit, außerhalb von SQL noch weitere Logik unterzubringen.
und dann muss ich dennoch prüfen/abfragen wie die IDs der beiden Tabellen sind um diese in die dritte Tabelle einzutragen, wenn nicht sogar unnötig weil schon vorhanden.
Was im dritten Insert passiert.
Und diesen vielen inserts&selects nur um einen Datansatz einzutragen finde ich schon heftig, aber wenn es dann im Batchverfahren sehr viel Daten sind wird es krass.
Drei Inserts. Null Selects.
Also kann ich nicht glauben, dass das nicht besser gehen sollte?
Wie viel besser magst Du es noch haben?
Cheatah
und dann muss ich dennoch prüfen/abfragen wie die IDs der beiden Tabellen sind um diese in die dritte Tabelle einzutragen, wenn nicht sogar unnötig weil schon vorhanden.
Was im dritten Insert passiert.
ohoh, Denkfehler stimmt ja.
Danke
Nikki
echo $begrüßung;
Drei Inserts. Null Selects.
Wie viel besser magst Du es noch haben?
Das Problem an der Geschichte ist, die IDs der bereits vorhandenen Datensätze zu bekommen. Bei einem INSERT IGNORE liefert LAST_INSERT_ID() (bzw. das API-Pendant dazu) nur dann einen brauchbaren Wert, wenn der IGNORE-Fall nicht eintritt.
Alternative Vorgehensweisen:
INSERT IGNORE title SET title='title';
INSERT IGNORE interpret SET interpret='interpret';
INSERT IGNORE stücke SET id_title=(SELECT id FROM title WHERE title='title'), id_interpret=(SELECT id FROM interpret WHERE interpret='interpret');
Man kommt hier um die zwei SELECTs nicht drumrum, versteckt sie aber im dritten INSERT.
(Wobei mir grad auffällt, dass ein Titelname durchaus zwei verschiedene Stücke bezeichnen kann, und da muss der eine noch nicht mal eine Coverversionen des anderen sein. Das so zu normalisieren halte ich für nicht richtig. Ich würde die Titel n:1 dem Interpreten zuordnen.)
Ein zweiter Vorschlag:
INSERT title SET title='title' ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id);
mysql_insert_id() befragen und Wert merken. Enthalten ist entweder die ID vom eingefügten Satz oder aufgrund der LAST_INSERT_ID(expr)-Arbeitsweise (man beachte den Parameter expr) der Wert von einem bereits vorhandenen Titel.
Das gleiche mit dem Interpreten machen und beide gemerkte ID-Werte im dritten INSERT (mit IGNORE) angeben.
Siehe dazu: INSERT ... ON DUPLICATE KEY UPDATE Syntax
Hier hat man also "Drei Inserts. Null Selects." aber unter Zuhilfenahme der API. In reinem MySQL benötigt man noch eine benutzerdefinierte Variable, um den Title-ID-Wert zwischenzuspeichern. Also hat man effektiv "Drei Inserts. Ein Set."
echo "$verabschiedung $name";
Hi,
Drei Inserts. Null Selects.
Wie viel besser magst Du es noch haben?
Das Problem an der Geschichte ist, die IDs der bereits vorhandenen Datensätze zu bekommen.
warum? Ich kenne die Werte, die eindeutig auf die zugehörige ID schließen lassen. Die ID selbst brauche ich außerhalb der Insert-Statements nicht.
Man kommt hier um die zwei SELECTs nicht drumrum, versteckt sie aber im dritten INSERT.
Sorry, mit den o.g. Selects meinte ich entsprechende Statements. Dass Unterabfragen benutzt werden sollten, hatte ich zuvor bereits gesagt.
(Wobei mir grad auffällt, dass ein Titelname durchaus zwei verschiedene Stücke bezeichnen kann, und da muss der eine noch nicht mal eine Coverversionen des anderen sein. Das so zu normalisieren halte ich für nicht richtig. Ich würde die Titel n:1 dem Interpreten zuordnen.)
Jupp. "The Power of Love" wäre hierfür ein Beispiel; von Huey Lewis and the News, Jennifer Rush und Frankie Goes to Hollywood - drei völlig unterschiedliche Songs mit dem selben Titel.
Cheatah